我对单元测试和测试一般都很陌生。我正在使用phpUnit开发,但由于我的问题更一般/一个设计问题,实际环境不应该太重要。
我认为,将您的测试用例尽可能具体地编写是一种很好的做法。例如(越晚越好):
assertNotEmpty($myObject); // myObject is not Null
assertInternalType('array', $myObject); // myObject is an array
assertGreaterThan(0, count($myObject)); // myObject actually has entries
如果这是正确的,这是我的问题:
在测试用例中编写一些流控制是否是公认的做法,如果测试的对象的状态取决于外部源(即DB) - 或者甚至是一般的?
像:
if (myObject !== null) {
if (count(myObject) > 0) {
// assert some Business Logic
}
else {
// assert some different Business Logic
}
}
测试用例中的这种流量控制是否可以接受或者是“代码异味”并且应该被规避?如果没问题,是否有任何提示或做法,这里应该记住哪些?
答案 0 :(得分:3)
Paul的答案解决了测试方法范围和断言,但是你的问题代码暗示的一件事是如果返回的对象具有值X则测试A但是如果它具有值Y则测试B.换句话说,您的测试将期望多个根据实际得到的东西来衡量和测试不同的东西。
一般而言,如果您的每个测试都有一个已知的正确值,那么您将是一个更快乐的测试人员。您可以通过使用固定的已知测试数据来实现此目的,通常通过在测试本身内部进行设置。以下是三条常见路径:
setUp()
期间,测试将丢弃并使用其特定数据集重新创建数据库。它最初可以使编写测试更容易,但是随着对象的发展,您仍然必须更新数据集。这也可以使测试运行时间更长。答案 1 :(得分:2)
在你的测试用例中有一些控制流是可以的,但总的来说,要理解你的单元测试如果不相交就会最好,也就是说,他们每个测试都会测试不同的东西。这很好的原因是,当您的测试用例失败时,您可以准确地看到失败的测试用例失败,而不是需要深入更大的测试用例以查看出现了什么问题。通常的度量标准是每单元测试用例的单个断言。也就是说,每条规则都有例外,这当然是其中之一;在测试用例中有一些断言没有什么不妥,特别是当测试用例场景的设置/拆除特别困难时。但是,您要避免的真实代码气味是您有一个“测试”测试所有代码路径的情况。