你能在 phpunit 中测试参数的边界吗?
Can you test the bounds of a parameter in phpunit?
假设我有以下方法:
public function setDeliveryDay(int $deliveryDay)
{
$this->deliveryDay = $deliveryDay;
}
我想写一个测试来确保这个 setter 只允许 ISO-8601 值(所以 1
到 7
),我该如何实现?
似乎唯一真正的方法是分别测试低于或高于 1 和 7 的每个可能的整数?
当然这是不明智的,尤其是当您希望它抛出异常时。
起初我测试了下界:
$this->expectException(\InvalidArgumentException::class);
$obj->setDeliveryDay(0);
在另一个测试中上限(因为expectException
每次测试只支持一个异常):
$this->expectException(\InvalidArgumentException::class);
$obj->setDeliveryDay(8);
当然这不会阻止有人将其设置为 -1 或 -842 或 9 或 3835 等等。
是否有我在这里缺少的断言类型或公认的测试边界的最佳实践?
除非你转向 "quickcheck" 之类的测试,否则你无能为力。 QuickCheck 是一种最初来自 haskell 世界的测试方法,但似乎也有 php library。它们都是关于 "property based testing":
Generative testing, also called property-based testing, is about describing the behaviour of your system in terms of properties that should hold true for all possible input.
换句话说:这种框架的思想是确保有效的输入通过; 任何错误输入失败。
如果你不想走那条路......我会这样做:
- 编写一个测试用例来测试循环中的几个有效值
- 为边界写另外两个测试用例
- 编写另一个循环并尝试一堆无效值的测试用例(例如基于随机数)
最后一句话:当你选择 "random" 值时,确保在某处使用 种子 并记录它 - 以确保你可以稍后重现失败的测试上。
我要做的是为工作日创建一个简单的 ValueObject,它不公开数字并使用静态工厂方法来设置值。这样你就可以相当安全地通过该对象的类型提示传递正确的值。
在通过 int
测试您的代码时,我不会担心捕获所有不可能的值。你只测试预期的误用,所以我只会测试 0
但如果你想表示上限,你也可以测试 8
。如果不容易辨别哪些数字可能是有效的,哪些不是,您仍然应该将测试用例限制为最合理的测试用例,然后只测试更多的用例,例如对于3835,当你因为这个数字遇到bug时,为了保险起见,它不会再出现了。
如果您想捕获这些情况,您可能需要研究突变测试。或者,您可以传入随机测试值,例如rand(8, PHP_INT_MAX)
,但我不推荐这样做,因为它会导致不稳定的测试,并且更难跟踪使用了哪些值以及原因。
假设我有以下方法:
public function setDeliveryDay(int $deliveryDay)
{
$this->deliveryDay = $deliveryDay;
}
我想写一个测试来确保这个 setter 只允许 ISO-8601 值(所以 1
到 7
),我该如何实现?
似乎唯一真正的方法是分别测试低于或高于 1 和 7 的每个可能的整数?
当然这是不明智的,尤其是当您希望它抛出异常时。
起初我测试了下界:
$this->expectException(\InvalidArgumentException::class);
$obj->setDeliveryDay(0);
在另一个测试中上限(因为expectException
每次测试只支持一个异常):
$this->expectException(\InvalidArgumentException::class);
$obj->setDeliveryDay(8);
当然这不会阻止有人将其设置为 -1 或 -842 或 9 或 3835 等等。
是否有我在这里缺少的断言类型或公认的测试边界的最佳实践?
除非你转向 "quickcheck" 之类的测试,否则你无能为力。 QuickCheck 是一种最初来自 haskell 世界的测试方法,但似乎也有 php library。它们都是关于 "property based testing":
Generative testing, also called property-based testing, is about describing the behaviour of your system in terms of properties that should hold true for all possible input.
换句话说:这种框架的思想是确保有效的输入通过; 任何错误输入失败。
如果你不想走那条路......我会这样做:
- 编写一个测试用例来测试循环中的几个有效值
- 为边界写另外两个测试用例
- 编写另一个循环并尝试一堆无效值的测试用例(例如基于随机数)
最后一句话:当你选择 "random" 值时,确保在某处使用 种子 并记录它 - 以确保你可以稍后重现失败的测试上。
我要做的是为工作日创建一个简单的 ValueObject,它不公开数字并使用静态工厂方法来设置值。这样你就可以相当安全地通过该对象的类型提示传递正确的值。
在通过 int
测试您的代码时,我不会担心捕获所有不可能的值。你只测试预期的误用,所以我只会测试 0
但如果你想表示上限,你也可以测试 8
。如果不容易辨别哪些数字可能是有效的,哪些不是,您仍然应该将测试用例限制为最合理的测试用例,然后只测试更多的用例,例如对于3835,当你因为这个数字遇到bug时,为了保险起见,它不会再出现了。
如果您想捕获这些情况,您可能需要研究突变测试。或者,您可以传入随机测试值,例如rand(8, PHP_INT_MAX)
,但我不推荐这样做,因为它会导致不稳定的测试,并且更难跟踪使用了哪些值以及原因。