假设我想将我的 NUnit 参数化测试方法更改为理论。就理论而言,他们应该定义断言将通过的所有假设/前提条件。根据 NUnit 文档:
[将理论与参数化测试进行比较时] 另一方面,理论做出一般性陈述,即其所有断言对于满足某些假设的所有论点都将通过。
但据我了解,这意味着被称为 PUT 的代码应该基本上转换为假设。完全。
那么有理论有什么意义呢?因为我们的算法会被写两次。首先是可测试的代码,其次是理论假设。因此,如果我们在算法中引入错误,我们的代码和测试都可能有相同的错误。那有什么意义呢?
更好理解的示例
假设我们有一个只支持数字的校验和方法,我们想用理论来测试它。让我们写一个理论:
static Regex rx = new Regex(@"^\d+$", RegexOptions.Compiled);
[Theory]
public void ChecksumTheory(string value)
{
Assume.That(!string.IsNotNullOrWhiteSpace(value));
Assume.That(value.Length > 1); // one single number + checksum = same number twice
Assume.That(rx.IsMatch(value));
var cc = new ChecksumValidator();
bool result = cc.ValidateValue(value);
Assert.IsTrue(result); // not really as algorithm assumptions are missing
}
这是一个非常好的理论,除了如果没有实际实现测试代码算法并将其表达为一组假设,它的断言仍然不会通过,因为没有明确的算法假设,我们无法知道验证的结果是什么。
附加信息
当我们只需要提供输入状态的假设即检查特定值是否正确设置或它们的组合是否相关时,理论似乎相当简单和简洁:
[Theory]
public void Person_ValidateState(Person input)
{
Assume.That(input.Age < 110);
Assume.That(input.Birth < input.Death || input.Death == null);
...
}
问题
- 如果需要为所有断言提供足够的假设以使其通过,为什么还要编写单元测试理论?
- 如果我们不想通过提供所有算法假设来重新发明轮子,我们如何提供正确的假设?
- 如果不是这样,我应该如何重写我的理论以使其成为 NUnit 理论的一个很好的例子?
- 无论如何,测试理论的预期用途(由他们的创造者)是什么?