Google

Oct 22, 2013

jBehave Tutorial

This extends the previous tutorials
To appreciate jBehave, let's look at a better example here. This example is about a science formula

  Speed = distance / Time.

So,

  • given  distance and time, calculate speed
  • given speed and time, calculate distance
  • given speed and distance, calculate time.

Step 1: The story file in plain english. speed.story under src/main/resources/jBehave folder.


Narrative: As a student, I want to practice speed formula where speed = distance / time

scenario: calculate speed from distance and time

Given distance = 10.0
Given time = 2.5
When calculate speed
Then verify speed = 4.0


scenario: calculate distance from speed and time

Given speed = 4.0
Given time = 2.5
When calculate distance
Then verify distance = 10.00

scenario: calculate time from speed and distance

Given speed = 4.0
Given distance = 10.0
When calculate time
Then verify time = 2.50


Step 2: Mapping the story to Java step class. The steps are fine grained so that they can be mixed and matched depending on th scenario.

package com.mycompany.jbehave2;

import org.jbehave.core.annotations.Given;
import org.jbehave.core.annotations.Named;
import org.jbehave.core.annotations.Then;
import org.jbehave.core.annotations.When;
import org.jbehave.core.steps.Steps;
import org.springframework.util.Assert;

public class SpeedVelocityFormulaSteps extends Steps
{
    
    SpeedVelocityFormaula svf = new SpeedVelocityFormulaImpl();
    
    private double speed;
    private double distance;
    private double time;
    
    private double resultSpeed;
    private double resultDistance;
    private double resultTime;
    
    @Given("speed = $speed")
    public void speedInput(@Named("speed") double speed)
    {
        this.speed = speed;
    }
    
    @Given("distance = $distance")
    public void distanceInput(@Named("distance") double distance)
    {
        this.distance = distance;
    }
    
    @Given("time = $time")
    public void timeInput(@Named("time") double time)
    {
        this.time = time;
    }
    
    @When("calculate speed")
    public void calcSpeed()
    {
        Assert.notNull(distance);
        Assert.notNull(time);
        
        resultSpeed = svf.calculateSpeed(this.distance, this.time);
    }
    
    @When("calculate distance")
    public void calcDistance()
    {
        Assert.notNull(speed);
        Assert.notNull(time);
        
        resultDistance = svf.calculateDistance(this.speed, this.time);
    }
    
    @When("calculate time")
    public void calcTime()
    {
        Assert.notNull(speed);
        Assert.notNull(distance);
        
        resultTime = svf.calculateTime(this.speed, this.distance);
    }
    
    @Then("verify speed = $speedSupplied")
    public void verifySpeed(double speedSupplied)
    {
        Assert.notNull(distance);
        Assert.notNull(time);
        
        junit.framework.Assert.assertEquals(speedSupplied, resultSpeed);
    }
    
    @Then("verify distance = $distanceSupplied")
    public void verifyDistance(double distanceSupplied)
    {
        Assert.notNull(this.speed);
        Assert.notNull(time);
        
        junit.framework.Assert.assertEquals(distanceSupplied, resultDistance);
    }
    
    @Then("verify time = $timeSupplied")
    public void verifyTime(double timeSupplied)
    {
        Assert.notNull(speed);
        Assert.notNull(distance);
        
        junit.framework.Assert.assertEquals(timeSupplied, resultTime);
    }
    
}

Step 3: The actual interface that performs the calculations.

package com.mycompany.jbehave2;

public interface SpeedVelocityFormaula
{
    abstract double calculateSpeed(double distance, double time);
    
    abstract double calculateDistance(double speed, double time);
    
    abstract double calculateTime(double speed, double distance);
}

Step 4: The implementation. This is the class under test.


package com.mycompany.jbehave2;

public class SpeedVelocityFormulaImpl implements SpeedVelocityFormaula
{  
    public double calculateSpeed(double distance, double time)
    {
        return distance / time; // s = d/t
    }
    
    public double calculateDistance(double speed, double time)
    {
        return speed * time; //speed * time
    }
    
    public double calculateTime(double speed, double distance)
    {
        return distance / speed;  //distance/speed
    }
    
}


Step 5: Finally the jUnit test class

package com.mycompany.jbehave2;

import de.codecentric.jbehave.junit.monitoring.JUnitReportingRunner;

import java.util.Arrays;
import java.util.List;

import org.jbehave.core.junit.JUnitStories;
import org.jbehave.core.steps.InjectableStepsFactory;
import org.jbehave.core.steps.InstanceStepsFactory;
import org.junit.runner.RunWith;

@RunWith(JUnitReportingRunner.class)
public class JBehaveUnitTest extends JUnitStories
{
    
    public JBehaveUnitTest()
    {
        super();
    }
    
    public InjectableStepsFactory stepsFactory()
    {
        return new InstanceStepsFactory(configuration(), new SpeedVelocityFormulaSteps());
    }
    
    @Override
    protected List<String> storyPaths()
    {
        return Arrays.asList("jbehave/speed.story");
    }
    
}

Step 6: Run th unit test.



Labels: ,

2 Comments:

Blogger Unknown said...

I believe the screenshot which you have added for the above jbehave example is completely different. isn't it?

Am trying to run the above example, am seeing the following error continuously, any idea whats wrong with ?

Please Help,

java.lang.NoClassDefFoundError: com/thoughtworks/paranamer/Paranamer
at org.jbehave.core.steps.Steps.(Steps.java:105)
at com.mycompany.jbehave2.SpeedVelocityFormulaSteps.(SpeedVelocityFormulaSteps.java:9)
at com.mycompany.jbehave2.JBehaveUnitTest.stepsFactory(JBehaveUnitTest.java:31)
at org.jbehave.core.ConfigurableEmbedder.configuredEmbedder(ConfigurableEmbedder.java:126)
at de.codecentric.jbehave.junit.monitoring.JUnitReportingRunner.getStoryPathsFromJUnitStories(JUnitReportingRunner.java:125)
at de.codecentric.jbehave.junit.monitoring.JUnitReportingRunner.(JUnitReportingRunner.java:43)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at org.junit.internal.builders.AnnotatedBuilder.buildRunner(AnnotatedBuilder.java:29)
at org.junit.internal.builders.AnnotatedBuilder.runnerForClass(AnnotatedBuilder.java:21)
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:26)
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
at org.junit.internal.requests.ClassRequest.getRunner(ClassRequest.java:26)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.(JUnit4TestReference.java:33)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestClassReference.(JUnit4TestClassReference.java:25)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.createTest(JUnit4TestLoader.java:48)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.loadTests(JUnit4TestLoader.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:452)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: java.lang.ClassNotFoundException: com.thoughtworks.paranamer.Paranamer
at java.net.URLClassLoader$1.run(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
... 24 more

8:53 PM, May 20, 2014  
Blogger Unknown said...

it seems to be a class loading issue. Things may have changed since I posted this tutorial. Debugging class loading issues is a good skills to have, and try debugging this with the help of this post --> http://java-success.blogspot.com.au/2014/02/debugging-java-class-loading-issues.html. Please post back your findings.

9:35 AM, May 21, 2014  

Post a Comment

Subscribe to Post Comments [Atom]

<< Home