首页 文章

symfony:需要进程分离的phpunit测试

提问于
浏览
0

我正在尝试为Symfony系统添加登录过程的phpunit功能测试 . 登录过程很简单,但我在 Build 一个没有下面描述的许多问题之一的客户端时遇到了问题,而且我已经没有办法解决这些问题了 . 我对帖子的长度表示歉意 . 任何建议都将受到高度赞赏 .

Details
正常登录调试系统的顺序是:

http://localhost:8000/login GET -> html form for login
http://localhost:8000/login_check POST(_username,_password) -> redirect
http://localhost:8000/useridx/NN (same as redirect)

我的测试类扩展了WebTestCase,并包含相应的公共函数:

testGetLoginPage(): tests page returned from /login, returns $context (with $client)
testLoginCheck($context): posts the login data, validates the redirect page, and returns $context (with $client)
testUserIndex($context): validates the page returned by following the redirect

当我运行测试时,testGetLoginPage成功,然后testLoginCheck得到一个带有symfony堆栈跟踪的返回页面,指示:

<title>    Failed to start the session because headers have already been sent by &quot;/home1/xxxxx-app/vendor/phpunit/phpunit/src/Util/Printer.php&quot; at line 133. (500 Internal Server Error)</title>

与Printer.php中的行是:

print $buffer;

经过一些研究,我发现注释表明我可以通过为testLoginCheck声明这个来避免这个问题:

/**
 * @runInSeparateProcess 
 */

在声明之后,testLoginCheck获得了正确的页面(重定向)到/ useridx / NN . 然后我尝试按照testUserIndex中的重定向进行操作,但是响应返回了第一个登录页面的副本,其中包含访问被拒绝的指示,即使登录测试成功 .

我的下一个想法是我还需要为testUserIndex声明@runInSeparateProcess,但结果是一样的 . 我猜这导致了Print.php的一个进程,testLoginCheck的第二个进程,以及testUserIndex的第三个进程 . 我最终找到了另一个应用于我的测试类的指令:

/**
 * @runTestsInSeparateProcesses
 */

我从函数中删除了@runInSeparateProcess指令 . 这很有效,直到其中一个测试断言失败,此时我得到一个长的symfony异常和堆栈跟踪指示:

Caused by
exception 'ErrorException' with message 'Class __PHP_Incomplete_Class has no unserializer' in /home1/xxxxx-app/vendor/phpunit/phpunit/src/Util/PHP.php:107

通过故意断言一次断言一个断言,我发现不完整的类断言总是由第一个失败的断言触发 .

与@preserveGlobalState相关的注释表明可以禁用它以解决父进程和子进程之间的序列化器/反序列化器问题,但为该类设置该问题会导致新问题:

RuntimeException: You must override the KernelTestCase::createKernel() method.

我也试过模拟身份验证,所以我可以使用这种方法进入剩余的测试(需要身份验证):

http://symfony.com/doc/current/testing/simulating_authentication.html
http://symfony.com/doc/current/testing/http_authentication.html

但它总是让我重定向回登录页面 .

在开始使用不同的测试系统之前,我认为最好停下来寻求帮助 . 这是一个基本的测试,我似乎在玩傻瓜 .

1 回答

  • 0

    我找到了似乎有用的东西,但它可能不是“symfony方式”......

    • Do not 为测试类设置@runTestsInSeparateProcesses .

    • 将login / login_check合并为单个测试(由Massimiliano建议),这是该类中的第一个测试,设置了“@runInSeparateProcess” . 然后$ client = static :: createClient(); $ context [“client”] = $ client; return $ context;

    • 在所有后续测试中,$ client = $ context ["client"];在进入,并返回$ context . Do not 为其余测试设置@runInSeparateProcess . 使用此方法根据需要包含尽可能多的testXxx函数 . 客户端已经登录,因此权限没有问题 .

    • 我曾尝试将一个安全/防火墙/测试/ http_basic规则添加到app / config / security.yml,但它不能用于我的系统授权方式,并且所有后续测试都因权限问题而失败 .

    • 当测试以“bin / phpunit -c app src / BundleXxx / Tests / Controller / TheTest.php”运行时,“类__PHP_Incomplete_Class没有反序列化器”异常仍然是一个问题,但是当它作为一部分运行时不会发生“bin / phpunit -c app” . 我可以忍受这种情况,并且我已经添加了相应的文档 .

相关问题