我可以创建一个客户端并将其重用于我的所有功能测试吗?

时间:2016-02-04 17:24:00

标签: php symfony testing functional-testing

tl; dr:这可能会使我的测试无法正常运行吗?

我正在尝试为我的Symfony项目编写功能测试,并使用The Symfony Book中的示例。到目前为止,测试类的每个方法都以相同的代码行开始:

namespace Tests\AppBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;

class SomeControllerTest extends WebTestCase
{
    public function testSomethingOnRouteX()
    {
        $client = static::createClient();
        // set up and assert
    }

    public function testSomethingElseOnRouteX()
    {
        $client = static::createClient();
        // different set up and assert
    }
}

我想删除这个冗余代码,但我不确定是否应该这样做。

我添加了一个构造函数,我在其中创建了客户端。

public function __construct()
{
    parent::__construct();
    $this->client = static::createClient();
}

然后在各种测试方法中我可以使用$this->client而无需重复创建它。这似乎到目前为止工作(我还没有很多测试。)但我对这个框架已经足够新了,对于这种类型的测试,我不确定它是否会在未来发生问题。

3 个答案:

答案 0 :(得分:2)

建议的方法是使用setUp()方法或@before挂钩。在每种测试方法之前都会调用这两种测试方法,因此您可以在测试用例之间共享状态时保持安全。运行每个测试用例后,也会自动完成清理(在WebTestCase类中实现)。

namespace Tests\AppBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use Symfony\Bundle\FrameworkBundle\Client;

class SomeControllerTest extends WebTestCase
{
    /**
     * @var Client
     */
    private $client;

    protected setUp()
    {
        $this->client = self::createClient();
    }

    public function testSomethingOnRouteX()
    {
        // set up and assert
        $this->client->request('GET', '/something');
    }

    public function testSomethingElseOnRouteX()
    {
        // different set up and assert
        $this->client->request('GET', '/something-else');
    }
}

setUp()之外,您可以使用@before挂钩:

namespace Tests\AppBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use Symfony\Bundle\FrameworkBundle\Client;

class SomeControllerTest extends WebTestCase
{
    /**
     * @var Client
     */
    private $client;

    /**
     * @before
     */
    protected setUp()
    {
        $this->client = self::createClient();
    }

    // ...

}

答案 1 :(得分:1)

如果你尝试一下,你应该使用setUp-method代替。重用客户端可能会引入副作用,这是您试图避免的。如果您的测试开始随机失败,您可能希望尝试返回每个测试创建一个新客户端。我不会推荐它,但更多来自直觉而非实际的糟糕体验。它应该在大多数情况下都可以正常工作,但是当你突然重复使用一个客户端,例如一个不同设置的标题并且它不起作用时你会很头疼。

我认为无论如何ui测试都会很慢,因此会有巨大的性能提升,因此尝试测试用例可能是更好的方法(寻找测试金字塔,如果你没有&#如果这是你的目标,那就知道我的意思了。

答案 2 :(得分:0)

取决于您正在测试的内容,它可能有效或可能无效。

新客户端就像一个全新的浏览器安装。没有设置Cookie,没有历史记录,没有actual页面,等等。

如果您正在测试auth,例如,如果testCanNotAccessInternalResourceIfNotLoggedIn将使用仍然登录的客户端,因为testLogInWithCorrectCredentialsWorks在它之前运行并因此失败,那将是非常糟糕的。当然,您可以确保在访问资源之前注销用户,但只是创建一个干净的新浏览器实例是最简单且最不容易出错的方法。