php - 将常见测试重构为基本测试用例

标签 php unit-testing testing phpunit xunit

如果两个或多个测试相同接口(interface)/抽象类的不同实现的测试类具有共同测试具有不同的固定装置,那么重构测试用例是否是个好主意?

假设代码和测试如下所示:

interface MathOperation
{
    public function doMath($a, $b);
}

class Sumator implements MathOperation
{
    public function doMath($a, $b)
    {
        return $a + $b;
    }
}


class Multiplicator implements MathOperation
{
    public function doMath($a, $b)
    {
        return $a * $b;
    }
}

// tests
class SumatorTest extends PHPUnit_Framework_TestCase
{
    /**
     * @var Sumator
     */
    protected $sumator;

    public function setUp()
    {
        $this->sumator = new Sumator;
    }

    /**
     * @dataProvider fixtures
     */
    public function testDoMath($a, $b, $expected)
    {
        $result = $this->sumator->doMath($a, $b);
        $this->assertEqual($expected, $result);
    }

    public function fixtures()
    {
        return array(
            array(1, 1, 2);
            array(2, 1, 3);
            array(100, -1, 99);
        );
    }
}

class MultiplicatorTest extends PHPUnit_Framework_TestCase
{
    /**
     * @var Multiplicator
     */
    protected $multiplicator;

    public function setUp()
    {
        $this->multiplicator = new Multiplicator;
    }

    /**
     * @dataProvider fixtures
     */
    public function testDoMath($a, $b, $expected)
    {
        $result = $this->multiplicator->doMath($a, $b);
        $this->assertEqual($expected, $result);
    }

    public function fixtures()
    {
        return array(
            array(1, 1, 1);
            array(2, 1, 2);
            array(100, -1, -100);
        );
    }
}

我希望它们(测试)看起来像这样:

class MathOperationTestCase extends PHPUnit_Framework_TestCase
{
    /**
     * @var MathOperation
     */
    protected $operation;

    public function setUp()
    {
        $this->operation = $this->createImpl();
    }

    /**
     * @return MathOperation
     */
    abstract function createImpl();

    /**
     * @dataProvider fixtures
     */
    public function testDoMath($a, $b, $expected)
    {
        $result = $this->operation->doMath($a, $b);
        $this->assertEqual($expected, $result);
    }

    abstract public function fixtures();
}

class SumatorTest extends MathOperationTestCase
{
    public function createImpl()
    {
        return new Sumator;
    }

    public function fixtures()
    {
        return array(
            array(1, 1, 2);
            array(2, 1, 3);
            array(100, -1, 99);
        );
    }
}

class MultiplicatorTest extends MathOperationTestCase
{
    public function createImpl()
    {
        return new Multiplicator;
    }

    public function fixtures()
    {
        return array(
            array(1, 1, 1);
            array(2, 1, 2);
            array(100, -1, -100);
        );
    }
}

这看起来结构更好,但可能缺乏可读性。所以最后我不确定它是否可用。

最佳答案

您已经抽象出 PHPUnitTest 的功能,足以使其适用于多个类!凉爽的。我还看到,如果 Sumator 或 Multiplicator 在未来添加了功能,这就会成为问题——无论你对这两个类做什么,你总是会面临是否应该将它抽象到基础的问题测试框架中的类也是如此。

在我看来,这使可维护性变得复杂,不是因为您必须调整多个类(无论哪种方式都会发生在测试类中),而是因为维护额外代码结构的负担增加了,您需要随时跟踪任一个类(class)的选择。

出于这个原因,在我看来,单元测试适用于一对一结构。你的方法减少了代码重复,因为只要一个类具有相同的结构和功能,它就适用于这个测试类。另一方面,在我看来,它开启了让类(class)适合测试的诱惑,而不是相反。

关于php - 将常见测试重构为基本测试用例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10431090/

相关文章:

angularjs - 如何在模块配置中模拟提供程序/配置以进行单元测试

unit-testing - QT:获取对象的类名

在 Raku 中测试私有(private)方法

php - google sheets 将数据附加到 sheet api 返回 401 身份验证错误

php - 在 ubuntu 14.04 PHP 版本 5.5.9-1ubuntu4.6(64 位服务器)上安装 PDFlib 时出现问题

php - 语法错误或访问冲突

python - 使用单元测试在 Jupyter 中测试学生的代码

Grails/Spock 测试为服务提供 stub 实现

testing - 聚类 : Cluster validation

php - 为 wordpress 主题添加额外的侧边栏