如何测试业务规则?

问题描述:

我需要一个单元测试来确保我正确地累计休假时间。但假期时间根据商业规则积累,如果规则改变,则单元测试会中断。如何测试业务规则?

这是可以接受的吗?我应该通过一种方法公开规则,然后从我的代码和我的测试中调用该方法,以确保单元测试不那么脆弱?

我的问题是:单元测试可能会改变的业务规则的正确方法是什么?

+3

当您更改规则时,您将更改预期结果。这意味着过去通过的一些正面的单元测试失败了,并且一些曾经通过的负面测试(通过检测错误)现在可能会失败(尽管这通常不太常见)。单元测试只能验证当前的规则 - 在规则更改之前,它们无法验证规则的所有更改。当规则发生变化时,单元测试也可能会发生。 – 2009-06-20 22:03:18

您的测试应确保代码正确遵守业务规则。因此,我不会编写围绕业务规则的测试或依赖业务规则代码本身。相反,当业务规则发生变化时,我会首先更改测试以反映新的业务规则,然后当我的代码不再通过测试时,请去修复代码,使其通过测试。

你不想发生的事情就是编写你的测试,这样当你改变如何应用相同的业务规则时,测试就会中断。说起来容易做起来难,但基本上你想测试的是实现规则所需的最低要求,而不是过分狭窄地规定代码的实现。但是,如果规则的结果不同,那么您应该先更改测试,然后再更改代码以匹配它。

您也不希望测试与特定数据耦合。假设在进行税务计算时,不应将您的测试写为假设受测班级使用5%作为税收。相反,您应该编写测试,以便提供税率,然后检查计算是否正确完成。据推测,你将有一系列的值来测试,以确保超出范围的值也被捕获。这样做的一个结果是,您将拥有更好的设计,因为这将帮助您避免硬编码值,并使生产代码更灵活地适应数据更改。

我有一个类似的设置 - 但是我的业务规则已编译,但具有可配置的选项(您可能会有所不同)。当业务规则改变其运作的核心方式时,我的单元测试就会中断。这实际上是预期的 - 而且很好!这意味着我可以隔离整个系统中的任何意外涟漪,并更新测试以匹配更改。

如果您的规则是外部的(某种脚本语言或数据库存储过程),那么您将需要将它们包装在集成测试中,并将自动执行的集成测试连接起来。虽然不再是单元测试,但集成测试也相当重要,并将以与单元测试相同的方式帮助您,以防止由于业务规则更改而导致的意外涟漪。

如果规则发生变化,测试就会失败 - 这是可以预料的。

如果您在测试本身中使用数据夹具而不是硬编码值,那么您可以更容易地在将来维护测试。例如,如果你的方法应该返回foo,你可以在灯具中找到它。当您更改业务逻辑时,只需更改灯具,而不必通过单元测试。

当然,这很大程度上取决于您正在测试的逻辑类型,可能并不总是适用。

这听起来像你有业务规则,然后你有这些业务规则的客户端。如果这两者可以独立变化,那么相应地设计您的API将是明智的。

如上所述,您的问题听起来像是可以通过适当使用策略模式来解决。该策略代表您的业务规则,因此您可以在纯粹的环境中对其进行单元测试,而无需担心客户端。

当业务规则发生变化时,将原有策略保持原样(以备日后再次使用时),并编写(和单元测试)代表新业务的全新策略规则。

当您完全使用新策略时,您可以在客户端中替换策略。

当单元测试客户端时,您应该对测试双重策略(如模拟或存根)执行此操作,以验证客户端与策略正确交互而不依赖任何特定的策略实施。

通过这种方式,您可以清晰地分离问题并保持单元测试的可维护性。你也遵守开放/封闭原则。

我认为这是不正确的问题 业务规则和单元测试处于不同的抽象级别。 业务规则处于最高抽象层次(业务建模),但是单元测试用于测试处于最低抽象级别的代码单元,因此您不能使用单元测试来验证或验证业务规则 此外,分析和设计后的业务规则可能会影响多个代码单元,因此不能使用单元测试来验证或验证业务规则。 我认为您可以使用测试用例或BDD方案来验证和验证业务规则。

+0

这是完全错误的,通过嘲笑应用业务规则的对象下的图层,您可以完全将业务层隔离为单个单元,因此单元测试它。 – Walfrat 2016-06-28 08:22:08