在 Drupal SimpleTest 中模仿数据提供者功能
尽管DrupalSimpleTest是一个非常有用的模块,但它目前不支持数据提供程序,这很遗憾,因为我在其他测试框架中使用了很多该功能。数据提供程序是一种机制,它允许您使用不同的参数多次调用单个测试用例,以便确保每次都能获得正确的输出。这很有用,因为测试单个函数一次就可以了,但是用各种不同的值测试它可能意味着有多个测试用例。
要在DrupalSimpleTest中模拟此功能,您可以创建一个返回数组的数据提供程序方法,然后用于测试特定函数。
例如,假设我在Drupal模块中有以下(微不足道的)函数。
function my_module_add_numbers($number1, $number2) { return $number1 + $number2; }
我通常会在DrupalSimpleTest中通过在测试类中创建一个方法并将一些参数提供给函数来测试它。这是删除了其余测试类的测试方法。
public function testAdding1And1Equals3() { $this->assertEqual(my_module_add_numbers(1, 2), 3); }
显然这个函数只是将两个数字相加,但是如果参数不同会发生什么?如果我们传递两个字符串而不是整数会怎样?如果发生这种情况,该函数显然不会很好地降级,因此我们需要向该函数添加一些错误检查,以确保它可以处理不同形式的输入。为了正确地对我们的工作进行单元测试,我们需要使用数据提供程序将多个参数传递给这个函数。这是我们将用于此单元测试的数据提供程序。每个数组中的前两个值是我们将使用的参数,第三个是预期的输出。
public function addingNumbersDataProvider() { return array( array(1, 2, 3), array('1', '2', 3), array('monkey', 'wrench', 0) ); }
我们对单元测试所做的唯一更改是遍历来自数据提供者的数据,将参数提供给函数并测试返回的正确输出。
public function testAddingNumbers() { foreach ($this->addingNumbersDataProvider() as $data) { $this->assertEqual(my_module_add_numbers($data[0], $data[1]), $data[2]); } }
有了单元测试,我们可以看到我们的测试现在失败了。因此,我们可以通过对原始函数进行一些简单的更改来确保正确的输出。
function my_module_add_numbers($number1, $number2) { if (!is_numeric($number1) && !is_numeric($number2)) { return 0; } return (int)$number1 + (int)$number2; }
使用此方法意味着您现在可以多次调用单个测试用例,而不必拥有多个测试用例。我们还可以确保我们的函数无论我们抛出什么样的数据都能正常工作。这对于转义字符串之类的事情特别有用,因为您需要确保安全地处理任何安全威胁。如果出现任何新的安全威胁,您可以随时将其添加到您的数据提供程序并确保您的功能能够处理它。
这种方法的一个小缺点是,如果您的数据提供程序数组中有很多元素,您几乎肯定会迷路。解决此问题的一种方法是通过list()函数提取数组中的变量。在以下示例中,我们采用由4个元素组成的数据数组,并从这些元素创建变量,以便我们可以更好地了解测试中发生的情况。
public function calculationDataProvider() { return array( array(2, 2, 2, 4), array(1, 1, 1, 2) ); } public function testCalculation() { foreach ($this->calculationDataProvider() as $data) { list($height, $length, $width, $total_devices_count) = $data; //运行计算 $result = theCalculation($height, $length, $width); //断言 $this->assertEqual($result['total_devices_count'], $total_devices_count); } }