phpunit可以使用多个数据提供者吗

Posted

技术标签:

【中文标题】phpunit可以使用多个数据提供者吗【英文标题】:Can phpunit use multiple data provider 【发布时间】:2013-02-14 01:08:57 【问题描述】:

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

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

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

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

所以代码是这样的:

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

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

PS:在here没有找到太多帮助

【问题讨论】:

我处于类似的情况,拥有单独的 dataProviders 会使代码更具可读性(通过提供给它们的数据记录代码和测试用例)。我想知道最佳做法是什么? 【参考方案1】:

只是对问题的更新,pull request 已被接受,现在是代码:

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

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

【讨论】:

一个问题:我有非常通用的测试用例名称。如果您提供名称,则必须确保它们在您的提供程序中是唯一的,否则只会执行具有该名称的最后一个测试用例。【参考方案2】:

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

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

public function allIds()

    return array_merge(provideInvalidId(),provideFailedId());

【讨论】:

【参考方案3】:

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

public static function DataProvider()

    return array(
        'Invalid Id'      => array(123),
        'Failed Id'       => array(321),
        'Id Not Provided' => array(NULL),
);

【讨论】:

【参考方案4】:

您也可以使用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']]
    );

【讨论】:

【参考方案5】:

嗯,你可以从另一面考虑;) 您确切地知道您的预期是什么,例如 getById(1) 预期结果是 $result_expected,而不是 $result_null 所以,你可以做一个这样的数据提供者

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

那么,你的测试方法是这样的:

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

所以,测试结果是:

.F

【讨论】:

以上是关于phpunit可以使用多个数据提供者吗的主要内容,如果未能解决你的问题,请参考以下文章

如何在 phpunit 中引用外部数据提供者?

Laravel5、PHPUnit 和 Date Mutators:不能在数据提供者中使用 mutator

PHPUnit-函数依赖-数据提供-异常-忽略-自动生成

PHPUnit和数据提供者的问题

Composer 安装的 PHPUnit 二进制文件使用系统提供的 ResultPrinter 并失败

我可以单独使用 Flask app.run() 为多个客户端提供服务吗?