我正在为我的 webapp 编写单元测试。我的许多测试用例共享相同的样板。例如,从购物车中删除商品和更新购物车中商品数量的测试都从导航到产品页面、搜索产品并将其添加到购物车开始。
这种重复的代码是否应该以某种方式从单元测试中剔除?我应该写一个函数add_item_to_cart
吗?但是,我有另一个测试test_add_to_cart
,它基本上只包含添加到购物车的重复样板。
由于每个测试都需要独立,单元测试本质上不是 DRY 吗?
我正在为我的 webapp 编写单元测试。我的许多测试用例共享相同的样板。例如,从购物车中删除商品和更新购物车中商品数量的测试都从导航到产品页面、搜索产品并将其添加到购物车开始。
这种重复的代码是否应该以某种方式从单元测试中剔除?我应该写一个函数add_item_to_cart
吗?但是,我有另一个测试test_add_to_cart
,它基本上只包含添加到购物车的重复样板。
由于每个测试都需要独立,单元测试本质上不是 DRY 吗?
单元测试应该只测试一件事。以“导航到产品页面、搜索产品并将其添加到购物车”开始的测试——这是三个不同的东西——听起来根本不像是单元测试,而是集成测试。我怀疑你实际上有两个不同的测试要在这里构建。
你的集成测试,在Cucumber或类似的东西中,应该包括一系列步骤:
When I navigate to the products page
And I search for a product
And I add it to the cart
您可以定义每个步骤一次并多次使用它,使其变得既美观又干燥。
另一方面,您的单元测试应该删除所有必要的设置,只测试您感兴趣的一件事:
before
stub(cart)
stub(product)
click on "X" for item in cart
it should...
expect(cart not to contain item)
expect(product count to be updated)
如果这变得非常复杂并且涉及大量存根,则表明您的代码不是模块化的;解决方案是 TDD 并首先编写测试,而不是之后添加它们。
至少将通用代码重构为一个函数,并在启动时简单地调用该函数。您想测试特定于您的测试的代码,而不是重复的设置代码(应该在其他地方测试)
您应该将相同的原则应用于任何其他代码的测试。
考虑示例,然后您更改会破坏测试的内容。您希望在一个地方或每个测试中更新测试代码吗?
我认为答案是显而易见的。