Getting started with JBehave in 8 steps.

2009 August 12
by Shaaf Shah

This post is about JBehave and how to quickly get started with it. If you would like to know about BDD please use the following link.
What is Behavioral Driven Development?

Today I have used JBehave for the first time. It does have some convincing factors for instance diving requirements into scenarios which map pretty nicely to the tests that are written with in the Steps. Thus it seems like it would be easier for Stakeholder/s to use it as a good guideline for the initial requirements. Its always quite usual to come up to some disagreements about the development however the tool does help to bring forth the ease for stake holders who really dont have to get into writing code but will have a technical jargon to communicate through to the developers in shape of scenarios.

So the first things come up.
1. Create a Java project in Eclipse.
2. Download the JBehave latest version from the website and add the jar files to your project build classpath
3. Create a scenario file and name it as user_wants_to_shop.scenario

Add the following text to the file

1
2
3
Given user Shaaf is logged in
Check if user shaaf is Allowed to shop
Then show shaaf his shopping cart

The lines above simply state the rules for the scenario we are about to create.

4. Now we will create a java file mapping to it.

Create a new class with the name corresponding to the same as the .scenario file
UserWantsToShop.java

Add the following code to it

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import org.jbehave.scenario.PropertyBasedConfiguration;
import org.jbehave.scenario.Scenario;
import org.jbehave.scenario.parser.ClasspathScenarioDefiner;
import org.jbehave.scenario.parser.PatternScenarioParser;
import org.jbehave.scenario.parser.ScenarioDefiner;
import org.jbehave.scenario.parser.UnderscoredCamelCaseResolver;
 
public class UserWantsToShop extends Scenario {
 
        // The usual constructor with default Configurations.
	public UserWantsToShop(){
		super(new ShoppingSteps());
	}
 
	// Mapping .scenario files to the scenario. This is not by default.
    public UserWantsToShop(final ClassLoader classLoader) {
        super(new PropertyBasedConfiguration() {
            public ScenarioDefiner forDefiningScenarios() {
                return new ClasspathScenarioDefiner(
                    new UnderscoredCamelCaseResolver(".scenario"), 
                    new PatternScenarioParser(this), classLoader);
            }
        }, new ShoppingSteps());
    }
 
}

5. Just that we now have steps we need some place to put the logic for the Steps in the Scenarios. So we create a new Steps class ShoppingSteps.java

1
2
3
4
5
6
7
8
import org.jbehave.scenario.annotations.Given;
import org.jbehave.scenario.annotations.Then;
import org.jbehave.scenario.annotations.When;
import org.jbehave.scenario.steps.Steps;
 
public class ShoppingSteps extends Steps {
 
}

6. Now you can run the Scenario by running it as a Junit Test.

Following should be the output

1
2
3
4
5
Scenario: 
 
Given I am not logged in (PENDING)
When I log in as Shaaf with a password JBehaver (PENDING)
Then I should see my "Shopping Cart" (PENDING)

This means that none of the scenario requirements have been implemented as yet. But the test result should be green to show there are no problems with our setup.

Now lets add the implementation to the tests.

7. Add the body to the ShoppingSteps. I have added the comments with the methods.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
        // Given that a user(param) is loggen in
	@Given("user $username is logged in")
	public void logIn(String userName){
		checkInSession(userName);
	}
 
        // Check if the user is allowed on the server
	@When("if user $username is $permission to shop")
	public void isUserAllowed(String userName, String permission){
		getUser(userName).isUserAllowed().equals(permission);
	}
 
       // finally then let him use the shopping cart.
	@Then("show $username his Shopping cart")
	public void getMyCart(String userName, String cart){
		getUserCart(userName);
	}

8. Now you should try to run the scenario again. And all of the test should be green. I have not implemented the actual methods so they will be red. :-)

Logging with log4J isDebugEnabled

2009 August 12
by Shaaf Shah

Alot of times I have seen the questions popping up whether to use isDebugEnabled property or not. Arguably most of the times or rather always about performance. Some of the stuff that I feel important about using it follows.

The answer is simple. It is made to be used. However using it has to be with caution.

For instance
If I am using the following line in my code.

1
log.debug("I am there");

Thats an example of a good practise

However I can really blow it out of proportions if I do the following.

1
2
3
4
// Not good practise
if (log.isDebugEnabled()){
    log.debug("I am there"); 
}

And why exactly is that so. This is because the method debug in the class Category i.e. extended by Logger in the log4j libraries explicitly checks the mode for the logging itself.

Extract from the class org.apache.log4j.Category is below

1
2
3
4
5
6
7
public void debug(Object message) {
if(repository.isDisabled(Level.DEBUG_INT))
return;
if(Level.DEBUG.isGreaterOrEqual(this.getEffectiveLevel())) {
forcedLog(FQCN, Level.DEBUG, message, null);
}
}

Okay so thats the case where we say dont use it. What about the one where we actually do use the isDebugEnabled property.

For instance you have a large parameter going in the debug.

1
2
// Bad Practise
 log.debug("XML "+Tree.getXMLText());

In such a case it can clearly be said “No dont do it!” If Tree.getXMLText is going to pull out all the hair out of the app then there is no use. As it will be constructed first and if the debug level is not enabled that would be a performance cost.

1
2
3
4
// Good Practise
if (log.isDebugEnabled()){
    log.debug("XML "+Tree.getXMLText());
}

Thus in the example above it would be wiser to use log.isDebugEnabled() just to make sure the mileage or cost stays lesser.

Keep it simple, short and stupid (KISS)

2009 June 22
by Shaaf Shah

“everything should be made as simple as possible, but no simpler” – Albert Einstein

-

I am sitting in a design room today designing a simple requirement for a client. He wants me to enhance the transfer money from one account to another. Just that it happens that I have my best friend Yuky sitting right next to me. He is damn good in Maths and extra ordinarily knows all the calculations on his tips. I am sure if I had asked him what was the angle of sight to the light on the wall he could just tell me in a few seconds looking with 10 eyes at his 12 fingers, trust me it will be correct.

Just that I cannot ignore his brilliance and just that I admire it sometimes and posed to be inspired by it all the time, I don’t agree with it all the time!

And this is what I mention here today.KISS (Keep it simple, short and stupid)

Rule# 1.  Don’t try to be a super genius.

Rule# 2. Don’t over do it!

Rule# 3. Break down your problems

Rule# 4. Common Sense has to prevail

Rule# 5. Keep your mess small, don’t litter around the park.

Most importantly keep everything short, simple and stupid.

I recently had to deliver a few minutes inspirational presentation on Test Driven Development and especially about KISS. Attached is some of the material. Feel free to explore.

What is the KISS principle?

Could be more simpler :-)

DISCLAIMER: All names, products, technologies are trademarks of the respective owners and organizations. Not to sure but maybe the rest is mine.