38

简而言之一个问题:phpunit 在运行测试时可以使用多个数据提供者吗?

例如,我有一个名为 getById 的方法,我需要为它运行成功和不成功的测试用例。

成功的测试用例意味着它可以返回相应的记录。对于不成功的,输入可以分为两类:无效和失败。

invalid表示输入不合法,failed表示输入可能有效,但没有对应的ID对应的记录。

所以代码是这样的:

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

但事实证明,只使用了第一个数据提供者,而忽略了第二个。虽然我不确定这种情况是否常见,但这是问题所在。我们可以使用多个数据提供者吗?如果我们可以,怎么做?

PS:在这里没有找到太多帮助

4

5 回答 5

31

只是对问题的更新,拉取请求被接受,现在代码:

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

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

于 2016-10-09T14:21:16.310 回答
15

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

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

public function allIds()
{
    return array_merge(provideInvalidId(),provideFailedId());
}
于 2013-08-27T17:01:01.180 回答
3

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

public static function DataProvider()
{
    return array(
        'Invalid Id'      => array(123),
        'Failed Id'       => array(321),
        'Id Not Provided' => array(NULL),
);
}
于 2013-02-28T02:23:01.003 回答
2

您还可以使用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']]
    );
}
于 2019-06-07T13:03:23.697 回答
0

好吧,你可以从另一边考虑它;)你确切地知道你的预期是什么,例如 getById(1) 预期的结果是 $result_expected,而不是 $result_null 所以,你可以像这样制作一个数据提供者

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

然后,你的测试方法是这样的:

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

所以,测试结果是:

.F
于 2016-07-01T01:46:26.033 回答