你能测试一下phpunit中参数的界限吗?

时间:2017-06-26 10:10:56

标签: php phpunit tdd

说我有以下方法:

public function setDeliveryDay(int $deliveryDay)
{
    $this->deliveryDay = $deliveryDay;
}

我想编写测试以确保此setter仅允许ISO-8601值(17),我将如何实现此目标?

似乎唯一真正的方法是分别测试低于或高于1和7的每个可能的整数?

当然这不合理,特别是如果你期望它抛出异常。

起初我测试了下限:

$this->expectException(\InvalidArgumentException::class);
$obj->setDeliveryDay(0);

并且在另一个测试中上限(因为expectException每个测试只支持一个例外):

$this->expectException(\InvalidArgumentException::class);
$obj->setDeliveryDay(8);

当然,这不会阻止某人将其设置为-1或-842或9或3835等等。

我在这里缺少一种断言或者测试边界的公认最佳做法吗?

2 个答案:

答案 0 :(得分:2)

我要做的是为工作日创建一个简单的ValueObject,它不公开数字并使用静态工厂方法来设置值。这样,通过类型提示为该对象传递正确的值,您可以相当安全。

在测试代码时,int被传递,我不会担心捕获所有不可能的值。您只测试预期的误用,因此我只测试0,但如果您想表示上限,也可以对8进行测试。如果不容易辨别哪些数字可能有效,哪些不是你仍然应该将测试用例限制在最合理的数字,然后只测试其他情况,例如对于3835,当你因为那个号码而遇到一个bug时,为了安全起见,它不会再出现。

如果您想捕获这些案例,您可能需要研究突变测试。或者,您可以传入随机测试值,例如使用rand(8, PHP_INT_MAX),但我不建议这样做,因为它会导致片状测试,并且更难以跟踪使用的值和原因。

答案 1 :(得分:1)

除非你转向"快速检查"像测试一样,你无法做到这么多。 QuickCheck是一种最初来自haskell世界的测试方法,但似乎还有一个php library。它们都是关于"基于属性的测试":

  

生成测试,也称为基于属性的测试,是根据应该适用于所有可能输入的属性来描述系统的行为。

换句话说:这种框架的想法是确保有效的输入传递;并且任何错误输入都失败了。

如果你不想走这条路......我会这样做:

  • 编写一个测试用例来测试循环中的几个有效值
  • 边界
  • 编写另外两个测试用例
  • 编写另一个循环并尝试一堆无效值的测试用例(例如基于随机数)

最后一句话:当你选择"随机"值,确保在某处使用种子并记录 - 以确保您以后可以重现失败的测试。