测试

编辑本页

警告:您正在浏览的文档欧宝体育电话<一个href="//www.oldmanjams.com/releases/2.6">欧宝娱乐app下载地址Symfony 2.6,现已不再维护。

读<一个href="//www.oldmanjams.com/doc/current/testing.html">本页的更新版本用于Sy欧宝娱乐app下载地址mfony 6.2(当前稳定版本)。

测试

每当您编写新的代码行时,您也可能会添加新的错误。为了构建更好、更可靠的应用程序,应该同时使用功能测试和单元测试来测试代码。

PHPUnit测试框架

欧宝娱乐app下载地址Symfony集成了一个名为PHPUnit的独立库,为您提供了一个丰富的测试框架。本章不会涉及PHPUnit本身,但它有自己的优点<一个href="http://phpunit.de/manual/current/en/" class="reference external" rel="external noopener noreferrer" target="_blank">欧宝体育电话

请注意

建议使用最新的稳定PHPUnit版本(您必须使用4.2或更高版本来测试Symfony核心代码本身)。欧宝娱乐app下载地址

每个测试——无论是单元测试还是功能测试——都是一个PHP类,应该存在于测试/你的包的子目录。如果您遵循此规则,那么您可以使用以下命令运行应用程序的所有测试:

1 2
#在命令行上指定配置目录$ phpunit -c app/

- c选项告诉PHPUnit在app /配置文件的目录。如果您对PHPUnit选项感兴趣,请查看app / phpunit.xml.dist文件。

提示

方法可以生成代码覆盖——覆盖- *选项,请参阅使用时显示的帮助信息——帮助获取更多信息。

单元测试

单元测试是针对单个PHP类的测试,也称为单位.如果您想测试应用程序的整体行为,请参阅有关的部分<一个href="//www.oldmanjams.com/doc/2.6/book/testing.html" class="reference internal">功能测试

编写Symfon欧宝娱乐app下载地址y单元测试与编写标准的PHPUnit单元测试没有什么不同。假设,比如说,你有一个令人难以置信的类调用计算器Util /应用程序包目录:

1 2 3 4 5 6 7 8 9 10
/ / src / AppBundle / Util / Calculator.php名称空间AppBundle跑龙套计算器公共函数添加一个b返回一个+b;}}

要测试这一点,可以创建一个CalculatorTest测试/ Utilbundle目录:

12 3 4 5 6 7 8 9 10 11 12 13 14 15 16
/ / src / AppBundle /测试/ Util / CalculatorTest.php名称空间AppBundle测试跑龙套使用AppBundle跑龙套计算器CalculatorTest扩展PHPUnit_Framework_TestCase公共函数testAdd()calc计算器();结果calc->add (30.12);//你的计算器加的数是正确的!->assertequal (42结果);}}

请注意

按照惯例,测试/子目录应该复制单元测试包的目录。所以,如果你在你的捆绑包中测试一个类Util /目录,将测试放在测试/ Util /目录中。

就像在您的实际应用程序-自动加载是自动启用通过bootstrap.php.cache文件中默认配置的app / phpunit.xml.dist文件)。

对给定的文件或目录运行测试也非常简单:

1 2 3 4 5 6 7 8 9 10 11
#运行应用程序的所有测试$ phpunit -c app#运行Util目录下的所有测试$ phpunit -c app src/AppBundle/Tests/Util#运行计算器类的测试$ phpunit -c app src/AppBundle/Tests/Util/CalculatorTest.php#运行整个Bundle的所有测试$ phpunit -c app src/AppBundle/

功能测试

功能测试检查应用程序不同层(从路由到视图)的集成。就PHPUnit而言,它们与单元测试没有什么不同,但它们有一个非常具体的工作流程:

  • 提出请求;
  • 测试响应;
  • 点击链接或提交表单;
  • 测试响应;
  • 清洗并重复。

你的第一个功能测试

功能测试是简单的PHP文件,通常位于测试/控制器包的目录。如果您想测试由您的为PostController类,首先创建一个newPostControllerTest.php扩展特殊类型的文件WebTestCase类。

举个例子,一个测试可以是这样的:

12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
/ / src / AppBundle /测试/控制器/ PostControllerTest.php名称空间AppBundle测试控制器使用欧宝娱乐app下载地址FrameworkBundle测试WebTestCasePostControllerTest扩展WebTestCase公共函数testShowPost()客户端静态::createClient ();履带客户端->请求(“得到”' / post / hello world ');->assertGreaterThan (0履带->过滤器(html:包含(“Hello World”)”->count ());}}

提示

要运行功能测试,请使用WebTestCase类引导应用程序的内核。在大多数情况下,这是自动发生的。但是,如果您的内核位于非标准目录中,则需要修改您的内核phpunit.xml.dist文件来设置KERNEL_DIR到内核目录的环境变量:

1 2 3 4 5 6 7
<?XML版本="1.0" charset="utf-8"<phpunit)><php><服务器的名字“KERNEL_DIR”价值“/道路/ /你/ app /”/>php><!——……-->phpunit)>

createClient ()方法返回一个客户端,它就像一个浏览器,你将使用它来抓取你的网站:

1
履带客户端->请求(“得到”' / post / hello world ');

请求()方法(读<一个href="//www.oldmanjams.com/doc/2.6/book/testing.html" class="reference internal">关于请求方法的更多信息)返回一个<一个href="https://github.com/symfony/symfony/blob/2.6/src/Symfony/Component/DomCrawler/Crawler.php" class="reference external" title="履带" rel="external noopener noreferrer" target="_blank">履带对象,可用于在响应中选择元素、单击链接和提交表单。

提示

履带只有当响应是XML或HTML文档时才有效。要获得原始内容响应,请调用客户端- > getResponse()——> getContent ()

点击一个链接,首先用爬虫选择它,使用XPath表达式或CSS选择器,然后使用客户端单击它。例如:

1 2 3 4 5 6 7
链接履带->过滤器(答:包含(“问候”)的//找到所有文本"Greet"的链接->eq (1//选择列表中的第二个链接->链接()//然后点击它履带客户端->点击(链接);

提交表单非常类似:选择一个表单按钮,可选地覆盖一些表单值,并提交相应的表单:

1 2 3 4 5 6 7 8
形式履带->selectButton (“提交”->形式();//设置一些值形式“名字”] =“卢卡斯”形式“form_name(主题)”] =“嘿!”//提交表单履带客户端->提交(形式);

提示

表单还可以处理上传,并包含填充不同类型表单字段的方法(例如。select ()而且蜱虫()).详细信息请参见<一个href="//www.oldmanjams.com/doc/2.6/book/testing.html" class="reference internal">形式下面的部分。

现在您可以轻松地在应用程序中导航,使用断言来测试它实际上执行了您期望的操作。使用爬虫对DOM进行断言:

1 2
//断言响应匹配给定的CSS选择器。->assertGreaterThan (0履带->过滤器(“标题”->count ());

或者直接测试响应内容,如果你只是想断言内容包含一些文本,或者如果响应不是XML/HTML文档:

1 2 3 4
->assertContains (“Hello World”客户端->getResponse ()->getContent ());

为了让你更快地开始,这里有一个最常见和最有用的测试断言列表:

12 34 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
使用欧宝娱乐app下载地址组件HttpFoundation响应/ /……//确定至少有一个h2标签//与类"subtitle"->assertGreaterThan (0履带->过滤器(“h2.subtitle”->count ());//断言页面上恰好有4个h2标记->assertCount (4履带->过滤器(“氢气”));//声明"Content-Type"报头为"application/json"->assertTrue (客户端->getResponse ()->->包含(“内容类型”“application / json”));//断言响应内容包含一个字符串->assertContains (“foo”客户端->getResponse ()->getContent ());/ /……或matches a regex->assertRegExp (' / foo (bar) ?/ '客户端->getResponse ()->getContent ());//确认响应状态码为2xx->assertTrue (客户端->getResponse ()->isSuccessful ());//确认响应状态代码为404->assertTrue (客户端->getResponse ()->isNotFound ());//指定200状态码->assertequal (200//或者Sy欧宝娱乐app下载地址mfony\Component\HttpFoundation\Response::HTTP_OK客户端->getResponse ()->getStatusCode ());//断言响应是一个重定向到/demo/contact->assertTrue (客户端->getResponse ()->isRedirect (“/演示/接触”));/ /……或simply check that the response is a redirect to any URL->assertTrue (客户端->getResponse ()->isRedirect ());

2.4

Symfony 2.4中引入了对HTTP状态码常量的支持。欧宝娱乐app下载地址

使用测试客户端

测试客户端模拟一个HTTP客户端,就像一个浏览器,并向您的Symfony应用程序发出请求:欧宝娱乐app下载地址

1
履带客户端->请求(“得到”' / post / hello world ');

请求()方法将HTTP方法和URL作为参数,并返回一个履带实例。

提示

硬编码请求url是功能测试的最佳实践。如果测试使用Symfony路由器生成url,它将不会检测到对应用程序url欧宝娱乐app下载地址所做的任何可能影响最终用户的更改。

的完整签名请求()方法是:

1 2 3 4 5 6 7 8 9
请求(方法uri数组参数数组(),数组文件数组(),数组服务器数组(),内容changeHistory真正的

服务器数组是您期望在PHP中通常找到的原始值<一个href="http://php.net/manual/en/reserved.variables.server.php" class="reference external" rel="external noopener noreferrer" target="_blank">$ _SERVERsuperglobal。例如,设置内容类型推荐人而且X-Requested-WithHTTP报头,您将传递以下信息(注意HTTP_非标准标头的前缀):

1 2 3 4 5 6 7 8 9 10 11
客户端->请求(“得到”' / post / hello world '数组(),数组(),数组“CONTENT_TYPE”= >“application / json”“HTTP_REFERER”= >“/ foo / bar”“HTTP_X-Requested-With”= >XMLHttpRequest的,));

使用爬虫程序在响应中查找DOM元素。这些元素可以用来点击链接并提交表单:

1 2 3 4 5
链接履带->selectLink (“去别处……”->链接();履带客户端->点击(链接);形式履带->selectButton (“验证”->形式();履带客户端->提交(形式数组“名字”= >“法”));

click ()而且提交()方法都返回履带对象。这些方法是浏览应用程序的最佳方式,因为它为您处理了很多事情,比如从表单中检测HTTP方法,并为您提供用于上传文件的漂亮API。

提示

您将了解更多关于链接而且形式对象中的<一个href="//www.oldmanjams.com/doc/2.6/book/testing.html" class="reference internal">履带下面的部分。

请求方法也可用于直接模拟表单提交或执行更复杂的请求。一些有用的例子:

12 34 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
//直接提交表单(但是使用爬虫更容易!)客户端->请求(“职位”/提交的数组“名字”= >“法”));//在请求体中提交原始JSON字符串客户端->请求(“职位”/提交的数组(),数组(),数组“CONTENT_TYPE”= >“application / json”),”{“名称”:“法”}’);//表单提交和文件上传使用欧宝娱乐app下载地址组件HttpFoundation文件UploadedFile照片UploadedFile (“/道路/ / photo.jpg”“photo.jpg”“图像/ jpeg”123);客户端->请求(“职位”/提交的数组“名字”= >“法”),数组“照片”= >照片));//执行DELETE请求并传递HTTP报头客户端->请求(“删除”' / post / 12数组(),数组(),数组“PHP_AUTH_USER”= >“用户名”“PHP_AUTH_PW”= >“爸爸$ $词”));

最后但并非最不重要的是,你可以强制每个请求在它自己的PHP进程中执行,以避免在同一个脚本中使用多个客户端时产生任何副作用:

1
客户端->使();

爬虫

每次向客户端发出请求时,都会返回一个爬虫实例。它允许您遍历HTML文档,选择节点,查找链接和表单。

形式

可以使用按钮来选择表单,可以使用selectButton ()方法,就像链接一样:

1
buttonCrawlerNode履带->selectButton (“提交”);

请注意

注意,您选择的是表单按钮而不是表单,因为一个表单可以有几个按钮;如果使用遍历API,请记住必须寻找按钮。

selectButton ()方法可以选择按钮标签和提交输入标签。它使用按钮的几个部分来查找它们:

  • 价值属性值;
  • idalt图像的属性值;
  • id的名字的属性值按钮标签。

有了表示按钮的Crawler后,调用形式()方法来获取形式实例,用于包装按钮节点的表单:

1
形式buttonCrawlerNode->形式();

当致电形式()方法,您还可以传递一个覆盖默认值的字段值数组:

1 2 3 4
形式buttonCrawlerNode->形式(数组“名字”= >“法”“my_form(主题)”= >“欧宝娱乐app下载地址Symfony岩石!”));

如果你想为表单模拟一个特定的HTTP方法,将它作为第二个参数传递:

1
形式buttonCrawlerNode->形式(数组(),“删除”);

客户可以提交形式实例:

1
客户端->提交(形式);

属性的第二个参数传递字段值提交()方法:

1 2 3 4
客户端->提交(形式数组“名字”= >“法”“my_form(主题)”= >“欧宝娱乐app下载地址Symfony岩石!”));

对于更复杂的情况,请使用形式实例作为数组单独设置每个字段的值:

1 2 3
//改变一个字段的值形式“名字”] =“法”形式“my_form(主题)”] =“欧宝娱乐app下载地址Symfony岩石!”

还有一个很好的API来根据字段的类型来操作字段的值:

1 2 3 4 5 6 7 8
//选择一个选项或收音机形式“国家”->选择(“法国”);//勾选复选框形式“like_欧宝娱乐app下载地址symfony”->蜱虫();//上传文件形式“照片”->上传(“/道路/ / lucas.jpg”);

提示

如果您有意选择“无效”的选择/单选值,请参见<一个href="//www.oldmanjams.com/doc/2.6/components/dom_crawler.html" class="reference internal">DomCrawler组件

提示

方法可以获得将要提交的值getvalue ()方法。形式对象。返回的单独数组中有上传的文件getfile ().的getPhpValues ()而且getPhpFiles ()方法也会返回提交的值,但是是PHP格式(它转换了带有方括号符号的键)。my_form(主题)- PHP数组)。

测试配置

功能测试使用的客户端创建在特殊环境中运行的内核测验环境。因为Symf欧宝娱乐app下载地址ony加载应用程序/配置/ config_test.yml测验环境,您可以调整应用程序的任何设置专门用于测试。

例如,默认情况下,Swift Mailer配置为实际上是在测验环境。你可以看到这个在swiftmailer配置选项:

  • YAML
  • XML
  • PHP
1 2 3 4 5
# app / config / config_test.yml#……swiftmailer:disable_delivery:真正的

您也可以完全使用不同的环境,或重写默认的调试模式(真正的),将它们作为选项传递给createClient ()方法:

1 2 3 4
客户端静态::createClient (数组“环境”= >“my_test_env”“调试”= >));

的第二个参数来传递它们createClient ()

1 2 3 4
客户端静态::createClient (数组(),数组“HTTP_HOST”= >“en.example.com”“HTTP_USER_AGENT”= >“MySuperBrowser / 1.0”));

你也可以在每个请求的基础上覆盖HTTP头:

1 2 3 4
客户端->请求(“得到”' / '数组(),数组(),数组“HTTP_HOST”= >“en.example.com”“HTTP_USER_AGENT”= >“MySuperBrowser / 1.0”));

提示

中的容器中的服务可用于测试客户端测验环境(或任何地方)<一个href="//www.oldmanjams.com/doc/2.6/reference/configuration/framework.html" class="reference internal">framework.test选项已启用)。这意味着如果需要,您可以完全覆盖该服务。

PHPUnit)配置

每个应用程序都有自己的PHPUnit配置,存储在app / phpunit.xml.dist文件。您可以编辑此文件以更改默认值或创建app / phpunit.xml文件仅为本地计算机设置配置。

提示

存储app / phpunit.xml.dist文件,并忽略app / phpunit.xml文件。

默认情况下,只有来自您自己的定制包的测试存储在标准目录中src / * / *包/测试src / * /包/ *包/测试src / *包/测试都是由phpunit)命令中配置的app / phpunit.xml.dist文件:

12 3 4 5 6 7 8 9 10 11 12
<!——app / phpunit.xml。dist - - - ><phpunit)><!——……--><testsuite文件><testsuite的名字“项目测试套件”><目录>. . / src / * / *包/测试目录><目录>. . / src / * /包/ *包/测试目录><目录>. . / src / *包/测试目录>testsuite>testsuite文件><!——……-->phpunit)>

但是您可以轻松地添加更多目录。例如,以下配置从自定义添加测试lib /测试目录:

1 2 3 4 5 6 7 8 9 10 11
<!——app / phpunit.xml。dist - - - ><phpunit)><!——……--><testsuite文件><testsuite的名字“项目测试套件”><!——……---><目录>. . / lib /测试目录>testsuite>testsuite文件><!——……--->phpunit)>

要在代码覆盖范围中包含其他目录,还可以编辑过滤器> <部分:

12 3 4 5 6 7 8 9 10 11 12 13 14 15
<!——app / phpunit.xml。dist - - - ><phpunit)><!——……--><过滤器><白名单><!——……--><目录>. . / lib目录><排除><!——……--><目录>. . / lib /测试目录>排除>白名单>过滤器><!——……--->phpunit)>
此工作,包括代码示例,是根据<一个rel="license" href="https://creativecommons.org/licenses/by-sa/3.0/">创作共用BY-SA 3.0许可证。