JBehave学习笔记

1、什么是JBehave 
JBehave是一个用java编写的BDD(Behavior-Driven-Design)框架, java界的Cucumber。(注: 1、BDD主要的目的是能够从业务领域专家的视角来编写测试用例,以解决技术人员和业务领域专家的沟通问题。2、Cucumber是基于Ruby的BDD框架) 
        
2、JBehave的特点 
1)、纯Java实现,能调用java API的地方就能使用。 
2)、能够定义和执行基于文本的Story,让我们能够从用户价值出发进行开发。(BDD都是这个目的)。 
3)、User stories可以放在classpath,也可通过外部URL传进来。 
4)、User stories可以并发执行且能够指定并发执行的线程数。 
5)、可以通过一些用户定义的信息把User Stories形成一部完整文档。 
6)、通过Anotation把Story的步骤对应到Java类中,还能够把自动把Story中的String参数转换成方法对应的参数类型。(How?) 
7)、基于Anotation的运行配置信息,指定Story对应的Steps类文件 
8)、支持通过第三方IOC容器(Spring,Guice,PicoContainer,Weld)管理配置信息和Steps类 
9)、支持通过Groovy写配置信息和Steps文件 
10)、支持报表,既可以生成可读性良好的报表格式(HTML,TXT ),还支持Json,XML格式供外部程序调用。 
11)、未实现的步骤会自动标记Pending 
12)、支持任何语言书写Story 
13)、可以使用Junit或者任何基于anotation的测试框架运行Story测试 
14)、支持Maven,Ant集成,通过脚本运行BDD测试脚本。 

3、JBehave的结构 
Story:系统想要具有的功能 
Scenario:Story描述的功能的Key-Example 。插一句,如果一个功能你不能想出一个很好的例子,那么你就需要好好想想这个功能的价值了。个人感觉,此处借用了《Specification By Examples》的思想,以实例说明功能更容易让人理解。 
Steps:Scenario中描述的实例的具体执行步骤。 

4、JBehave的语法 
下面就是一个JBehave story的例子 
Story代码   收藏代码
  1. Meta:  
  2. @category basic  
  3. @color blue  
  4.   
  5. Narrative:   
  6.   
  7. In order to show the basic cart functionality  
  8. As a user  
  9. I want to add and remove items from the cart  
  10.   
  11. Scenario: Item can be added to cart  
  12.   
  13. Given that the cart is empty  
  14. !-- We don't care for which item is added to the cart  
  15. When I search for an item  
  16. And an item is added to the cart  
  17. Then the cart contains that item  
  18.   
  19. Scenario: Item can be removed from cart  
  20.   
  21. Given the cart contains one item  
  22. When the item is removed  
  23. Then the cart contents is empty  

上面的例子中基本上涵盖了JBehave的所有关键字(标红的词语就是JBehave的关键字) 
Meta: 以键值对的方式提供一些关于Story和Scenario的标签信息,我们在运行Story的时候,可以通过这些标签作为过滤项,只运行我们想运行的信息。 
Narrative: 对当前Story对应功能的一个描述,和一般Story卡上的描述差不多,In order to ….,As a ……,I want to……。 
Scenario:  关于当前场景的描述 
Given : 描述当前场景的Context的Step 
!--    :  JBehave中的注释符 
When: 描述用户进行操作的Step 
Then:  描述验收用户操作结果的Step, 
And : Step的辅助描述关键字,跟着哪个Step就表示哪个Step的意思,如跟着When后面就表示When。 


另外这个例子中未提到的关键字还有: 
GivenStories: 在当前Story中依赖另一个Story。 
Examples: 可以指定一系列的数据反复跑一个Scenario。 

5、一个JBehave的BDD测试的实现步骤 
1)、配置JBehave开发环境 
2)、按照上面的语法和业务领域专家一起写文本Story。 
3)、把文本Story对应到具体执行的java文件中(通过java的Anotation技术) 
4)、配置JBehave的运行规则。 
5)、运行测试 

6)、查看测试报告 


1、配置JBehave环境。 
1)、添加JBehave依赖包,基本的只需要添加jbehave-core和Junit包就足够了。 
2)、配置IntelliJ的JBehave插件,详情参见https://github.com/kumaraman21/IntelliJBehave/wiki 

2、实现一个JBehave的Story基本过程 

  JBahave的测试用例主要由3部分组成,描述测试功能的story文件,story文件对应的Steps类和基于Junit的运行配置文件。Steps类是通过Anotation和正则匹配技术把story文件中的文本Step对应到Steps类中的方法,运行配置文件的主要作用是告诉junit去哪儿找story文件和Steps文件,把其配置在同一个Context中。实现一个story的基本过程如下: 

1)、写Story 

Story代码   收藏代码
  1. Meta:  
  2. @author liuxianning  
  3. @theme  student  
  4.   
  5. Narrative: In order to get a new student,as a teacher, I want to add a student into the Class  
  6.   
  7. Scenario: Add a student into the class  
  8.   
  9. Given There is a student  
  10. And his name is 'Lincoln'  
  11. And his age is '18'  
  12. And his hobby is 'basketball'  
  13. And his father's name is 'Mike'  
  14. And his mother's name is 'Mary'  
  15. And his brother's name is 'Luis'  
  16. When system add the student into class  
  17. Then we can get student 'Lincoln2' from class  

2)、写Story对应的Steps类 
Java代码   收藏代码
  1. public class StudentSteps {  
  2.     private ClassRoom classRoom;  
  3.     private Student student;  
  4.   
  5.     @Given("There is a student")  
  6.     public void initStudent() {  
  7.         student = new Student();  
  8.     }  
  9.   
  10.     @Given("his name is '$name'")  
  11.     public void setName(@Named("name")String name) {  
  12.         student.setName(name);  
  13.     }  
  14.   
  15.     @Given("his age is '$age'")  
  16.     public void setAge(@Named("age")Integer age) {  
  17.         student.setAge(age);  
  18.     }  
  19.   
  20.     @Given("his hobby is '$hobby'")  
  21.     public void setHobby(@Named("hobbu")String hobby) {  
  22.         student.setHobby(hobby);  
  23.     }  
  24.   
  25.     @Given("his father's name is '$fatherName'")  
  26.     public void setFatherName(@Named("fatherName")String fatherName) {  
  27.         student.setFatherName(fatherName);  
  28.     }  
  29.   
  30.     @Given("his mother's name is '$motherName'")  
  31.     public void setMotherName(@Named("motherName")String motherName) {  
  32.         student.setMotherName(motherName);  
  33.     }  
  34.   
  35.     @Given("his brother's name is '$brotherName'")  
  36.     public void setBrotherName(@Named("brotherName")String brotherName) {  
  37.         student.setBrotherName(brotherName);  
  38.     }  
  39.   
  40.     @When("system add the student into class")  
  41.     public void addStudentIntoClass(){  
  42.         classRoom = new ClassRoom();  
  43.         classRoom.addStudent(student);  
  44.     }  
  45.   
  46.     @Then("we can get student '$studentName' from class")  
  47.     public void checkGetStudent(@Named("studentName")String studentName){  
  48.          assertThat(student, is(classRoom.getStudent(studentName)));  
  49.     }  
  50. }  

3)、配置运行环境 
Java代码   收藏代码
  1. public class StudentStories extends JUnitStories {  
  2.   
  3.     public Configuration configuration() {  
  4.         return new MostUsefulConfiguration().useStoryLoader(new LoadFromClasspath(this.getClass()))  
  5.                 .useStoryReporterBuilder(new StoryReporterBuilder().withCodeLocation(codeLocationFromClass(this.getClass())));  
  6.   
  7.     }  
  8.   
  9.     @Override  
  10.     protected List<String> storyPaths() {  
  11.         return new StoryFinder().findPaths(codeLocationFromClass(this.getClass()),"**/*.story","");  
  12.   
  13.     }  
  14. }  

4)、执行结果,执行StudentStories类,即可得到运行结果。 


1、Composite Steps 
顾名思义就是能够把多个Steps组合为一个Step。例子

Story代码   收藏代码
  1. Meta:  
  2. @author liuxianning  
  3. @theme  composite  
  4.   
  5. Narrative: This story is used to show composite steps.  
  6.   
  7. Scenario: Add a student into the class  
  8.   
  9. Given There is a student with default details  
  10. When system add the student into class  
  11. Then we can get student 'Lincoln2' from class  


然后在StudentSteps中增加方法
Java代码   收藏代码
  1. @Given("There is a student with default details")  
  2. @Composite(steps = {  
  3.         "Given his name is 'Lincoln2'",  
  4.         "Given his age is '18'",  
  5.         "Given his hobby is 'basketball'",  
  6.         "Given his father's name is 'Mike'",  
  7.         "Given his mother's name is 'Mary'",  
  8.         "Given his brother's name is 'Luis'"  
  9. })  
  10. public void createStudentWithDefaultDetails() {  
  11. }  

这样就可以用一句话执行之前已经实现的很多步骤。 

2、Tabular parameters 
表结构参数,这是一个简化和结构化参数输入的特性,我们可以在一个步骤中把需要传递的多个参数结构化的传递给Step方法。例子: 
Story代码   收藏代码
  1. Meta:  
  2. @author liuxianning  
  3. @theme  table  
  4.   
  5. Narrative: In order to get a new student,as a teacher, I want to add a student into the Class  
  6.   
  7. Scenario: Add a student into the class  
  8.   
  9. Given There is a student  with details:  
  10. |name    |age |hobby      |father name |mother name |brother name|  
  11. |lincoln3|18  |basketball |Mike        |Mary        |Luis        |  
  12.   
  13. When system add the student into class  
  14. Then we can get student 'lincoln3' from class  

可以通过一个Table以键值对的形势来输入参数,在StudentSteps添加对应的方法来接收参数 
Java代码   收藏代码
  1. @Given("There is a student  with details:$details")  
  2.     public void setDetails(@Named("details") ExamplesTable details) {  
  3.         student = new Student();  
  4.         Parameters parameters = details.getRowAsParameters(0);  
  5.         student.setName(parameters.valueAs("name",String.class));  
  6.         student.setAge(parameters.valueAs("age",Integer.class));  
  7.         student.setHobby(parameters.valueAs("hobby",String.class));  
  8.         student.setFatherName(parameters.valueAs("father name",String.class));  
  9.         student.setMotherName(parameters.valueAs("mother name",String.class));  
  10.         student.setBrotherName(parameters.valueAs("brother name",String.class));  
  11.     }  


3、Examples 
Scenario多实例,这个特性主要的目的在于可以使用不同的数据反复执行一个Scenario。例子:
Story代码   收藏代码
  1. Meta:  
  2. @author liuxianning  
  3. @theme  examples  
  4.   
  5. Narrative: In order to get a new student,as a teacher, I want to add a student into the Class  
  6.   
  7. Scenario: Add a student into the class  
  8.   
  9. Given There is a student  
  10. And his name is '$name'  
  11. And his age is '$age'  
  12. When system add the student into class  
  13. Then we can get student '$studentName' from class  
  14.   
  15. Examples:  
  16. |name|age|studentName|  
  17. |lxn1|18 |lxn1       |  
  18. |lxn2|19 |lxn2       |  
  19. |lxn3|20 |lxn3       |  

该实例中回使用Examples中的数据反复执行该Scenario。 

4、Meta Filtering 
Meta信息过滤,这个特性允许JBehave指定运行特定的Story或者Scenario。使用方法为在配置Embedder的时候添加上MetaFilter属性。
Java代码   收藏代码
  1. public Embedder configuredEmbedder() {  
  2.         Embedder embedder = new Embedder();  
  3.         embedder.useConfiguration(configuration());  
  4.         embedder.useCandidateSteps(candidateSteps());  
  5.         embedder.useStepsFactory(stepsFactory());  
  6.       [color=red]  embedder.useMetaFilters(asList("+theme composite""-skip"));[/color]  
  7.         return embedder;  
  8.     }  

在标红的代码段中指明了只执行Meta段中属性theme为composite的Story。 

5、GivenStories 
Story依赖,这个特性让一个Story可以作为另一个Story的Scenario的前提条件。例子 
Story代码   收藏代码
  1. Meta:  
  2. @author liuxianning  
  3. @theme  givenstories  
  4.   
  5. Narrative: In order to maintian student's info,as a teacher, I want to update a student's name  
  6. Scenario: Add a student into the class  
  7. GivenStories: AddStudentIntoClass.story  
  8. Given Get student "Lincoln"  
  9. When system Update student name to "Lin"  
  10. Then we can get student 'Lin' from class  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值