用behave(Python)定义场景的顺序(或必需场景)
我正在用behave来测试我的小Django应用。
我已经创建了一个叫做 user_management.feature
的文件,其中包含了这个场景:
Scenario: register
Given I can access registration form
When I put "doctor" in "username" field
And I put "tardisBlue" in "password" field
And I put "doctor@tardis.com" in "email" field
And I press the "Register" button
Then the registration is successful
And I am logged in
一切运行得很好。
接下来我想开发的功能在文件 project_management.feature
中:
Scenario: create a project
Given I am logged in
When I go to the home page
And I click on "Create new Project" link
And I fill the fields
| field | text |
| name | Save Gallifrey |
And I click on "Save" button
And I go to the home page
Then I see the project name in the project list
现在,当我执行测试时,behave会按字母顺序执行这些功能文件,所以 project_management.feature
会先被执行。
这会在第一个 given
处引发错误,因为用户还没有被创建。
我试着把第一个文件重命名为 01_user_management.feature
,这样就能正常工作了。
你知道有没有更好的解决办法吗?
有没有什么配置文件可以让我指定功能文件的执行顺序?
或者我能否告诉系统某个场景需要先运行另一个场景?
4 个回答
来自@Andrew Johnson和jenisys的回答提供了三种指定步骤/场景/功能顺序的方法。在这里,我再补充几种方法:
- 基本上和jenisys提到的列表文件是一样的,当你在命令行中指定功能文件时,功能会按照你写的顺序执行。虽然这似乎没有官方文档说明,但这是我观察到的情况。
- 你还可以使用标签来控制命令行中运行哪些场景。比如用--tags=t1,t2,t3,这些场景会严格按照你写的顺序执行。非常方便。
使用 feature-listfiles,像这样:
behave @my_foo.featureset …
配合使用:
# -- FILE: my_foo.featureset
features/alice.feature
features/bob.feature:10
这件事似乎有两种方法可以解决。第一种是你可以使用Background来为多个场景设置初始状态。第二种是从其他步骤调用之前的步骤。第一种方法的示例大概是这样的:
Feature: logins
Test login functionality
Background: login
Given I can access registration form
And I put "doctor" in "username" field
And I put "tardisBlue" in "password" field
And I put "doctor@tardis.com" in "email" field
And I press the "Register" button
Scenario: successful login
Then the registration is successful
And I am logged in
Scenario: create a project
When I go to the home page
And I click on "Create new Project" link
And I fill the fields
| field | text |
| name | Save Gallifrey |
And I click on "Save" button
And I go to the home page
Then I see the project name in the project list
你不应该让测试场景相互依赖。 这样做是完全可能的。我有多个大型复杂的测试套件,里面有上百个场景。我的每个场景都不依赖于之前运行的其他场景。
当你的测试套件很大,而其中有一个场景失败时,能够做到以下这一点是非常有用的:
behave -n 'failing scenario name'
这会让Behave只运行失败的场景。还有一个方法是使用 @wip
标签,它也能实现同样的效果。不过,如果你想测试的场景依赖于另一个场景,Behave就不会自动知道应该先运行那个场景。因此,你需要 a) 知道这种依赖关系,b) 手动选择所有你想运行的场景所依赖的场景。
在你的情况下(这也是我过去做过的),我会实现一个步骤 Given I am logged in as ...
。我用正则表达式来实现它,这样我就可以使用
Given I am logged in as an administrator
Given I am logged in as a regular user
Given I am logged in as a user with permissions to delete articles
我正在测试的应用程序的数据库里预先加载了一些测试用户,这些用户对应于上面的案例。(还有一个测试是注册新用户,但这与预加载的用户是独立的。)这个 Given I am logged in as ...
步骤只是让用户登录,并不需要创建用户。
这样做的一个附带好处是,如果你在像Sauce Labs或BrowserStack这样的测试服务上运行你的测试套件,并使用Selenium,你可以实现 Given I am logged in as ...
步骤来节省大量测试时间。在这种情况下,每个Selenium命令都需要在你的Behave测试和在测试服务上运行的浏览器之间进行一次往返,这在互联网上可能需要相当长的时间。减少这种交互的次数可以大大缩短整个测试套件的运行时间。