【问题标题】:How to keep your tests small while using data providers?如何在使用数据提供者的同时保持测试规模小?
【发布时间】:2016-07-18 04:44:22
【问题描述】:

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

  1. 向端点发出请求并断言http代码为200,返回响应
  2. 解析响应体并对它做一些断言,返回解析后的响应体
  3. 对解析后的响应体的调试值做一些断言
  4. 向另一个端点发出新请求并断言 http 代码为 200,返回响应
  5. 解析响应正文并断言测试 1 的副作用确实发生了

正如您所见,测试从测试 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)
{
    // ...
}

【问题讨论】:

  • 看起来您即将从单元测试进入功能测试。当然,功能测试可以通过普通的 phpunit 测试用例来执行,但我认为这可能会很混乱。我不想为这个问题提供直接的建议,但我认为在你的特殊情况下,我更喜欢用普通的 PHP 编写功能测试。或者,您可以查看代码接收框架。

标签: php testing phpunit silex


【解决方案1】:

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

  1. 从集成测试中移除了一些更复杂的测试用例 到单元测试。所以我不再测试端点,而是当你去端点时执行的方法。
  2. 添加了一个通用测试用例,该测试用例对来自数据提供者的数据进行操作,其中包括但不限于不同端点的 URL。这个测试用例只是测试端点是否返回了预期的 http 代码和其他一些小东西。这让我可以将所有的集成测试放到一个简单的测试用例中。

我对这个解决方案非常满意,我删除了 7-8 个测试类,并且转移到单元测试的复杂测试也得到了简化。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-01
    相关资源
    最近更新 更多