编写BDD测试的策略是什么,可以测试依赖于系统中某些数据的行为?
例如,假设我正在使用以下方案:
Feature: Search for friend
In order to find a friend
As a user
I want to search my list of friends
And filter by 'first name'
除非/直到一些“虚拟”朋友进入系统,否则这个测试怎么能成功?
更重要的是,测试会使用什么“虚拟”标准?
我应该硬编码朋友的名字,假设它已经存在于数据库中了吗?
但是如果我将代码移到具有新数据库的新环境中该怎么办?
或者,我应该编写代码来在执行每个测试之前手动将虚拟数据插入系统吗?
但是这将在测试框架内修改应用程序的内部状态,这似乎是一种糟糕的方法,因为我们应该将程序视为黑盒子,并且只通过界面处理它。
或者,我是否会创建其他方案/测试,其中使用程序的界面创建数据?
例如,'功能:将新朋友添加到我的列表'。然后我可以运行该测试,添加一个名为“Lucy”的用户,然后运行“搜索朋友”测试以搜索“Lucy”,现在将存在于数据库中。
但是,那么我将在我的场景之间引入依赖关系,这与测试应该可以独立运行的常见建议相矛盾。
哪一个最好的策略?或者有更好的方法吗?
答案 0 :(得分:5)
您将在方案中使用Given子句使系统进入测试的适当状态。实际的实现将隐藏在步骤定义中。
如果数据将在您的方案中共享,那么您可以在后台执行:
Background:
Given I have the following friends:
| andy smith |
| andy jones |
| andrew brown |
要添加这些朋友,您可以直接将记录插入数据库:
def add_friend(name)
Friend.create!(:name => name)
end
或自动化UI,例如:
def add_friend(name)
visit '/friends/new'
fill_in 'Name', :with => name
click_button 'Add'
end
对于场景本身,您需要考虑验证行为的关键示例,例如:
Scenario: Searching for a existing person by first name
When I search for 'andy'
Then I should see the friends:
| andy smith |
| andy jones |
But I should not see "andrew brown"
Scenario: Searching for a non-existing person by first name
When I search for 'peter'
Then I should not see any friends
您是正确的,测试应该是独立的,因此您不应该依赖其他方案来使数据库处于特定状态。在每次测试后,您可能需要一些机制来清理。例如,如果您正在使用Cucumber和Rails,那么'database-cleaner'宝石。
答案 1 :(得分:2)
您指的是BDD和集成测试风格。如果你使用一个像样的ORM(NHibernate?),你可以在每个测试运行之前创建一个内存数据库,并在测试成功后清理它,因为db在内存中,所以与运行它相比,它不会花费太多时间一个真正的数据库。
您可以使用前/后测试挂钩来填充场景所需的数据,然后进行清理,以便您的测试可以在不相互依赖的情况下运行。