JBehave
JBehave
上篇我们说到如何从Github上clone出一个JBehave项目,既是为了学习JBehava,也是为了熟悉下Github。
从clone下来的项目看来,基本没什么问题,稍微捋一捋就可以运行,但是就clone下来的代码来看,自己还是遇到一个问题(不知道是代码问题,还是我自己的操作有问题),就是没有办法运行(后面会详说)。
正如上篇所说,构建一个JBehave的应用的5大步骤:
- Write story
- Map steps to Java
- Configure Stories
- Run Stories
- 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 functionAs a userI want to login yahooScenario: normal loginGiven yahoo login address by.bouncer.login.yahoo.comThen 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.comMeta:@category browsing@color redNarrative:In order to show the browsing cart functionalityAs a userI want to browse in a galleryScenario: Browsing around the site for itemsGiven I am on localhostThen 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.storyNarrative:In order to show the browsing cart functionalityAs a userI want to browse in a galleryBrowse Etsy.com(com/story/TestStories.story)Meta:@category browsing@color redScenario: Browsing around the site for items----------------------localhostGiven 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.storyNarrative:In order to show the yahoo functionAs a userI want to login yahoo(com/story/loginYahoo.story)Scenario: normal login++++++++++++++++++++++++++++++by.bouncer.login.yahoo.comGiven yahoo login address by.bouncer.login.yahoo.com++++++++++++++++++++++++++++++successfulThen 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的更多相关文章
- 开发人员看测试之细说JBehave
上篇我们说到如何从Github上clone出一个JBehave项目,既是为了学习JBehava,也是为了熟悉下Github.从clone下来的项目看来,基本没什么问题,稍微捋一捋就可以运行,但是就cl ...
- 开发人员看测试之运行Github中的JBehave项目
本文要阐述的主要有两点,一是介绍自动化测试框架JBehave,二是介绍如何在Github上拉项目,编译成myeclipse环境中的项目,并最终导入Myeclipse中运行. JBehave是何物? J ...
- (org.jbehave.core.failures.BeforeOrAfterFailed: webdriver selenium错误解决。
(org.jbehave.core.failures.BeforeOrAfterFailed: Method initWebDriver (annotated with @BeforeStory in ...
- 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 ...
- Java资源大全中文版(Awesome最新版)
Awesome系列的Java资源整理.awesome-java 就是akullpp发起维护的Java资源列表,内容包括:构建工具.数据库.框架.模板.安全.代码分析.日志.第三方库.书籍.Java 站 ...
- Cucumber(一): Preparation
Every time I wrote some code in ruby and executed our cucumber features I craved for something simil ...
- 开发人员看测试之TDD和BDD
前言: 已经数月没有来园子了,写博客贵在坚持,一旦松懈了,断掉了,就很难再拾起来.但是每每看到自己博客里的博文的浏览量每天都在增加,都在无形当中给了我继续写博客的动力.最近这两天有听到Jbehave这 ...
- Android Testing学习01 介绍 测试测什么 测试的类型
Android Testing学习01 介绍 测试测什么 测试的类型 Android 测试 测什么 1.Activity的生命周期事件 应该测试Activity的生命周期事件处理. 如果你的Activ ...
- 从手工测试转型web自动化测试继而转型成专门做自动化测试的学习路线。
在开始之前先自学两个工具商业web自动化测试工具请自学QTP:QTP的学习可以跳过,我是跳过了的.开源web自动化测试工具请自学Selenium:我当年是先学watir(耗时1周),再学seleniu ...
随机推荐
- 通过openssh远程登录时的延迟问题解决
Linux下的ssh 服务器一般用的都是open-ssh,可是发现有些时候通过ssh连接服务器时总会有大概10秒钟左右的延迟. 一开始以为是openssh的安全策略,防止端口扫描,后来发现自己想多了. ...
- [C++]四种方式求解最大子序列求和问题
问题 给定整数: A1,A2,-,An,求∑jk=iAk 的最大值(为方便起见,假设全部的整数均为负数,则最大子序列和为0) 比如 对于输入:-2,11,-4,13,-5,-2,答案为20,即从A2到 ...
- android最新的工具DateHelper
最新的工具DateHelper 实用程序类,.的天数来获得一个给定的月份.过了几天去习惯或.周.一个月.日期等.. 代码例如以下: import android.annotation.Suppress ...
- 采用truelicense进行Java规划license控制 扩展可以验证后,license 开始结束日期,验证绑定一个给定的mac住址
采用truelicense进行Java规划license控制 扩展可以验证后,license 开始结束日期,验证绑定一个给定的mac住址. Truelicense 它是一个开源java license ...
- DocFX
微软开源全新的文档生成工具DocFX 微软放弃Sandcastle有些年头了,微软最近开源了全新的文档生成工具DocFX,目前支持C#和VB,类似JSDoc或Sphinx,可以从源代码中提取注释生成文 ...
- 第九讲:HTML5该canvas推箱子原型实现
<html> <head> <title>动</title> <script src="../js/jscex.jscexRequire ...
- struts开发步骤
说来惭愧.这是一个简单的struts折腾了很长一段时间,几乎相同的时间量就花了三天时间来解决.下面的步骤总结一下我开发:(我使用的是MyEclipse); 1.新建一个Exercise3的web Pr ...
- UVa 11587 - Brick Game
称号:背景:brick game有N块,给你一个整数的定数S,两个人轮流木: 的木块数是集合S中存在的随意数字.取走最后木块的人获胜.无法取则对方获胜. 题干:如今让你先取,给你一个你的结果序列串T, ...
- NGUI 3.5教程(四)Atlas和Sprite(制作图片button)
Atlas是NGUI的图集.我的理解是:Atlas把你的一些零散的图片,合并成一张图.这样做的优点是,能够减少Draw Call.我不了解它的底层运作机制,我猜应该也是再行进DXT之类的纹理压缩,所以 ...
- [原创].NET 分布式架构开发实战之四 构建从理想和实现之间的桥梁(前篇)
原文:[原创].NET 分布式架构开发实战之四 构建从理想和实现之间的桥梁(前篇) .NET 分布式架构开发实战之四 构建从理想和实现之间的桥梁(前篇) 前言:上一篇文章讲述了一些实现DAL的理论,本 ...