代码之家  ›  专栏  ›  技术社区  ›  Donnie Ashok

PHPUnit如何每次测试不同的变量?

  •  0
  • Donnie Ashok  · 技术社区  · 6 年前

    id name .

    例如:

    $Product = new Product;
    $Product->id = "ff62";
    $Product->readId();
    echo $Product->name;
    
    // returns a string with at least 5 characters.
    

    我的PHPUnit测试方法如下所示:

    $Product = new Product;
    $Product->id = "ff62"; // needs to be a variable
    $Product->readId();
    $this->assertEquals(gettype($Product->name), 'string');
    

    但是,我的目标是每次检查不同的产品ID,而不是 ff62

    理想情况下,应该能够定义 身份证件 测试过程中的变量。

    测试动态变量的最佳方法是什么?

    3 回复  |  直到 6 年前
        1
  •  1
  •   DrDamnit    6 年前

    Faker

    1测试一组不同的变量。

    但是您在设计这个测试时遇到了几个问题:

    1. 您正在使用 gettype() 巧编程序
    2. 你的设置方式并不能真正解决这个问题。虽然Faker可以创建假数据,但它不能为您的特定系统和业务案例自动创建已知的好数据和已知的坏数据。我假设您要测试已知的好数据+预期结果以及已知的坏数据+预期异常。

    构造此测试的正确方法是使用 @dataProvider database fixtures / testing .

    下面是它的样子:

    <?php
    namespace Foo\Bar;
    
    use PHPUnit\DbUnit\TestCaseTrait;
    use PHPUnit\Framework\TestCase;
    use \PDO;
    USE \Exception;
    
    class ProductTest extends TestCase
    {
        use TestCaseTrait;
    
    
        // only instantiate pdo once for test clean-up/fixture load
        static private $pdo = null;
    
        // only instantiate PHPUnit_Extensions_Database_DB_IDatabaseConnection once per test
        private $conn = null;
    
        final public function getConnection()
        {
            if ($this->conn === null) {
                if (self::$pdo == null) {
                    self::$pdo = new PDO($GLOBALS['DB_DSN'], $GLOBALS['DB_USER'], $GLOBALS['DB_PASSWD']);
                }
                $this->conn = $this->createDefaultDBConnection(self::$pdo, $GLOBALS['DB_DBNAME']);
            }
    
            return $this->conn;
        }
    
        public function getDataSet()
        {
            return $this->createMySQLXMLDataSet('tests/unit/testdata/sampleproductdata.xml');
        }
    
        /**
         * Tests products against known good data in the database fixture.
         * @param $id
         * @param $expectedName
         * @dataProvider providerTestProduct
         */
    
        public function testProduct($id, $expectedName) {
            $Product = new Product;
            $Product->id = $id;
            $Product->readId();
            $this->assertSame($expectedName, $Product->name);
        }
    
        /**
         * Provides data that should appear in the database.
         * @return array
         */
        public function providerTestProduct() {
                    // id , expectedName
            return  [ [ "ff62" , "fooproduct"]
                    , [ "dd83" , "barproduct"]
                    , [ "ls98" , "bazproduct"]
                    ];
        }
    
        /**
         * Tests products against known-bad data to ensure proper exceptions are thrown.
         * @param $id
         * @param $expectedName
         */
        public function testProductExceptions($id, $expectedName) {
            $Product = new Product;
            $Product->id = $id;
    
            $this->expectException(Exception::class);
            $Product->readId();
        }
    
        /**
         * Provides test data that when queried against the database should produce an error.
         * @return array
         */
        public function providerTestProductExceptions() {
            // id , expectedName
            return  [ [ "badtype" , "fooproduct"]  //Wrong id type
                    , [ "aaaa" , "barproduct"]     //Does not exist
                    , [ null   , "bazproduct"]     //null is a no-no.
            ];
        }
    }
    

    下面是一个细分:

    1. 使用名称空间。因为现在是2018年 it's the right thing to do
    2. use
    3. TestCaseTrait 适当地 setup your TestCase
    4. $pdo 变量将保留类/测试的数据库连接。
    5. getConnection() 是必需的。这将使用您在数据库中配置的数据库、用户名和密码 phpunit.xml 文件。 Reference
    6. getDataSet()

    中的数据提供程序 每种情况 提供要测试的ID和预期结果。如果是 testProduct providerTestProduct ,我们提供的身份证 应该存在 在数据库中(由上面的fixture保证)。我们可以检查一下 Product::readId() 不仅仅是返回一个 一串 ,但实际上是返回 .

    在第二种情况下, testProductException() providerTestProductException() 实际产生所需的行为:失败/抛出异常 .

        2
  •  0
  •   Kishlin    6 年前

    您可以使用随机数生成随机数据集。

    $value = dechex(random_int(0, 255)).dechex(random_int(0, 255));
    
    $Product = new Product;
    $Product->id = $value;
    $Product->readId();
    $this->assertEquals('string', gettype($Product->name));
    $this->assertEquals($value, $Product->name);
    

    人们通常把期望值放在左边,把实际值放在右边。

        3
  •  0
  •   Donnie Ashok    6 年前

    我发现最好的办法就是用假货。

    https://github.com/fzaninotto/Faker

    当我试图测试一个产品的不同实例时,我肯定可以使用Faker随机生成一个产品,并测试是否从数据库中正确检索到了该产品。