如何在使用数据提供程序时保持较小的测试?

时间:2016-03-30 09:15:33

标签: php testing phpunit silex

我正在测试Web应用程序的端点/ API。我有多个小测试依赖于前面测试的返回值。一些测试甚至取决于前面测试产生的副作用。以下是一个示例(编号列表项代表各个测试用例):

  1. 向端点发出请求并断言http代码为200,返回响应
  2. 解析响应主体并对其执行一些断言,返回已解析的响应主体
  3. 对已解析的响应正文的调试值执行一些断言
  4. 向另一个端点发出新请求,并断言http代码为200,返回响应
  5. 解析响应主体并断言测试1的副作用实际发生
  6. 正如您所看到的那样,测试从测试1传播,所有其他测试都取决于其返回值或副作用。

    现在,我想使用来自数据提供程序的数据执行这些测试,以测试来自我们应用程序的多个用户的行为。根据phpunit文档,这是不可能的。来自文档:

      

    当测试依赖于使用数据提供程序的测试时,依赖测试将在其依赖的测试成功执行至少一个数据集时执行。使用数据提供程序的测试结果无法注入依赖测试。

    为了清楚起见,我想要的是测试1用y值执行x次,并让所有其他测试传播其返回值或每次检查其副作用。 经过一些谷歌搜索后,想到的唯一解决方案是将所有测试放入一个单独的测试中以删除所有依赖项。但是我有多个测试套件具有这种行为,并且一些测试会变得非常庞大和笨拙。

    那么,如何在使用数据提供程序时保持小测试用例之间的依赖关系?我正在使用php 5.5以及Silex 1.3和phpunit 4.8

    编辑:我应该提一下,我的测试正在扩展Silex的WebTestCase,不过我不确定它是否有所作为。

    以下是我不清楚的例子:

    public function testValidResponse()
    {
        $client = $this->createClient();
        $client->request('POST', '/foo', $this->params);
        $this->assertEquals(200, $client->getResponse()->getStatusCode());
        return $client->getResponse();
    }
    
    /**
     * @depends testValidResponse
     */
    public function testStatusIsOk(Response $response)
    {
        $json = json_decode($response->getContent(), true);
        $this->assertTrue($json['status']);
        return $json;
    }
    
    /**
     * @depends testStatusIsOk
     */
    public function testExecutionTime($json)
    {
        $this->assertLessThan($this->maxExecutionTime, $json['debug']['executionTimeSec']);
    }
    
    /**
     * @depends testValidResponse
     */
    public function testAnotherEndpointValidResponse()
    {
        $client = $this->createClient();
        $client->request('GET', '/bar');
        $this->assertEquals(200, $client->getResponse()->getStatusCode());
        return $client->getResponse();
    }
    
    /**
     * @depends testAnotherEndpointValidResponse
     */
    public function testSideEffectsFromFirstTest(Response $response)
    {
        // ...
    }
    

1 个答案:

答案 0 :(得分:1)

我认为主要问题是测试过于复杂,并且不应该相互依赖。解决方案是通过重构测试来降低一些复杂性。以下是我所做的大致概述:

  1. 从集成测试中移除了一些更复杂的测试用例 到单元测试。所以我不再测试端点了,而是在你去端点时执行的方法。
  2. 添加了一个通用测试用例,该测试用例对来自数据提供者的数据进行操作,该数据提供者包括但不限于不同端点的URL。这个测试用例只测试端点返回预期的http代码和其他一些小东西。这使我能够将所有集成测试放到一个简单的测试用例中。
  3. 我对解决方案非常满意,我删除了7-8个测试类,并且简化了移动到单元测试的复杂测试。