我是TDD和ATDD的新手,我正在寻求理解用户故事与其验收标准之间的联系。对于上下文,我正在使用MVC前端在C#中构建一个3层应用程序。
比如说,我有以下用户故事:
为了确保正确输入容量数据 作为人员更新此数据 当输入的数据不符合我们的业务规则时,我想要反馈。
我有理由将其分解并定义“容量数据”是什么,以及管理这一点的业务规则。
例如,它可能具有“Number of Machines”属性,必须大于零。
我想避免做的是测试框架 - 如果我正确地遵循,我想要做的是测试这个业务逻辑是否正确实现,即:
我相信我可以通过验证控制器中的无效模型状态重定向到同一页面来测试规则#2,并且有很多例子。
但是,不执行此操作需要在viewmodel上放置装饰 - 并且这最终会从用户的角度实现业务规则? (从而满足#1?)
假设我有以下类型的声明/单元测试:
[Test]
public void GivenCapacityModelWhenNumMachinesZeroOrLessThenModelShouldBeInvalid()
{
// Given
IValidatorThing validator = new ValidatorThing(); //What enforces the rule? Should this be a controller service? Or a decorator such as [Range(0.000001,1000000)]? Doesn't each require different testing methods?
var invalidModel = new CapacityModel(); // Or the viewmodel?
double zeroValue = 0.000001;
invalidModel.NumMachines = zeroValue;
// When
var modelIsValid = ValidatorThing.validateModel(invalidModel);
// Then
Assert.IsFalse(modelIsValid);
}
当然,以上不会编译。我暂时遗漏了任何特定的模拟或固定框架,以保持简单。所以,为了使这个测试至少编译(但仍然失败),我做了一些决定:
要考虑的一些事项: 我将要知道的一件事是数据库表将具有描述这些规则的约束 - 因此看起来这个规则的目的实际上是将这些规则传达给使用该应用程序的任何人。在这种情况下,我是否可以安全地假设它会违反DRY以使规则出现在三个位置:viewmodel,data entity和database tables。
我们在数据库中有这些规则的原因是因为我们想要确保DBA是否需要弄乱规则不会意外违反的记录。但是,据我所知,没有很好的方法可以将这些CONSTRAINT规则转换为应用程序的DAL ...所以我想它们需要在应用程序中至少再重复一次,以便将它们传达给用户。
那么,如果我要编写一个单元测试来完成业务规则,那么我不会只是为了确保规则镜像数据库而写吗?另外,还要编写一个单元测试,以确保向用户显示正确的消息?
您可以提供任何指导都很精彩。我想我觉得我做出的决定是合理的,或者至少知道更好地解决问题的替代方法。
谢谢,
劳伦斯
编辑:
所以,最终我试图以集中的方式驱动应用程序中的验证,以便我可以分离关注点 - 即控制器只关心路由,视图模型只关心显示数据,验证器只关心验证等...而不是在视图模型中进行验证。
我找到了一个非常有帮助的article,帮助我了解如何使用现有的MVC基础设施。希望这将有助于其他人研究这些类型的场景。
答案 0 :(得分:2)
我怀疑你可能会模糊单元测试和验收测试之间的界限。
验收测试是非常注重业务用户的。它将应用程序视为黑盒子,但检查以确认应用程序的接口是否以用户期望的方式运行。
在你的例子中,我会看到验收测试如下:
对于简单的业务规则(机器数量必须大于零),请确保在违反业务规则时向用户提供正确的反馈。
我会在此阶段与产品负责人聊聊,以了解他们认为“正确的反馈”以及他们希望如何显示它们。
重要的是,您没有测试业务规则的评估方式或内部机制处理错误的方式。您完全专注于最终用户互动。
当然,您还需要实施单元测试,以确保您的技术解决方案是可靠的,这是您了解业务逻辑实施位置的详细信息。
如何处理业务逻辑是一项非常重要的设计决策。就个人而言,如果我在数据库中拥有业务逻辑,我还会有一个包含规则描述的表,这些规则描述将在违反规则时用作查找。应用程序的其他层对业务逻辑一无所知,但会知道如何传递错误消息。