非常简单的JBehave设置教程,一步一步地进行?

16
尽管我看了很多篇关于如何使用 JBehave 的文章,但我却无法使它正常工作。以下是我迄今为止所进行的步骤:
  1. 创建了一个新的 Java 项目
  2. 下载了 JBehave JAR 文件版本 3.6.8 并将其添加到我的构建路径库中
  3. 在测试源文件夹下创建了一个名为 com.wmi.tutorials.bdd.stack.specs 的包
  4. 将 JBehave JAR 文件添加到我的 Build path Library 配置中
  5. 在上述包中创建了一个 JBehave story(StackBehaviourStories.story)
  6. 在上述包中创建了一个 Java 类(StackBehaviourStory.java)
  7. 在上述包中创建了一个 Java 类(StackBehaviourSteps.java)
  8. 在我的 Java 类中导入了 Given、Named、Then、When 注解
  9. 在我的 JBehave story 文件中编写了两个不同的场景

然而,我仍然无法让它工作/运行!=(

故事文件:

Narrative:
In order to learn to with JBehave using Eclipse
As a junior Java developer though senior in .Net and in BDD
I want to define the behaviour of a custom stack

Scenario: I push an item onto the stack
Given I have an empty stack
When  I push an item 'orange'
Then  I should count 1

Scenario: I pop from the stack
Given I have an empty stack
When  I push an item 'apple'
And   I pop the stack
Then  I should count 0

故事类

package com.wmi.tutorials.bdd.stack.specs

import org.jbehave.core.configuration.MostUsefulConfiguration;
import org.jbehave.core.junit.JUnitStory;

public class StackBehaviourStory extends JUnitStory {
    @Override 
    public Configuration configuration() { return new MostUsefulConfiguration(); }

    @Override
    public InjectableStepsFactory stepsFactory() {
        return new InstanceStepsFactory(configuration()
                                      , new StackBehaviourSteps());   
    }
}

步骤类

package com.wmi.tutorials.bdd.stack.specs

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.junit.Assert;

public class StackBehaviourSteps {
    @Given("I have an empty stack")
    public void givenIHaveAnEmptyStack() { stack = new CustomStack(); }

    @When("I push an item $item")
    public void whenIPushAnItem(@Named("item") String item) { stack.push(item); }

    @Then("I should count $expected")
    public void thenIShouldCount(@Named("expected") int expected) {
        int actual = stack.count();
        if (actual != expected) 
            throw new RuntimeException("expected:"+expected+";actual:"+actual);
    }
}

我目前使用的是 Eclipse Kepler (4.3) JEE 版本,已经安装了我需要使用的 JUnit、Google App Engine,而且是按照 Eclipse JBehave 安装教程正确安装了 JBehave。

但是我无法让它正常工作。那么我该如何在 Eclipse 中正确地使用 JBehave 和 JUnit?


你遇到了什么样的错误? - t0mppa
如果我能得到一个错误,我就能知道发生了什么!我根本无法运行任何东西!唯一可用的选项是“在服务器上运行”。打开的透视图是Java。此外,故事文件不断告诉我没有为“When”和“Then”定义步骤,奇怪的是,它们是带参数的两个!... = \ 我不知道该去哪里看了。 - Will Marcouiller
4个回答

11

我知道我来晚了,但我还是发帖了,因为这些信息是我一周前希望有的,因为这会让我免去很多痛苦。我非常喜欢BDD的想法,但不幸的是,我发现JBehave的文档在Maven集成方面有点困难,特别是很多我在他们网站和其他地方找到的代码都不起作用。通过试错和大量的教程,我能够拼凑出以下内容。它可以在Maven和Eclipse中运行,具有单个绑定类将story映射到step文件,并能够找到位于src/test/resources中的story文件。

以下是一个可工作的pom文件:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.projectvalis.st1</groupId>
  <artifactId>st1</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>st1</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <build>
    <pluginManagement>
      <plugins>

        <plugin>
      <artifactId>maven-compiler-plugin</artifactId>
        <version>2.3.2</version>
        <configuration>
          <source>1.8</source>
          <target>1.8</target>
        <compilerArgument></compilerArgument>
          </configuration>
        </plugin>

       <plugin>  
         <groupId>org.apache.maven.plugins</groupId>  
         <artifactId>maven-failsafe-plugin</artifactId>  
         <version>${failsafe.and.surefire.version}</version>  
         <executions>  
           <execution>  
             <id>integration-test</id>  
             <goals>  
               <goal>integration-test</goal>  
               <goal>verify</goal>  
             </goals>  
           </execution>  
         </executions>  
         <configuration>  
           <includes>  
             <include>**/*Test.java</include>  
           </includes>  
         </configuration>  
       </plugin>

       <plugin>
        <groupId>org.jbehave</groupId>
        <artifactId>jbehave-maven-plugin</artifactId>
        <version>4.0.2</version>
            <executions>  
                <execution>  
                    <id>run-stories-as-embeddables</id>  
                    <phase>integration-test</phase>  
                    <configuration>  

                    <includes>  
                        <include>**/*Test.java</include>  
                    </includes>  
                    <ignoreFailureInStories>false</ignoreFailureInStories>  
                    <ignoreFailureInView>false</ignoreFailureInView>  

                        <systemProperties>
                            <property>
                                <name>java.awt.headless</name>
                                <value>true</value>
                            </property>
                        </systemProperties>


                    </configuration>  
                    <goals>  
                    <goal>run-stories-as-embeddables</goal>  
                    </goals>  
            </execution>  
             </executions>
       </plugin>

      </plugins>
    </pluginManagement>
  </build>


  <dependencies>

    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
      <scope>test</scope>
    </dependency>

    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>1.7.7</version>
    </dependency>

    <dependency>
      <groupId>ch.qos.logback</groupId>
      <artifactId>logback-classic</artifactId>
      <version>1.0.1</version>
    </dependency>

    <dependency>
      <groupId>ch.qos.logback</groupId>
      <artifactId>logback-core</artifactId>
      <version>1.0.1</version>
    </dependency>

    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-lang3</artifactId>
        <version>3.4</version>
    </dependency>

    <dependency>
        <groupId>org.jbehave</groupId>
        <artifactId>jbehave-core</artifactId>
        <version>4.0.2</version>
    </dependency>

  </dependencies>
</project>

这里是一个示例故事文件。

Narrative:
In order to work with files to compress
As a guy who wants to win a bet with cameron
I want to ensure files are ingested and processed in the manner in which the
methods in the ingest class purport to process them. 

Scenario:  Simple test to give JBehave a test drive
Given a file, a.log
When the caller loads the file as a byte array
Then the byte array that is returned contains the correct number of bytes.

这里是一个示例的Step文件

package com.projectvalis.compUtils.tests.ingest;

import java.io.File;

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.junit.Assert;

import com.projectvalis.compUtils.util.fileIO.Ingest;


    /**
     * BDD tests for the ingest class
     * @author funktapuss
     *
     */
    public class LoadByteSteps extends Steps {

        private String fNameS;
        private byte[] byteARR;

        @Given("a file, $filename")
        public void setFileName(@Named("filename") String filename) {
            File file = new File(getClass().getResource("/" + filename).getFile());
            fNameS = file.getPath();
        }

        @When("the caller loads the file as a byte array")
        public void loadFile() {
            byteARR = Ingest.loadFile(fNameS);
        }

        @Then("the byte array that is returned contains the "
                + "correct number of bytes.") 
        public void checkArrSize() {
            File file = new File(fNameS);
            Assert.assertTrue(
                    "loading error - "
                    + "the file and the resultant byte array are different sizes!", 
                    (long)byteARR.length == file.length());
        }


    }

这里是通用的运行器。

package com.projectvalis.compUtils.tests.runner;


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

import org.jbehave.core.configuration.Configuration;
import org.jbehave.core.configuration.MostUsefulConfiguration;
import org.jbehave.core.io.CodeLocations;
import org.jbehave.core.io.LoadFromClasspath;
import org.jbehave.core.io.StoryFinder;
import org.jbehave.core.junit.JUnitStories;
import org.jbehave.core.reporters.Format;
import org.jbehave.core.reporters.StoryReporterBuilder;
import org.jbehave.core.steps.InjectableStepsFactory;
import org.jbehave.core.steps.InstanceStepsFactory;
import org.jbehave.core.steps.Steps;

import com.projectvalis.compUtils.tests.ingest.LoadByteSteps;



/**
 * generic binder for all JBehave tests. Binds all the story files to the 
 * step files. works for both Eclipse and Maven command line build.  
 * @author funktapuss
 *
 */
public class JBehaveRunner_Test extends JUnitStories {

    @Override 
    public Configuration configuration() { 
        return new MostUsefulConfiguration()            
                .useStoryLoader(
                        new LoadFromClasspath(this.getClass().getClassLoader()))
                .useStoryReporterBuilder(
                        new StoryReporterBuilder()
                            .withDefaultFormats()
                            .withFormats(Format.HTML, Format.CONSOLE)
                            .withRelativeDirectory("jbehave-report")
                );
    }

    @Override
    public InjectableStepsFactory stepsFactory() {
        ArrayList<Steps> stepFileList = new ArrayList<Steps>();
        stepFileList.add(new LoadByteSteps());

        return new InstanceStepsFactory(configuration(), stepFileList);       
    }

    @Override
    protected List<String> storyPaths() {
       return new StoryFinder().
               findPaths(CodeLocations.codeLocationFromClass(
                       this.getClass()), 
                       Arrays.asList("**/*.story"), 
                       Arrays.asList(""));

    }

}

跑步者位于src/test/java//tests.runner目录。 摄取测试位于src/test/java//tests.ingest目录。 故事文件位于src/test/resources/stories目录。

据我所知,JBehave有很多选项,因此这并不是唯一的做事方式。将其视为一个模板,可以让您快速上手。

完整的源代码在github上。


欢迎您的贡献。由于我对Java及其IDE仍不熟悉,所以我不妨尝试一下您的方法。=) - Will Marcouiller
让我知道结果如何-如果可以的话,我很乐意帮忙。 - snerd

4
紧密跟随着jbehave入门指南教程的步骤,其中的运行story 部分说:[...] ICanToggleACell.java类将能够作为JUnit测试运行。 这意味着您的构建路径中需要JUnit库。
使用Eclipse:
  1. 选择当前项目并右键单击它,Build pathConfigure Build Path...
  2. [当前项目]属性,Java Build PathLibraries,点击[Add Library...]
  3. 添加库,选择JUnit,点击[下一步]
  4. JUnit库,JUnit库版本,选择您希望使用的版本,点击[完成]
  5. Java Build Path,点击[确定]
  6. Project Explorer,选择您的ICanToggleACell.java类,右键单击它,然后选择“Run As”,点击JUnit Test
因此,在上面的示例代码中,StackBehaviourStory.java类应在您将正确的库添加到Java构建路径后能够作为JUnit测试运行。

0
在我的情况下,我已经从JBehave核心中的Steps类扩展了我的Steps类。

展示一些示例代码以说明你的观点可能会很有趣。=) - Will Marcouiller

0

我已将 JunitStory 更新为 JunitStories,它可以正常工作。

public class StackBehaviourStory extends JUnitStory ---> JunitStories


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接