behave是python语言的行为驱动开发,全称:Behavior-driven development,简称BDD,它是一种敏捷软件开发技术,它鼓励软件项目中的开发人员、QA和非技术或业务参与者之间进行协作,本文给大家介绍Python Behave框架,感兴趣的朋友一起看看吧
behave是python语言的行为驱动开发,全称:Behavior-driven development,简称BDD。
BDD框架
BDD即行为驱动开发(Behavior Driven Development),其特点为:
- 通过自然语言来定义系统行为
- 从功能使用者的角度,编写需求场景
- 鼓励软件项目中的开发者、非技术人员以及商业参与者之间的协作。协作的核心是通过活文档或者说场景文档来协作,该文档既是测试用例文档,也是需求定义文档
- 常见的BDD框架有Behave,Cucumber等
它是一种敏捷软件开发技术,它鼓励软件项目中的开发人员、QA和非技术或业务参与者之间进行协作。
python behave的官方网址:
Feature Testing Setup — behave 1.2.7.dev2 documentation
最初由Dan North命名,并于2009年对BDD给出了如下定义:
“BDD是第二代、由外而内、基于拉动、多利益相关者、多规模、高度自动化、敏捷的方法。
它描述了一个与定义明确的输出交互的循环,从而交付了重要的工作、测试软件。”
BDD并不会描述或定义软件怎么做,而是能做了什么。最终通过python代码进行验证。
首先用pycharm创建项目Python-Behave,python环境选择Virtualenv,接着安装behave包。
在项目Python-Behave下创建一个名为“features”的目录(这个目录名称是随意的),可以在这个目录下定义所有behave的文件结构。
在features目录下创建一个“.feature”文件,这是一种叫作“Gherkin”的语言。它对非技术人员比较友好,可以使用自然语言编写。
“.feature”文件有两个用途:文档和自动化测试。一句话,在“.feature”里编写测试场景。
很多文章提到Gherkin语言必须用pycharm专业版才能编写,但是我亲测用pycharm社区版也是可以编写的。
“.feature”文件的结构:
主体由多个场景Scenario组成,可以选用Background和tag进行约束。
feature文件的一个基本的结构为:
1 2 3 4 5 6 |
|
- Feature是功能名称
- Scenario是场景描述
- Given是此场景下的前提条件
- When是此场景下的操作步骤
- Then是此场景下的预期结果
如果有多个测试场景呢,就再加一个Scenario。如果Scenario下的Given/When/Then有多个呢?
可以用And或But表示。
所以
1 2 3 4 5 6 7 |
|
也可以这样写作
1 2 3 4 5 6 7 |
|
这种方式阅读会更流畅
当然,上面只是一个简单的feature结构,更复杂一点的,比如说这样:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
|
Background由一系列类似于Scenario的步骤组成,它的目的是为Scenario添加上下文,在Scenario执行之前执行Background,用于设置Scenario的前提条件。
Scenario由一系列步骤组成,它描述了Feature的一种场景。如果一种场景有多种情况呢?
比如登录这个Scenario,不同的登录名和密码,登录的结果不同。这种情况可以不需要写多个Scenario描述,可以使用Scenario Outline和Examples来完成。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
在上面这个例子中,用Scenario Outline描述“Blenders”场景,用多个Examples表示场景的多种类型,每个Examples下可以包含多种情况。不同情况的列举在Scenario Outline用符号“<key>”表示,在Examples中用key列举
Scenario由一系列步骤组成,步骤由关键字“Given”、“When”、“Then”、“And”、“But”为开头。Python Behave实际运行的也是这些步骤。
具体实现是通过此项目下的steps目录里的“.py”文件实现所有的Scenario的步骤。这里要注意,steps目录名是确定的不能改变的,但是里面的py文件名是随意的。
python behave项目的执行方式也并不是通过运行steps目录里的py文件,而是通过命名behave调用“.feature”文件,映射到py文件里的步骤下的函数,执行这些函数。
步骤描述要尽量简洁,但有时会附带一些文本text或表格table。如果python代码需要使用这些text或table,则可以通过访问属性“context.text”或”context.table“来使用。
Text:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
Table:
1 2 3 4 5 6 7 8 9 10 |
|
Python中访问:
1 2 3 4 |
|
这个表格在python中是这样的数据类型:
1 |
|
认真体会下!!!
Tags:
tags用于标记Feature、Scenario或Scenario Outlook,可以选择性的只执行被标记的。
例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
如果只想执行Scenario: Weaker opponent,可以对它进行标记为@slow,然后运行“behave --tags=slow”。
如果想执行除标记@slow外的其他场景,可以运行“behave --tags=“not slow””。
组合使用tags标签:
–tags=“wip or slow”,选择所有标记为wip或slow的case
–tags=“wip and slow”,选择所有标记为wip和slow的case
以上讲的是如何用“.feature”文件编写所有测试场景。虽然是通过命令behave xxx.feature触发,但实际的执行操作是在steps目录下的“.py”实现。
所以,要如何把“.feature”里的所有步骤映射到“.py”中,还必须按照顺序不能出错,这就成为了一个关键。
假设给定一个Senario:
1 2 3 |
|
记住,只对所有的步骤按顺序实现,并不会对Scenario进行映射。
在python中实现如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
按照“.feature”中的步骤的顺序,将步骤的前面的关键字,在python中用装饰器匹配(@give、@when、@then),()里面是步骤描述。
如果是And或But,在python中用它们被重命名以前的关键字。也就是说,在python中,不可能有@and或@but。
然后在装饰器下方定义函数,函数名随意。函数体就是步骤的具体实现。
如果你想在某个步骤里执行另一个步骤,只需要用context对象调用execute_steps()函数,里面传入被调用步骤。
1 2 3 4 5 6 |
|
如果你想把“.feature”的步骤上的信息传递到“.py”中,可以在py文件中用中括号加关键字表示“{key}”。
比如访问百度首页:
1 2 3 4 |
|
关于其中输入百度网址,在python中就可以这样实现:
1 2 3 |
|
Context:
聪明的你一定注意到了,在py文件中每个步骤下的函数内第一个参数是context,它是Feature或Scenario的实例化,可以用来传递信息。
如何传递呢,这里我们暂且按下不表,先思考一个问题。
如果我有一个场景,打开百度网页,输入关键字搜索,然后查看搜索结果。
在feature文件中如何描述,这个我们应该已经学会了。在py文件中如何实现,我们也不陌生了。
1 2 3 4 |
|
1 2 3 4 5 6 7 8 |
|
后面我就不写了。现在只看given的步骤,你应该就能发现问题,context.driver哪来的,从已知的上下文中并没有相关信息。
如果你再仔细的思考一下,就会发现这里少了一步,我们在打开百度网站前,是不是应该先打开浏览器,然后才是输入百度网址。
如果你有多个关于网页搜索的场景,你是不是应该每次执行Scenario前都要打开浏览器,执行完毕关闭浏览器。这个操作类似于python unittester中的setup()和teardown()的用法。
那python behave框架中,对于操作前和操作后的前置条件和后置条件,是放在了“environment.py”文件中定义。
它有以下几种:
- before_step(context, step)和after_step(context, step),每一步之前和之后运行
- before_scenario(context, scenario)和after_scenario(context, scenario),每个场景运行之前和之后运行
- before_feature(context, feature)和after_feature(context, feature),每个feature文件执行之前和之后运行
- before_tag(context, tag)和after_tag(context, tag),每个标签调用之前和之后运行
- before_all(context)和after_all(context),整个behave之前和之后运行
那上面的例子中,在environment.py中实现打开和关闭浏览器的操作,要这样实现:
1 2 3 4 5 6 7 8 |
|
前置条件和后置条件在environment.py中用上面列举的函数直接定义,函数名和形参必须符合规范。
可以看出,如果environment.py中的信息、变量或对象需要在steps中的py文件中被使用,可以用context来存储。
这里就把打开的浏览器对象赋值给了context下定义的driver属性,然后在py文件中直接可以使用context.driver,就相当于使用这个浏览器了。
注意注意,environment.py文件在python behave项目中的位置是哪里?是steps目录中吗?
不是的,environment.py文件是和“.feature”文件、steps目录并列在同一目录下的。而且它的名称必须是environment.py。
现在回头看下一个完整的python behave项目的最低结构要求:
1 2 3 4 |
|
更复杂的目录为:
1 2 3 4 5 6 7 8 9 |
|
最后,如何执行behave的程序?
不是执行的steps目录里的py文件,而是通过cmd打开命令行窗口,执行:“behave xxx.feature”。
这样也很麻烦,有没有一种方式可以在py文件的主入口里执行"behave xxx.feature",这样可以封装成exe程序,双击运行exe,即可运行behave。
在python behave项目目录下创建一个py文件(也就是和feature文件、steps目录文件在同一级下),命名为main.py,然后写一个主入口程序:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|