测试

编辑该页面

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

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

测试< /h1>

每当你写新代码,你也可能添加新的bug。建立更好、更可靠的应用程序时,您应该使用功能和测试您的代码单元测试。

PHPUnit)测试框架< /h2>

欧宝娱乐app下载地址Symfony集成了一个独立的库——称为PHPUnit)——给你一个丰富的测试框架。本章不会覆盖PHPUnit)本身,但它有自己的优秀<一个href="https://phpunit.de/manual/current/en/" class="reference external" rel="external noopener noreferrer" target="_blank">欧宝体育电话

请注意

这是推荐使用的最新稳定版本PHPUnit),<一个href="https://phpunit.de/manual/current/en/installation.html" class="reference external" rel="external noopener noreferrer" target="_blank">安装在PHAR

每个测试——无论它是一个单元测试或功能测试——是一个PHP类,应该生活在测试/应用程序的目录。如果你遵循这个规则,你就可以运行您的应用程序的所有测试使用下面的命令:

1
phpunit)美元

PHPunit)的配置phpunit.xml.distSymfony应用程序文件的根。欧宝娱乐app下载地址

提示

代码覆盖率可以与生成——覆盖- *选项,查看帮助信息显示在使用中——帮助为更多的信息。

单元测试< /h2>

单元测试是一种测试一个PHP类,也称为单位。如果你想测试您的应用程序的整体行为,看到的部分<一个href="//www.oldmanjams.com/doc/3.0/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文件测试/ AppBundle /跑龙套您的应用程序的目录:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
/ /测试/ AppBundle / Util / CalculatorTest.php名称空间测试\AppBundle\跑龙套;使用AppBundle\跑龙套\计算器;CalculatorTest扩展\PHPUnit_Framework_TestCase{公共函数testAdd(){美元calc=计算器();美元结果=美元calc- >add (30.,12);/ /正确断言计算器添加数字!美元- >assertequal (42,美元结果);}}

请注意

按照惯例,测试/ AppBundle目录应该复制目录为单元测试你的包。所以,如果你正在测试一个类src / AppBundle / Util /目录,把测试测试/ AppBundle / Util /目录中。

就像在真实的应用程序——半自动的是自动启用通过app / autoload.php配置文件(默认情况下phpunit.xml.dist文件)。

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

1 2 3 4 5 6 7 8 9 10 11
#运行所有的测试应用程序phpunit)美元# Util目录中运行所有测试美元/ AppBundle / Util phpunit)测试#为计算器类运行测试美元/ AppBundle / Util / CalculatorTest.php phpunit)测试整个包#运行所有测试美元/ AppBundle phpunit)测试

功能测试< /h2>

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

  • 使一个请求;
  • 测试的响应;
  • 点击一个链接或提交表单;
  • 测试的响应;
  • 清洗和重复的方法。

你的第一个功能测试< /h3>

功能测试是简单的PHP文件,通常生活在测试/ AppBundle /控制器目录你的包。如果你想测试页面由你处理为PostController类,通过创建一个新的开始PostControllerTest.php扩展了一个特殊的文件WebTestCase类。

作为一个例子,一个测试可以是这个样子:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
/ /测试/ AppBundle /控制器/ PostControllerTest.php名称空间测试\AppBundle\控制器;使用欧宝娱乐app下载地址\\FrameworkBundle\测试\WebTestCase;PostControllerTest扩展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 version = " 1.0 " charset =“utf - 8”? ><phpunit)><php><服务器的名字=“KERNEL_DIR”价值=“/道路/ /你/ app /”/ >< /php>< !——……- - >< /phpunit)>

createClient ()方法返回一个客户,就像一个浏览器,您将使用爬行你的网站:

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

请求()方法(读<一个href="//www.oldmanjams.com/doc/3.0/testing.html" class="reference internal">更多关于请求方法)返回一个<一个href="https://github.com/symfony/symfony/blob/3.0/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 8
美元链接=美元履带- >过滤器(答:包含(“问候”)的)/ /查找所有与文本“问候”- >eq (1)/ /列表中选择第二个链接- >链接();/ /点击它美元履带=美元客户端- >点击(美元链接);

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

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

提示

形式也可以处理上传和包含的方法填写(如不同类型的表单字段。select ()蜱虫())。详情,请参阅<一个href="//www.oldmanjams.com/doc/3.0/testing.html" class="reference internal">形式下面的部分。

现在,您可以轻松地浏览应用程序中,使用断言来测试它实际上您期望它。使用爬虫对DOM断言:

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

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

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

开始更快,这里列出最常见的和有用的测试断言:

1 2 3 4 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 44 45
使用欧宝娱乐app下载地址\组件\HttpFoundation\响应;/ /……/ /断言,至少有一个h2标签/ /类的“字幕”美元- >assertGreaterThan (0,美元履带- >过滤器(“h2.subtitle”)- >count ());/ /断言,确切地说,有4 h2标签在页面上美元- >assertCount (4,美元履带- >过滤器(“氢气”));/ /断言“内容类型”头是“application / json”美元- >assertTrue (美元客户端- >getResponse ()- >- >包含(“内容类型”,“application / json”),的“内容类型”头“application / json”/ /可选的消息显示在失败);/ /断言响应内容包含一个字符串美元- >assertContains (“foo”,美元客户端- >getResponse ()- >getContent ());/ /……或matches a regex< /span>美元- >assertRegExp (“/ foo (bar) ?”,美元客户端- >getResponse ()- >getContent ());/ /断言响应状态码是2 xx美元- >assertTrue (美元客户端- >getResponse ()- >isSuccessful (),“响应状态是2 xx”);/ /断言响应状态码是404美元- >assertTrue (美元客户端- >getResponse ()- >isNotFound ());/ /维护特定的200状态码美元- >assertequal (200年,/ /或Sy欧宝娱乐app下载地址mfony \组件\ HttpFoundation \回应::并美元客户端- >getResponse ()- >getStatusCode ());/ /断言响应是一个重定向到/演示/接触美元- >assertTrue (美元客户端- >getResponse ()- >isRedirect (“/演示/接触”),的反应是一个重定向到/演示/接触');/ /……或simply check that the response is a redirect to any URL< /span>美元- >assertTrue (美元客户端- >getResponse ()- >isRedirect ());

使用测试客户端< /h2>

测试客户端模拟HTTP客户端浏览器和使请求Symfony应用程序:欧宝娱乐app下载地址

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

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

提示

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

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

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/3.0/testing.html" class="reference internal">履带下面的部分。

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

1 2 3 4 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年);美元客户端- >请求(“职位”,/提交的,数组(“名字”= >“法”),数组(“照片”= >美元照片));/ /执行删除请求并通过HTTP头美元客户端- >请求(“删除”,' / post / 12,数组(),数组(),数组(“PHP_AUTH_USER”= >“用户名”,“PHP_AUTH_PW”= >“爸爸$ $词”));

最后但并非最不重要,你可以迫使每个请求执行的PHP程序,以避免任何副作用在处理一些客户在相同的脚本:

1
美元客户端- >使();

爬虫< /h2>

履带实例返回每次与客户请求。它允许您遍历HTML文档,选择节点,发现链接和表单。

形式< /h3>

形式可以选择使用他们的按钮,可以选择的selectButton ()法,就像链接:

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

请注意

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

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

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

一旦你有了一个履带代表一个按钮,调用形式()方法来获取一个形式包装按钮节点实例的形式:

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/3.0/components/dom_crawler.html" class="reference internal">DomCrawler组件

提示

你可以将提交的值通过调用getvalue ()方法形式对象。上传的文件都可以在一个单独的数组返回getfile ()。的getPhpValues ()getPhpFiles ()方法也返回提交的值,但在PHP格式(它转换与方括号键符号——如。my_form(主题)- PHP数组)。

添加和删除表单收集< /h4>

如果你使用一个<一个href="//www.oldmanjams.com/doc/3.0/form/form_collections.html" class="reference internal">集合的形式,你不能将字段添加到现有的形式$形式['任务[标记][0][名字]]=“foo”;。这将导致一个错误遥不可及的领域“…”因为美元的形式只能使用现有的字段设置值。为了添加新的字段,你必须将值添加到原始数据数组:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
/ /获取表单。美元形式=美元履带- >过滤器(“按钮”)- >形式();/ /得到的原始值。美元=美元形式- >getPhpValues ();/ /添加字段的原始值。美元(“任务”][“标签”][0][“名字”]=“foo”;美元(“任务”][“标签”][1][“名字”]=“酒吧”;/ /提交表单与现有的和新的价值观。美元履带=美元- >客户端- >请求(美元形式- >getMethod (),美元形式- >getUri (),美元,美元形式- >getPhpFiles ());/ / 2标记被添加到集合中。美元- >assertequal (2,美元履带- >过滤器(ul。标签>李')- >count ());

在哪里任务[标记][0][名称]是使用JavaScript创建的字段的名称。

您可以删除现有的领域,例如一个标签:

1 2 3 4 5 6 7 8 9 10 11 12
/ /获取表单的值。美元=美元形式- >getPhpValues ();/ /删除第一个标记。设置(美元(“任务”][“标签”][0]);/ /提交数据。美元履带=美元客户端- >请求(美元形式- >getMethod (),美元形式- >getUri (),美元,美元形式- >getPhpFiles ());/ /标签已被删除。美元- >assertequal (0,美元履带- >过滤器(ul。标签>李')- >count ());

测试配置< /h2>

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

例如,在默认情况下,迅速梅勒配置提供的电子邮件测试环境。你可以看到这下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”,“调试”= >));

如果您的应用程序的行为根据一些HTTP头,可以将它们作为第二个参数传递的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/3.0/reference/configuration/framework.html" class="reference internal">framework.test选项启用)。这意味着您可以完全覆盖服务如果你需要。

这项工作,包括代码示例,许可下<一个rel="license" href="https://creativecommons.org/licenses/by-sa/3.0/">Creative Commons冲锋队3.0许可证。