JBehave

上篇我们说到如何从Github上clone出一个JBehave项目,既是为了学习JBehava,也是为了熟悉下Github
从clone下来的项目看来,基本没什么问题,稍微捋一捋就可以运行,但是就clone下来的代码来看,自己还是遇到一个问题(不知道是代码问题,还是我自己的操作有问题),就是没有办法运行(后面会详说)。
正如上篇所说,构建一个JBehave的应用的5大步骤:

  1. Write story
  2. Map steps to Java
  3. Configure Stories
  4. Run Stories
  5. View Reports

这里,我们结合clone下来的项目分别对应这五个步骤了解JBehave是如何运行的并完成测试的。
1.Write story,设定一个story,给出一个情景,使用通用语言进行表示,不管是开发或是非开发的都能看懂
本项目有两个测试案例,一个是模拟登录的story:

1
2
3
4
5
6
7
8
9
10
11
loginYahoo.story:
Narrative:
 
In order to show the yahoo function
As a user
I want to login yahoo
 
Scenario: normal login
 
Given yahoo login address by.bouncer.login.yahoo.com
Then print successful

  

另一个是模拟浏览的story:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
TestStroies.story:
Browse Etsy.com
 
Meta:
@category browsing
@color red
 
 
Narrative:
 
In order to show the browsing cart functionality
As a user
I want to browse in a gallery
 
Scenario: Browsing around the site for items
 
Given I am on localhost
Then print hello world
 
!--Examples:
!--|host|hello|
!--|localhost|hello world|
!--|www.baidu.com|hello baidu|

  

2.Map steps to Java, 将上述的每个story细分成每一个step,给出Given条件,则会得到Then的结果,从而将通用语言转换成可以通过代码逻辑描述的问题
loginYahoo.story对应的steps类TestLogin.java:

1
2
3
4
5
6
7
8
9
10
11
public class TestLogin {
        @Given("yahoo login address $url")
        public void getHostPage(String url){
            System.out.println("++++++++++++++++++++++++++++++"+url);
        }
 
        @Then("print $successful")
        public void hello(String successful){
            System.out.println("++++++++++++++++++++++++++++++"+successful);
        }
}

  

TestStories.story对应的steps类TestStep.java:

1
2
3
4
5
6
7
8
9
10
11
public class TestStep {
    @Given("I am on $host")
    public void getHostPage(String host){
        System.out.println("----------------------"+host);
    }
 
    @Then("print $hello")
    public void hello(String hello){
        System.out.println("----------------------"+hello);
    }
}

  

3.Configure Stories 配置一些映射关系,比如如何找到并加载story文件等

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
public class EmbedderBase extends Embedder{
 
    @Override
    public EmbedderControls embedderControls() {
        return new EmbedderControls().doIgnoreFailureInStories(true).doIgnoreFailureInView(true);
    }
  
    @Override
    public  Configuration configuration() {
        Class<? extends EmbedderBase> embedderClass = this.getClass();
      //MostUsefulConfiguration使用默认的配置
        return new MostUsefulConfiguration()
            //设置story文件的加载路径
            .useStoryLoader(new LoadFromClasspath(embedderClass.getClassLoader()))
            //设定生成报告的相关配置
            .useStoryReporterBuilder(new StoryReporterBuilder()
                .withCodeLocation(CodeLocations.codeLocationFromClass(embedderClass))
                .withFormats(Format.CONSOLE, Format.TXT)
                .withCrossReference(new CrossReference()))
             //设定相关参数的转换
            .useParameterConverters(new ParameterConverters()
                    .addConverters(new DateConverter(new SimpleDateFormat("yyyy-MM-dd")))) // use custom date pattern
            .useStepMonitor(new SilentStepMonitor());                             
    }
}

  

4.Run Stories

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class TraderStoryRunner {
    @Test(groups={"test"})
    public void runClasspathLoadedStoriesAsJUnit() {
        // Embedder defines the configuration and candidate steps
        Embedder embedder = new TestStories();
        List<String> storyPaths = new StoryFinder().findPaths(CodeLocations.codeLocationFromClass(this.getClass()),"**/TestStories.story",""); // use StoryFinder to look up paths
        embedder.runStoriesAsPaths(storyPaths);
    }
    @Test(groups={"test"})
    public void runClasspathLoadedStories() {
        // Embedder defines the configuration and candidate steps
        Embedder embedder = new loginYahoo();
        List<String> storyPaths = new StoryFinder().findPaths(CodeLocations.codeLocationFromClass(this.getClass()),"**/loginYahoo.story",""); // use StoryFinder to look up paths
        embedder.runStoriesAsPaths(storyPaths);
    }
}

  

这里可以看出,声明了两个类TestStories和loginYahoo。
TestStories.java

1
2
3
4
5
6
7
8
public class TestStories extends EmbedderBase {
 
    @Override
    public InjectableStepsFactory stepsFactory() {
        return new InstanceStepsFactory(configuration(), new TestStep());//设定需要映射的step类
    }
  
}

  

loginYahoo.java:

1
2
3
4
5
6
7
8
public class loginYahoo extends EmbedderBase {
  
    @Override
    public InjectableStepsFactory stepsFactory() {
        return new InstanceStepsFactory(configuration(), new TestLogin());//设定需要映射的step类
    }
  
}

  

这两个类是一个桥梁的作用,用于设定从story到step的映射,注意这里的两个类是继承类EmbedderBase的,而EmbedderBase类又是Embedder的子类

这是项目给出的测试类TraderStoryRunner,但是这里有一个问题,就是没有找到运行的入口,点击右键,除了一些maven的操作,并没有其他可以运行的指标,比如junit。
所以通过摸索,按照自己的方法,发现首先要做的就是添加junit测试库,这是必须的。具体步骤:
右键项目->Build path->Configured build path

打开对话框,选择Libraries->Add Library->JUnit,点击next,选择junit4->finished。

添加完Junit后,新建一个Junit测试类

将TraderStoryRunner类的主体方法放进去,命名为Tc.java

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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
import static org.junit.Assert.*;
import java.util.List;
import org.jbehave.core.embedder.Embedder;
import org.jbehave.core.io.CodeLocations;
import org.jbehave.core.io.StoryFinder;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
 
import com.story.TestStories;
import com.story.loginYahoo;
public class Tc {
 @BeforeClass
 public static void setUpBeforeClass() throws Exception {
 }
 @AfterClass
 public static void tearDownAfterClass() throws Exception {
 }
 @Before
 public void setUp() throws Exception {
 }
 @After
 public void tearDown() throws Exception {
 }
  
 // @Test : 表示这是一个测试用例,只有标识了改符号的函数才会被执行测试
 
 @Test
 public void runClasspathLoadedStoriesAsJUnit() {
     // Embedder defines the configuration and candidate steps
     Embedder embedder = new TestStories();
     List<String> storyPaths = new StoryFinder().findPaths(CodeLocations.codeLocationFromClass(this.getClass()),"**/TestStories.story",""); // use StoryFinder to look up paths
     embedder.runStoriesAsPaths(storyPaths);
 }
    @Test
 public void runClasspathLoadedStories() {
     // Embedder defines the configuration and candidate steps
     Embedder embedder = new loginYahoo();
     List<String> storyPaths = new StoryFinder().findPaths(CodeLocations.codeLocationFromClass(this.getClass()),"**/loginYahoo.story",""); // use StoryFinder to look up paths
     embedder.runStoriesAsPaths(storyPaths);
 }
}

至此,这个项目是可以运行起来了。

5.View Reports
点击运行上面的Tc.java类,可以得到:

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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
Processing system properties {}
Using controls EmbedderControls[batch=false,skip=false,generateViewAfterStories=true,ignoreFailureInStories=false,ignoreFailureInView=false,verboseFailures=false,verboseFiltering=false,storyTimeoutInSecs=300,threads=1]
 
(BeforeStories)
 
Running story com/story/TestStories.story
Narrative:
In order to show the browsing cart functionality
As a user
I want to browse in a gallery
Browse Etsy.com
(com/story/TestStories.story)
Meta:
@category browsing
@color red
 
Scenario: Browsing around the site for items
----------------------localhost
Given I am on localhost
----------------------hello world
 
!--Examples:
!--|host|hello|
!--|localhost|hello world|
!--|www.baidu.com|hello baidu|
Then print hello world
 
!--Examples:
!--|host|hello|
!--|localhost|hello world|
!--|www.baidu.com|hello baidu|
 
 
 
(AfterStories)
 
Generating reports view to 'C:\Program Files (x86)\Git\Jbehave\TestBehave_v2_testng\target\jbehave' using formats '[console, txt]' and view properties '{defaultFormats=stats, decorateNonHtml=true, viewDirectory=view, decorated=ftl/jbehave-report-decorated.ftl, reports=ftl/jbehave-reports-with-totals.ftl, maps=ftl/jbehave-maps.ftl, navigator=ftl/jbehave-navigator.ftl, views=ftl/jbehave-views.ftl, nonDecorated=ftl/jbehave-report-non-decorated.ftl}'
Reports view generated with 0 stories (of which 0 pending) containing 0 scenarios (of which 0 pending)
Processing system properties {}
Using controls EmbedderControls[batch=false,skip=false,generateViewAfterStories=true,ignoreFailureInStories=false,ignoreFailureInView=false,verboseFailures=false,verboseFiltering=false,storyTimeoutInSecs=300,threads=1]
 
(BeforeStories)
 
Running story com/story/loginYahoo.story
Narrative:
In order to show the yahoo function
As a user
I want to login yahoo
 
(com/story/loginYahoo.story)
Scenario: normal login
++++++++++++++++++++++++++++++by.bouncer.login.yahoo.com
Given yahoo login address by.bouncer.login.yahoo.com
++++++++++++++++++++++++++++++successful
Then print successful
 
 
 
(AfterStories)
 
Generating reports view to 'C:\Program Files (x86)\Git\Jbehave\TestBehave_v2_testng\target\jbehave' using formats '[console, txt]' and view properties '{defaultFormats=stats, decorateNonHtml=true, viewDirectory=view, decorated=ftl/jbehave-report-decorated.ftl, reports=ftl/jbehave-reports-with-totals.ftl, maps=ftl/jbehave-maps.ftl, navigator=ftl/jbehave-navigator.ftl, views=ftl/jbehave-views.ftl, nonDecorated=ftl/jbehave-report-non-decorated.ftl}'
Reports view generated with 0 stories (of which 0 pending) containing 0 scenarios (of which 0 pending)

 大体的思路,是将story和step对应起来,将story中的条件、参数传入step对应的类中,如果满足则通过测试,得到then给出的结果,否则得不到理想的结果。

JBehave的更多相关文章

  1. 开发人员看测试之细说JBehave

    上篇我们说到如何从Github上clone出一个JBehave项目,既是为了学习JBehava,也是为了熟悉下Github.从clone下来的项目看来,基本没什么问题,稍微捋一捋就可以运行,但是就cl ...

  2. 开发人员看测试之运行Github中的JBehave项目

    本文要阐述的主要有两点,一是介绍自动化测试框架JBehave,二是介绍如何在Github上拉项目,编译成myeclipse环境中的项目,并最终导入Myeclipse中运行. JBehave是何物? J ...

  3. (org.jbehave.core.failures.BeforeOrAfterFailed: webdriver selenium错误解决。

    (org.jbehave.core.failures.BeforeOrAfterFailed: Method initWebDriver (annotated with @BeforeStory in ...

  4. Atitit各种SDM 软件开发过程SDP sdm的ddd tdd bdd设计

    Atitit各种SDM 软件开发过程SDP sdm的ddd tdd bdd设计 1.1. software development methodology (also known as SDM 1 1 ...

  5. Java资源大全中文版(Awesome最新版)

    Awesome系列的Java资源整理.awesome-java 就是akullpp发起维护的Java资源列表,内容包括:构建工具.数据库.框架.模板.安全.代码分析.日志.第三方库.书籍.Java 站 ...

  6. Cucumber(一): Preparation

    Every time I wrote some code in ruby and executed our cucumber features I craved for something simil ...

  7. 开发人员看测试之TDD和BDD

    前言: 已经数月没有来园子了,写博客贵在坚持,一旦松懈了,断掉了,就很难再拾起来.但是每每看到自己博客里的博文的浏览量每天都在增加,都在无形当中给了我继续写博客的动力.最近这两天有听到Jbehave这 ...

  8. Android Testing学习01 介绍 测试测什么 测试的类型

    Android Testing学习01 介绍 测试测什么 测试的类型 Android 测试 测什么 1.Activity的生命周期事件 应该测试Activity的生命周期事件处理. 如果你的Activ ...

  9. 从手工测试转型web自动化测试继而转型成专门做自动化测试的学习路线。

    在开始之前先自学两个工具商业web自动化测试工具请自学QTP:QTP的学习可以跳过,我是跳过了的.开源web自动化测试工具请自学Selenium:我当年是先学watir(耗时1周),再学seleniu ...

随机推荐

  1. [转载]起动service保存android系统log( logcat服务)

    原文链接:http://www.myexception.cn/android/1904013.html 启动service保存android系统log 作为android开发工程师,出现了BUG是否苦 ...

  2. centos 64位编译安装 glibc-2.14

    cd /opt wget http://ftp.gnu.org/gnu/glibc/glibc-2.14.tar.gz tar -xzf glibc-2.14.tar.gz cd glibc-2.14 ...

  3. Unity3D之Vector3.Dot和Vector3.Cross采用

    在Unity3D中.Vector3.Dot表示求两个向量的点积;Vector3.Cross表示求两个向量的叉积.   点积计算的结果为数值,而叉积计算的结果为向量.两者要注意差别开来.   在几何数学 ...

  4. log4j 日志大小限制 分成30一个 不按日期分日志 按大小分成 按生产日期

    首先说说生成按日期.不解释,大家都懂的,这种方法的缺点是很吃硬盘空间 log4j.rootLogger=INFO,logfile,stdout log4j.logger.java.sql=DEBUG, ...

  5. HttpClient使用具体解释

    Http协议的重要性相信不用我多说了,HttpClient相比传统JDK自带的URLConnection,添加�了易用性和灵活性(详细差别,日后我们再讨论),它不仅是client发送Http请求变得e ...

  6. android 网络运营商的名字显示规则(锁定屏幕,下拉列表)

    一:Background & 有关flow MTK Operator name display分为两种类型的手机: 1. Sim卡名称: 从基于引导SIM卡读取IMSI到Spn-conf.xm ...

  7. cheese desktop内容

    #!/usr/bin/env xdg-open [Desktop Entry] Encoding=UTF- Version=1.0 Type=Application Terminal=false Na ...

  8. 【游戏】2048及各种变种大集合汇总【更新ing~新版Floppy2048 - 恒星聚变版 - 恶搞改数据】

    threes - 鼻祖 手机版:http://asherv.com/threes/ js版:http://threesjs.com/ 2048 - 原版 http://gabrielecirulli. ...

  9. spring改版官网下载jar包, 源代码和文档

    从网上找了一些方法,现在都整理了一下,有简单粗暴的,也有百转回肠的(详细,直接从官网一步一步的进入下载页),希望大家根据自己的喜好可以找到的真爱. 方法一:(简单粗暴直接) http://repo.s ...

  10. 自定义ViewGroup实现垂直滚动

    转载请表明出处:http://write.blog.csdn.net/postedit/23692439 一般进入APP都有欢迎界面,基本都是水平滚动的,今天和大家分享一个垂直滚动的例子. 先来看看效 ...