【问题标题】:Using YAML Files as data provider in PHPUnit (CIUnit)在 PHPUnit (CIUnit) 中使用 YAML 文件作为数据提供者
【发布时间】:2012-05-24 16:54:59
【问题描述】:

我正在使用 PHP CodeIgniter 框架编写应用程序。我正在尝试通过扩展 PHPUnit 使用 CI_Unit 测试应用程序。为了测试模型,我尝试加载 PHPUnit 文档中定义的 YAML 数据提供程序,但收到错误消息。如果我捏造数据提供者对象,我会得到另一个错误。如果我为它提供一个普通的 PHP 数组,它会按预期运行。

我做错了什么?这样做的正确方法是什么?以下是我的结果:

如果我返回下面 Yaml 文件的对象PHPUnit_Extensions_Database_DataSet_YamlDataSet,我会得到:

数据集“客户”无效。

如果我围绕PHPUnit_Extensions_Database_DataSet_YamlDataSet 返回的对象循环并返回:我收到此错误:

PHPUnit_Framework_Exception:“models.php”和“models.php”都无法打开。在 /Users/eric/pear/share/pear/PHPUnit/Util/Skeleton/Test.php 第 100 行

如果我提供一个普通的 PHP 数组,测试运行得很好。我用来运行测试的命令是:

phpunit 模型

以下是我的 YAML 文件的示例。

Clients:
    1:
        client_id: 1
        client_information: "info number 1"
        client_key: 48fb10b15f3d44a09dc82d
    2:
        client_id: 2
        client_information: "info number 2"
        client_key: 48fb10b15f3d44addd

我正在使用 PHP 5.3、PHPUnit 3.6.10、DBUnit 1.1.2、CodeIgniter 2.1.0 和与 CI 2.1.0 关联的 CI_unit。

编辑: 附上我的models/Test.php文件:

/**
 * test_add_client
 * @dataProvider add_client_provider
 */
public function test_add_client($client_id,$company_id,$software_id,$client_information,$client_key)
{
    $data = array('software_id' => $software_id,
                  'client_information' => $client_information,
                  'client_key'         => $client_key);
    try {
        $id = $this->_m->add_client($company_id,$data);
        $this->assertEquals(true, is_int($id));
    } catch (Exception $e){
        $this->assertEquals(true,false);
    }
}

public function add_client_provider()
{
    $result = new PHPUnit_Extensions_Database_DataSet_YamlDataSet(
        dirname(__FILE__)."/../fixtures/Clients.yml");

    // Case #1 returns this $result
    //return $result;

    foreach($result as $key => $value){
        if($key == 'Clients'){
            $substructure = $value;
        }
    }

    // Case #2 return the inner structure that is the table
    return $substructure;

    // Case #3 return an array of arrays
    $data = array(
                array(1,1,1,'test','text 2'),
                array(1,2,1,'test 3', 'test 3'));
    return $data;
}

【问题讨论】:

    标签: php codeigniter phpunit yaml


    【解决方案1】:

    Data Providers 上的 PHPUnit 文档中所述:

    数据提供者方法必须是 public 并且返回一个数组 实现Iterator 接口并产生的数组或对象 每个迭代步骤的数组。对于作为一部分的每个数组 收集测试方法将被调用的内容 数组作为它的参数。

    根据您的Test.php 源代码,您似乎想要这样的东西:

        /**
         * test_add_client
         * @dataProvider add_client_provider
         */
        public function test_add_client($data)
        {
            $company_id = 0;
            $id = $this->_m->add_client($company_id, $data);
            $this->assertEquals(true, is_int($id));
        }
    
        public function add_client_provider()
        {
            $result = new PHPUnit_Extensions_Database_DataSet_YamlDataSet(
                dirname(__FILE__)."/../fixtures/Clients.yml");          
    
            // Return the Clients data
            $clients = array();
            $tbl = $result->getTable('Clients');
            for ($i = 0; $i < $tbl->getRowCount(); $i++) {
                $clients[] = $tbl->getRow($i);
            }
            return $clients;
        }
    

    似乎 PHPUnit 应该提供一个函数来将数据集表直接转换为数组数组,但快速浏览后我没有看到任何东西。

    phpunit.xml 文件无关紧要,据我所知,可以从您的问题中删除。

    您也不需要 PHPUnit 测试方法中的 try/catch 块 - PHPUnit 会为您解决这个问题。

    请注意,您的 $company_id 未定义,因此我将其设置为 0。您上面的方法参数和 YAML 数据似乎也不完全匹配,但这应该很容易解决。

    通过将数组传递给测试函数,该函数会立即传递给add_client 方法,您的代码也更加干燥。

    【讨论】:

    • 由于PHPUnit_Extensions_Database_DataSet_YamlDataSet应该实现一个Iterator对象,我想知道如何直接传递它,但这符合我的需要。谢谢!
    • 它提供的迭代器对象只允许您迭代数据集中的表。这不会从行中获取您似乎需要的数据。
    【解决方案2】:

    PHPUnit 提供程序自动加载器

    在 PHPUnit 中自动加载 CSV、JSON、PHP、XML 和 YAML 数据提供程序的魔术助手。

    安装

    composer require redaxmedia/phpunit-provider-autoloader
    

    用法

    为您的测试套件创建 TestCaseAbstract:

    <?php
    namespace ExampleProject\Tests;
    
    use PHPUnitProviderAutoloader;
    
    /**
     * TestCaseAbstract
     *
     * @since 2.0.0
     *
     * @package ExampleProject
     * @category Tests
     */
    
    abstract class TestCaseAbstract extends PHPUnitProviderAutoloader\TestCaseAbstract
    {
        /**
         * directory of the provider
         *
         * @var string
         */
    
        protected $_providerDirectory = 'tests' . DIRECTORY_SEPARATOR . 'provider';
    
        /**
         * namespace of the testing suite
         *
         * @var string
         */
    
        protected $_testNamespace = __NAMESPACE__;
    }
    

    从 TestCaseAbstract 扩展以自动加载 ExampleTest{_testMethod}.{csv|json|php|xml|yml} 文件:

    <?php
    namespace ExampleProject\Tests;
    
    /**
     * ExampleTest
     *
     * @since 2.0.0
     *
     * @package ExampleProject
     * @category Tests
     */
    
    class ExampleTest extends TestCaseAbstract
    {
        /**
         * testMethod
         *
         * @since 2.0.0
         *
         * @param string $expect
         *
         * @dataProvider providerAutoloader
         */
    
        public function testMethod(string $expect = null)
        {
            $this->assertEquals($expect, 'test');
        }
    }
    

    了解详情

    相关仓库:https://github.com/redaxmedia/phpunit-provider-autoloader

    示例集成:YAML test 自动加载 YAML class providerYAML method provider

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-10-21
      • 2018-01-06
      • 2020-08-26
      • 2013-02-14
      • 2018-02-02
      • 1970-01-01
      • 1970-01-01
      • 2017-10-31
      相关资源
      最近更新 更多