PHPUnit可以使用多个数据提供程序吗?

43
简短的问题:phpunit在运行测试时能否使用多个数据提供程序?
例如,我有一个名为getById的方法,并且我需要为其运行成功和不成功的测试用例。
成功的测试用例意味着它可以返回相应的记录。对于不成功的测试用例,输入可以分为两类:无效和失败。
无效意味着输入不合法,而失败则意味着输入可能有效,但没有与该ID相对应的记录。
所以代码像这样:
/** 
 * @dataProvider provideInvalidId
 * @dataProvider provideFailedId
 */
public function testGetByIdUnsuccess($id)
{   
    $this->assertNull($this->model->getById($id));
}   

但事实证明,只有第一个数据提供程序被使用了,忽略了第二个。虽然我不确定这种情况是否常见,但问题在于:我们可以使用多个数据提供程序吗?如果可以,应该如何操作?
PS: 在此处没有找到太多帮助。

我处于类似的情况,拥有单独的数据提供程序将使代码更易读(通过提供给它们的数据来记录代码和测试用例)。我想知道什么是最佳实践? - Pitt
5个回答

35

仅仅是关于这个问题的一次更新,一个拉取请求被接受并且现在的代码为:

/** 
 * @dataProvider provideInvalidId
 * @dataProvider provideFailedId
 */
public function testGetByIdUnsuccess($id)
{   
    $this->assertNull($this->model->getById($id));
}

将在PHPUnit 5.7上工作,您将能够添加任意数量的数据提供器。


2
一个需要注意的地方是:我的测试用例名称非常通用。如果您给出名称,必须确保它们在您的提供者中是唯一的,否则只有具有该名称的最后一个测试用例将被执行。 - Adam P.

15
您可以使用以下显示的帮助函数。唯一的问题是,如果所有“子数据提供者”提供的测试用例总数很大,那么找出哪个测试用例导致问题可能会很繁琐。

您可以使用以下显示的帮助函数。唯一的问题是,如果所有“子数据提供者”提供的测试用例总数很大,那么找出哪个测试用例导致问题可能会很繁琐。

/** 
 * @dataProvider allIds
 */
public function testGetByIdUnsuccess($id)
{   
    $this->assertNull($this->model->getById($id));
}  

public function allIds()
{
    return array_merge(provideInvalidId(),provideFailedId());
}

6
您还可以使用CrossDataProviders,它允许您将多个数据提供程序结合在一起使用。
<?php

/** 
 * @dataProvider provideInvalidIdAndValues
 */
public function testGetByIdUnsuccess($id, $value)
{   
    $this->assertNull($this->model->getById($id));
}   

function provideInvalidIdAndValues() {
    return DataProviders::cross(
        [[1], [2], [3]],
        [['Rob'], ['John'], ['Dennis']]
    );
}

4

您可以向您的dataProvider数组添加注释,以提供相同的功能,而无需多个dataProvider。

public static function DataProvider()
{
    return array(
        'Invalid Id'      => array(123),
        'Failed Id'       => array(321),
        'Id Not Provided' => array(NULL),
);
}

0

嗯,你可以从另一个角度考虑一下 ;) 你清楚地知道你的期望结果,例如getById(1)的期望结果是$result_expected,而不是$result_null 因此,你可以像这样制作一个数据提供程序

$dataProvider = array(1, 'unexpected');

那么,你的测试方法应该像这样:

public function testGetById($id) {
    $this->assertEquals($result_expected, $obj::getById($id));
}

所以,测试结果是:

.F

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接