用户故事源代码布局与 MSpec
一个示例,展示了使用 MSpec 反映用户故事的源代码结构。
引言
通过这篇文章,我将演示一种与许多测试框架兼容的行为驱动开发 (BDD) 源代码结构。
这种风格的一个优势在于它与源代码查看工具(如解决方案资源管理器和 ReSharper (R#))的集成方式。另一个优势是,即使对于不太懂技术的人来说,测试也易于阅读和理解。
对于我的示例,我将使用 Machine Specifications (MSpec),因为我更喜欢该框架的语法。
背景
本文面向对 BDD 有一定了解的人。维基百科关于该主题的文章在这里,BDD 维基在这里。 另外一个链接,一些读者可能会觉得有用,是我包含的关于MSpec的链接。 可以找到将 R# 和 MSpec 结合在一起的教程在这里。
Using the Code
代码分为两个项目:Banking(主项目)和 Banking.Behavior(测试项目)。
我在这里展示的是镜像用户故事的源代码:作为一个\[角色] 我想要\[功能] 以便\[收益]
Banking.Behavior\As an\account holder\I want\to transfer
money from my savings account\so that\I can get cash easily from an ATM
通常,一个用户故事包含许多场景。 因此,源代码结构也反映了这一点:作为一个\[角色] 我想要\[功能] 当\[场景]
Banking.Behavior\As an\account holder\I want\to transfer money
from my savings account\When\I_transfer_an_amount_less_than_my_savings_account_balance.cs
每个场景都有一个或多个断言,位于相关的场景文件中
using Banking;
using Machine.Specifications;
using NUnit.Framework;
namespace When
{
public class I_transfer_an_amount_less_than_my_savings_account_balance
{
static Account _savings;
static Account _checking;
Because of = () =>
{
_savings = new Account(100);
_checking = new Account(10);
new Bank().Transfer(_savings, _checking, 20);
};
It should_subtract_the_amount_from_my_savings_account_balance = () =>
Assert.That(_savings.Balance, Is.EqualTo(80));
It should_add_the_amount_to_my_checking_account_balance = () =>
Assert.That(_checking.Balance, Is.EqualTo(30));
}
}
这里的场景是 I_transfer_an_amount_less_than_my_savings_account_balance
,断言是 should_subtract_the_amount_from_my_savings_account_balance
和 should_add_the_amount_to_my_checking_account_balance
。 请注意,我将此类放在了 When
命名空间中。 这在从测试运行器查看源代码时提供了清晰度。
我使用 ReSharper (R#) 作为我的测试运行器。 这是来自 R# 的“单元测试资源管理器”的视图,使用了“项目和命名空间”选项
这是来自 R# 的单元测试会话的视图,使用了“项目结构”选项
这是来自解决方案资源管理器的视图
注意:要运行示例项目,您需要自行包含 Machine.Specifications、Machine.Specifications.NUnit 和 NUnit.Framework DLL。 我没有包含这些 DLL,因为 Coderoject.com 和这些产品之间可能存在潜在的许可冲突。 MSpec 源代码可以在这里找到(您需要自行构建它),NUnit 下载可以在这里找到。
关注点
这种源代码结构可以移植到许多其他测试框架,例如纯 NUnit。 在纯 NUnit 的情况下,我们将把 It
委托移植到带有 [Test]
注释的方法,将 Because
委托移植到带有 [SetUp]
注释的方法,并将 [TestFixture]
属性添加到每个测试类。