我一直在学习BDD,在尝试了一些框架之后决定在我的最新项目中使用MSpec。
在查看一些示例后,我不确定如何识别场景和上下文。
采取以下故事(摘自Rob Connery's Kona example):
Removing a shopping cart item
* All items of same SKU are removed. TotalItems decremented by Quantity
* When quantity is 0 nothing happens
* When quantity is negative, items are removed, TotalItems stays at 0 (never negative)
以下是相关规范:
[Subject("Cart with items in it")]
public class when_removing_item : with_cart_with_1_item_of_sku1 {
It should_remove_all_items_with_same_sku;
It should_not_remove_anything_when_sku_not_in_cart;
It should_not_remove_more_items_than_are_in_cart_resulting_in_negative_totalitems;
}
现在,如果我的理解是正确的:
但是,看看其他例子,似乎应该这样声明:
并且测试应该是:
[Subject("Removing an item from cart")]
public class when_removing_an_item_from_cart_with_items : with_cart_with_1_item_of_sku1 {
It should_remove_all_items_with_same_sku;
// etc.
}
我的理解是正确的,还是没有正确和错误的方法?我的假设是主题/场景与我们正在测试的整体行为有关(即从购物车中删除一个项目),每个规范类在不同的上下文中测试该行为。
答案 0 :(得分:2)
when
类)时,请确保它包含与场景关联的所有内容。大多数情况下,只有一个“动作”(在您的示例中,删除项目),其中的规范表示系统应该在特定上下文中执行该操作后应处于的状态。当然可以有不同的前提条件(购物车为空,带有一件商品的购物车等),这些都构成了不同的背景。
只是为了澄清,删除项目不是观察,而是行动。
因此,我认为您可以为概述的功能编写以下规范:
[Subject("Removing item from shopping cart")]
public class when_removing_item_from_empty_cart {
It should_be_empty;
}
[Subject("Removing item from shopping cart")]
public class when_removing_item_from_cart_with_one_item_of_another_SKU {
It should_still_contain_the_item;
}
[Subject("Removing item from shopping cart")]
public class when_removing_item_from_cart_with_two_items {
It should_be_empty;
}
// probably more ;-)
使用SubjectAttribute
表示功能/方案。您还可以使用TagsAttribute
添加更多元数据(并可能过滤测试运行)。
我会故意选择不使用基类。根据我的经验,有更好的方法来进行复杂的设置(Fluent API,Machine.Fakes行为配置)。 DRY在这里并不真正适用:当规范失败时,您希望将所有属于规范的内容放在您面前,而不是导航类层次结构以查找可能会在其他位置停留的Establish
。 / p>
此外,您可能会发现this sample app有趣,使用MSpec开发和测试。