测试
测试
当我们开始将越来越多的功能添加到应用程序中,这可能是正确的时间谈论测试。
有趣的事实:我发现一个错误在写测试在这一章。
ob娱乐下载Symfony依赖PHPUnit)为单元测试。让我们安装它:
1
美元ob娱乐下载symfony作曲家点播phpunit) - dev
编写单元测试
SpamChecker
第一节课我们要编写测试。生成单元测试:
1
美元ob娱乐下载symfony控制台:测试TestCase SpamCheckerTest
测试SpamChecker是一个挑战,我们当然不希望Akismet API。我们要模拟API。
我们先写一个测试API时,返回一个错误:
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
- - - /测试/ SpamCheckerTest.php+ + + b /测试/ SpamCheckerTest.php@@ 2,12 + 2,26 @@名称空间的应用程序\测试;+使用App \实体\评论;+使用App \ SpamChecker;使用PHPUnit) \ Framework \ TestCase;+使用Syob娱乐下载mfony \ \ HttpClient \ MockHttpClient组件;+使用Syob娱乐下载mfony \组件\ HttpClient \ \ MockResponse反应;+使用Syob娱乐下载mfony \ \ HttpClient \ ResponseInterface合同;类SpamCheckerTest扩展TestCase {——公共职能testSomething():空白+公共职能testSpamScoreWithInvalidRequest():空白{- $ this - > assertTrue(真正的);+ $ = new评论评论();+ $评论- > setCreatedAtValue ();+ $上下文= [];++ $客户=新MockHttpClient([新MockResponse(“无效”,(“response_headers”= > [x-akismet-debug-help:无效的键的]])));+ $检查=新SpamChecker(客户美元,'中的');++ $ this - > expectException (\ RuntimeException::类);+ $ this - > expectExceptionMessage('无法检查垃圾邮件:无效(无效键)。”);+ $检查器- > getSpamScore(评论,上下文美元);}}
的MockHttpClient
类可以模拟任何HTTP服务器。需要的数组MockResponse
实例包含预期的身体和响应头。
然后,我们所说的getSpamScore ()
方法和检查通过的是抛出一个异常expectException ()
PHPUnit)的方法。
他们通过运行测试来检查:
1
美元ob娱乐下载symfony php bin / phpunit)
让我们为愉快路径添加测试:
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
- - - /测试/ SpamCheckerTest.php+ + + b /测试/ SpamCheckerTest.php@@ -24、4 + 24、32 @@类SpamCheckerTest扩展TestCase $ this - > expectExceptionMessage(“无法检查垃圾邮件:无效(无效键)。”);$检查器- > getSpamScore(评论,上下文美元);}++ / * *+ * @dataProvider provideComments+ * /+公共职能testSpamScore (int expectedScore美元,美元ResponseInterface响应,评论评论,美元数组$上下文)+ {+ $客户=新MockHttpClient([$响应]);+ $检查=新SpamChecker(客户美元,'中的');++ $得分= $检查器- > getSpamScore(评论,上下文美元);+ $ this - > assertSame (expectedScore美元,美元的分数);+}++公共静态函数provideComments (): iterable+ {+ $ = new评论评论();+ $评论- > setCreatedAtValue ();+ $上下文= [];++ $ = new MockResponse (“[' response_headers ' = > [x-akismet-pro-tip:丢弃的]]);+“blatant_spam”= >[2,反应,美元美元评论,美元背景);++ $响应=新MockResponse(“真正的”);+“垃圾邮件”= >[1美元反应评论美元,美元背景);++ $响应=新MockResponse('错误');+“火腿”= >[0,反应,美元评论,美元背景);+}}
PHPUnit)数据提供者允许我们重用相同的测试逻辑几个测试用例。
编写功能测试控制器
测试控制器有点不同于测试一个“普通”的PHP类我们要一个HTTP请求的上下文中运行它们。
为会议控制器创建一个功能测试:
使用ob娱乐下载
而不是PHPUnit) \ \ TestCase的框架
作为一个基类对我们的测试给了我们一个很好的抽象功能测试。
的美元的客户
变量模拟浏览器。而不是使HTTP调用服务器,它直接调用Symfony应用程序。ob娱乐下载这种策略有几个好处:它要快得多在客户机和服务器之间传输,但它也允许测试内省状态的每个HTTP请求后服务。
第一个测试检查主页返回一个200 HTTP响应。
断言等assertResponseIsSuccessful
添加PHPUnit)来减轻你的工作。有很多这样的断言定义的Symfony。ob娱乐下载
提示
我们使用/
生成的URL而不是通过路由器。这样做是故意测试终端用户的url是我们想要测试的一部分。如果你改变路由路径,测试将作为一个提醒,你应该将旧URL重定向到新的一个好的搜索引擎和网站链接回你的网站。
配置测试环境
默认情况下,PHPUnit)运行测试测试
ob娱乐下载Symfony环境PHPUnit)中定义的配置文件:
使测试工作,我们必须设置AKISMET_KEY
对于这个秘密测试
环境:
1
美元ob娱乐下载symfony控制台的秘密:集AKISMET_KEY——env =测试
使用一个测试数据库
正如我们已经看到的,Symfony CLI自动暴露了ob娱乐下载DATABASE_URL
环境变量。当APP_ENV
是测试
设置运行时PHPUnit)一样,数据库名称的变化应用程序
来app_test
所以,测试他们自己的数据库:
这很重要,因为我们需要一些稳定的数据来运行我们的测试,我们当然不希望覆盖我们存储在数据库开发。
在运行测试之前,我们需要“初始化”测试
数据库(创建数据库和迁移):
1 2
美元ob娱乐下载symfony控制台学说:数据库:创建- env =测试美元ob娱乐下载symfony控制台学说:迁移:迁移- n - env =测试
请注意
在Linux和类似操作系统,您可以使用APP_ENV =测试
而不是——env =测试
:
1
美元APP_ENV =测试ob娱乐下载symfony控制台学说:数据库:创建
如果您现在运行测试,PHPUnit)不会与您的开发数据库交互了。只运行新测试,通过类路径的路径:
1
美元ob娱乐下载php bin / symfony /控制器/ ConferenceControllerTest.php phpunit)测试
提示
当一个测试失败,它可能是有用的内省的响应对象。通过访问它客户端- > getResponse美元()
和回声
看它是什么样子。
定义设备
能够测试评论列表、分页,表单提交,我们需要用一些数据来填充数据库。和我们想要的数据是相同的测试,使测试通过。装置正是我们需要的。
安装原则fixture包:
1
美元ob娱乐下载symfony作曲家点播orm-fixtures - dev
一个新的src / DataFixtures /
目录在安装期间创建了一个示例类,可以定制。现在添加两个会议,一个评论:
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
- - - / src / DataFixtures / AppFixtures.php+ + + b / src / DataFixtures / AppFixtures.php@@ 2,6 + 2,8 @@名称空间的应用程序\ DataFixtures;+使用App \实体\评论;+使用App \实体\会议;使用原则\包\ FixturesBundle \夹具;使用原则\ \ ObjectManager持久性;8 + @@ 9日11日24 @@类AppFixtures延伸夹具{公共函数加载(ObjectManager经理美元):{无效——/ / $产品=新产品();——/ / $经理- >保存(产品);+ $阿姆斯特丹=新的会议();+ $阿姆斯特丹- > setCity(阿姆斯特丹);+ $阿姆斯特丹- > setYear (' 2019 ');+ $阿姆斯特丹- > setIsInternational(真正的);+ $经理- >保存(阿姆斯特丹);++ $巴黎=新的会议();+ $巴黎- > setCity(巴黎);+ $巴黎- > setYear (' 2020 ');+ $巴黎- > setIsInternational(假);+ $经理- >保存(巴黎);++ $ comment1 =新的评论();+ $ comment1 - > setConference阿姆斯特丹($);+ $ comment1 - > setAuthor(“法”);+ $ comment1 - > setEmail (fabien@example.com);+ $ comment1 - > setText(“这是一个伟大的会议。”);+ $经理- >保存($ comment1);$经理- >冲洗();}
当我们将加载装置,所有数据将被删除;包括管理用户。为了避免这种情况,让我们添加管理用户的设备:
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
- - - / src / DataFixtures / AppFixtures.php+ + + b / src / DataFixtures / AppFixtures.php20 @@ @@ 2 13 + 2名称空间的应用程序\ DataFixtures;+使用App \实体\管理;使用App \实体\评论;使用App \实体\会议;使用原则\包\ FixturesBundle \夹具;使用原则\ \ ObjectManager持久性;+使用Syob娱乐下载mfony \组件\ PasswordHasher \切肉机\ PasswordHasherFactoryInterface;类AppFixtures延伸夹具{+公共职能__construct (+私人PasswordHasherFactoryInterface passwordHasherFactory美元,+){+}+公共函数加载(ObjectManager经理美元):空白{$阿姆斯特丹=新的会议();@@ -30 6 + 37 12 @@类AppFixtures延伸夹具$ comment1 - > setText(“这是一个伟大的会议。”);(管理器- >坚持美元comment1);+ $管理= admin ();+ $管理- > setRoles ([' ROLE_ADMIN ']);+ $管理- > setUsername(管理);+ $管理- >向setPassword ($ this - > passwordHasherFactory - > getPasswordHasher (admin::类)- >哈希('管理'));+ $经理- >保存(管理);+$经理- >冲洗();}}
提示
如果你不记得哪些服务需要使用对于一个给定的任务,使用调试:自动装配
有一些关键字:
1
美元ob娱乐下载symfony控制台调试:自动装配侍者
爬行网站的功能测试
正如我们所看到的,HTTP客户端使用的测试模拟一个浏览器,可以浏览网站上如果我们使用一个无头的浏览器。
会议上添加一个新的测试,点击页面的主页:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
- - - /测试/控制器/ ConferenceControllerTest.php+ + + b /测试/控制器/ ConferenceControllerTest.php@@ -14,4 + 14、19 @@类ConferenceControllerTest延伸WebTestCase $ this - > assertResponseIsSuccessful ();$ this - > assertSelectorTextContains (h2,给你反馈);}++公共testConferencePage()函数+ {+ $客户=静态:createClient ();+ $履带= $客户- >请求(‘得到’,‘/’);++ $ this - > assertCount(2 $履带- >过滤器(h4));++ $客户- > clickLink(“视图”);++ $ this - > assertPageTitleContains(阿姆斯特丹);+ $ this - > assertResponseIsSuccessful ();+ $ this - > assertSelectorTextContains (h2,阿姆斯特丹2019);+ $ this - > assertSelectorExists (“div:包含(“有1评论”));+}}
让我们描述发生了什么在这个测试用浅显的英语:
- 像第一个测试中,我们去主页;
- 的
请求()
方法返回一个履带
实例,帮助找到页面元素(比如链接形式,或任何你可以达到与CSS选择器或XPath); - 多亏了一个CSS选择器,我们断言,我们有两个会议在主页上市;
- 然后点击“查看”链接(如不能一次点击多个链接,Symfony会自动选择第一个找到);ob娱乐下载
- 我们认为页面标题、响应和页面
< h2 >
可以肯定的是我们正确的页面上(我们也可以检查路线相匹配); - 最后,我们断言,有1评论页面。
div:包含()
不是一个有效的CSS选择器,但Symfony一些不错的添加,借用了ob娱乐下载jQuery。
而不是点击文本(即。视图
),我们可以选择链接通过一个CSS选择器:
1
美元客户端- >点击(美元履带- >过滤器(“h4 + p”)- >链接());
检查新的测试是绿色:
1
美元ob娱乐下载php bin / symfony /控制器/ ConferenceControllerTest.php phpunit)测试
提交表单的功能测试
你想要更上一层楼吗?尝试添加新评论的会议上照片测试通过模拟一个表单提交。这看起来雄心勃勃,不是吗?看看需要代码:没有更复杂的比我们已经写道:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
- - - /测试/控制器/ ConferenceControllerTest.php+ + + b /测试/控制器/ ConferenceControllerTest.php@@ -29,4 + 29日19 @@类ConferenceControllerTest延伸WebTestCase $ this - > assertSelectorTextContains (h2,阿姆斯特丹2019);$ this - > assertSelectorExists (“div:包含(“有1评论”));}++公共testCommentSubmission()函数+ {+ $客户=静态:createClient ();+ $客户- >请求(‘得到’,' /会议/阿姆斯特丹- 2019 ');+ $客户- > submitForm(“提交”,(作者)+ ' comment_form ' = > '法',+ ' comment_form[文本]' = > '一些反馈一个自动化的功能测试,(电子邮件)+ ' comment_form ' = >“me@automat.ed”,+ ' comment_form[图片]' = >目录名(__DIR__, 2)。“/公共/图片/ under-construction.gif”,+));+ $ this - > assertResponseRedirects ();+ $客户- > followRedirect ();+ $ this - > assertSelectorExists (“div:包含(有两个评论)');+}}
通过提交表单submitForm ()
,由于浏览器DevTools找到输入的名字或通过Symfony分析器形式面板。ob娱乐下载注意施工形象的聪明的重用!
再次运行测试,检查一切都是绿色的:
1
美元ob娱乐下载php bin / symfony /控制器/ ConferenceControllerTest.php phpunit)测试
如果你想在浏览器中检查结果,停止Web服务器并重新运行它测试
环境:
1 2
美元ob娱乐下载symfony服务器:停止美元APP_ENV =测试ob娱乐下载symfony服务器:开始- d
重载设备
如果你第二次运行测试,他们应该失败。现在有更多的言论在数据库中,断言检查评论的数量打破了。我们需要重置数据库之间的状态由重载设备每次运行前:
1 2
美元ob娱乐下载symfony控制台学说:夹具:负载——env =测试美元ob娱乐下载php bin / symfony /控制器/ ConferenceControllerTest.php phpunit)测试
Makefile的自动化工作流程
必须记住一系列命令来运行测试是烦人。这至少应该被记录下来。但是文档欧宝官网下载app应该是最后一招。相反,自动化日常活动呢?这将作为文档,帮助其他开发人员发现,让开欧宝官网下载app发人员的生活更加容易和快速。
使用一个Makefile
是一种自动化命令:
警告
在Makefile规则,缩进必须由一个制表符,而不是空间。
注意- n
国旗条令司令部;它是一个全球性的国旗在Symfony命令,让他ob娱乐下载们非互动。
每当你想要运行测试,使用做测试
:
1
美元做测试
每个测试后重置数据库
重置数据库在每次测试运行很好,但在真正的独立测试就更好了。我们不想要一个测试依赖以往的结果。改变测试的顺序不能改变结果。现在我们要弄清楚,这并非如此。
移动testConferencePage
测试后,testCommentSubmission
一:
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
- - - /测试/控制器/ ConferenceControllerTest.php+ + + b /测试/控制器/ ConferenceControllerTest.php@@ -15 21 + 15 6 @@类ConferenceControllerTest延伸WebTestCase $ this - > assertSelectorTextContains (h2,给你反馈);}——公共testConferencePage()函数——{-客户=静态:美元:createClient ();-履带=美元客户- >请求(‘得到’,‘/’);- - - - - -- $ this - > assertCount(2 $履带- >过滤器(h4));- - - - - --客户- > clickLink(“视图”);- - - - - -- $ this - > assertPageTitleContains(阿姆斯特丹);- $ this - > assertResponseIsSuccessful ();- $ this - > assertSelectorTextContains (h2,阿姆斯特丹2019);- $ this - > assertSelectorExists (“div:包含(“有1评论”)');- - - - - -}- - - - - -公共函数testCommentSubmission(){$客户=静态:createClient ();@@ -44,4 + 29日19 @@类ConferenceControllerTest延伸WebTestCase $客户- > followRedirect ();$ this - > assertSelectorExists (“div:包含(有两个评论)');}++公共testConferencePage()函数+ {+ $客户=静态:createClient ();+ $履带= $客户- >请求(‘得到’,‘/’);++ $ this - > assertCount(2 $履带- >过滤器(h4));++ $客户- > clickLink(“视图”);++ $ this - > assertPageTitleContains(阿姆斯特丹);+ $ this - > assertResponseIsSuccessful ();+ $ this - > assertSelectorTextContains (h2,阿姆斯特丹2019);+ $ this - > assertSelectorExists (“div:包含(“有1评论”));+}}
现在测试失败。
重置数据库之间测试,安装DoctrineTestBundle:
1
美元ob娱乐下载symfony作曲家配置extra.symfony.allow-contrib真正的
1
美元ob娱乐下载symfony作曲家要求“dama / doctrine-test-bundle: ^ 6”——开发
你需要确认配方的执行(因为它不是一个“正式”支持包):
1 2 3 4 5 6 7 8 9 10 11
ob娱乐下载Symfony操作:1配方(a5c79a9ff21bc3ae26d9bb25f1262ed7)——警告dama / doctrine-test-bundle(> = 4.0):从github.com/symfony/recipes-contrib:master这个包的秘诀来自“contrib”存储库,这是社区的贡献。欧宝体育平台怎么样检查配方在https://github.com/symfony/recipes-ob娱乐下载contrib/tree/master/dama/doctrine-test-bundle/4.0上你想执行这个配方吗?[y]是[n]不是[a]是的所有包,只有当前安装的会话[p]是永久的,不会又问这个项目(默认为n): p
启用PHPUnit)监听器:
1 2 3 4 5 6 7 8 9 10 11 12 13
- - - a / phpunit.xml.dist+ + + b / phpunit.xml.dist10 @@ @@ -29年6 + 29日< /包括> < /覆盖>+ <扩展>+ <扩展类= " DAMA \ DoctrineTestBundle \ PHPUnit) \ PHPUnitExtension " / >+ < /扩展>+<听众> <侦听器类= "桥Symfony \ \ Phpob娱乐下载Unit) \ SymfonyTestsListener " / > < /听众>
和完成。现在做任何更改测试每个测试结束时自动回滚。
测试应该是绿色:
1
美元做测试
使用一个真正的浏览器功能测试
功能测试使用一个特殊的浏览器直接调用Symfony层。ob娱乐下载但是你也可以使用一个真正的浏览器和HTTP层由于Symfony豹:ob娱乐下载
1
美元ob娱乐下载symfony作曲家点播豹- dev
然后您可以编写测试,使用一个真正的谷歌Chrome浏览器使用以下变化:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
- - - /测试/控制器/ ConferenceControllerTest.php+ + + b /测试/控制器/ ConferenceControllerTest.php13 @@ @@ 2 13 + 2名称空间应用\ \测试控制器;用Symfob娱乐下载ony \包\ FrameworkBundle \ \ WebTestCase测试;+使用Syob娱乐下载mfony \ \豹\ PantherTestCase组件;海尔集团ConferenceControllerTest WebTestCase延伸+类ConferenceControllerTest PantherTestCase延伸{公共职能testIndex () {-客户=静态:美元:createClient ();+ $客户=静态:createPantherClient ([' external_base_uri ' = > $ _SERVER [' SYMFob娱乐下载ONY_PROJECT_DEFAULT_ROUTE_URL ']]);$客户- >请求(‘得到’,‘/’);$ this - > assertResponseIsSuccessful ();
的ob娱乐下载SYMFONY_PROJECT_DEFAULT_ROUTE_URL
环境变量包含本地web服务器的URL。
选择正确的测试类型
我们已经创建了三个不同类型的测试。虽然我们只有使用制造商包生成单元测试类,我们可以使用它来生成另一个测试类:
1 2 3
美元ob娱乐下载symfony控制台:测试\ \ ConferenceController WebTestCase控制器美元ob娱乐下载symfony控制台:测试\ \ ConferenceController PantherTestCase控制器
制造商包支持生成以下类型的测试取决于你想测试您的应用程序:
TestCase
:基本PHPUnit)测试;KernelTestCase
:基本的测试,获得Symfony服务;ob娱乐下载WebTestCase
:运行浏览器的场景,但不执行JavaScript代码;ApiTestCase
:运行API-oriented场景;PantherTestCase
:使用一个real-browser e2e运行场景,或HTTP客户端和一个真正的web服务器。
运行与黑焰黑盒功能测试
另一种方法是使用运行功能测试黑焰的球员。除了你能做功能测试,它还可以执行性能测试。
读了性能一步了解更多信息。
要进一步
- 断言定义的Symfony的列表ob娱乐下载功能测试;
- PHPUnit)文档;
- 的摊贩图书馆生成实际的设备数据;
- 的CssSelector组件文档;
- 的ob娱乐下载Symfony豹库浏览器测试和web爬行在Symfony应用程序;ob娱乐下载
- 的使/ Makefile文件。