Testen
Testen
大的修女和大的Funktionalität在die Anwendung einbauen, ist jetzt wahrscheinlich der richtige Zeitpunkt um über das Testen zu sprechen。
有趣的事实:我有机会在我的世界里接受试验。
ob娱乐下载Symfony setzt bei Unit-Tests auf PHPUnit。Lass es uns安装:
1
$ob娱乐下载Symfony作曲家req phpunit—dev
单元测试写作
SpamChecker
ist die erste klase, für die wir Tests schreiben werden。单元测试:
1
$ob娱乐下载Symfony控制台制作:测验TestCase SpamCheckerTest
《垃圾邮件检查者测试手册》ständig aufrufen wollen。我们会死的乔汉纳(simulieren)。
Lasse uns einen ersten Test für den Fall schreiben, dass die API einen Fehler zurückgibt:
12 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(): void+公共函数testSpamScoreWithInvalidRequest(): void{- $ this - > assertTrue(真正的);+ $comment = new comment ();+ $评论- > setCreatedAtValue ();+ $context = [];++ $client = new MockHttpClient([new MockResponse('invalid', ['response_headers' => ['x-akismet-debug-help: invalid key']])]);+ $checker = new SpamChecker($client, 'abcde');++ $ this - > expectException (\ RuntimeException::类);+ $this->expectExceptionMessage('无法检查垃圾邮件:无效(无效键).');+ $checker->getSpamScore($comment, $context);}}
死MockHttpClient
-Klasse ermöglicht es, jeden beliebigen HTTP-Server zu simulieren。他是一个奇怪的人MockResponse
-Instanzen benötigen, die den erwarteten Body和die Response-Header enthten。
Anschließend rufen wir diegetSpamScore ()
-Methode auf und überprüfen, mit Hilfe derexpectException ()
-Methode von PHPUnit, ob eine Ausnahme ausgelöst wid。
Führe die Tests aus, um sicherzustellen, dass sie erfolgreich sind:
1
$ob娱乐下载Symfony PHP bin/phpunit
最后的uns测试für den快乐的路径hinzufügen:
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
——/测试/ SpamCheckerTest.php+ + + b /测试/ SpamCheckerTest.php@@ -24,4 +24,32 @@类SpamCheckerTest扩展TestCase $this->expectExceptionMessage('无法检查垃圾邮件:无效(无效键).');检查器- > getSpamScore(评论,上下文美元);}++ / * *+ * @dataProvider提供+ * /+公共函数testSpamScore(int $expectedScore, ResponseInterface $response, Comment $ Comment, array $context)+ {+ $client =新的MockHttpClient([$response]);+ $checker = new SpamChecker($client, 'abcde');++ $score = $checker->getSpamScore($comment, $context);+ $this->assertSame($expectedScore, $score);+}++公共静态函数provideComments(): iterable+ {+ $comment = new comment ();+ $评论- > setCreatedAtValue ();+ $context = [];++ $response = new MockResponse(", ['response_headers' => ['x-akismet-pro-tip: discard']]);+ yield 'blatant_spam' => [2, $response, $comment, $context];++ $response =新的MockResponse('true');+ yield 'spam' => [1, $response, $comment, $context];++ $response =新的MockResponse('false');+ yield 'ham' => [0, $response, $comment, $context];+}}
Der PHPUnit数据提供程序ermöglicht es uns, die gleiche Testlogik für mehere Testfälle wiederzuverwenden。
Funktionale测试für控制器schreiben
Das Testen von controller ist etwas anders als Das Testen einer "normalen" PHP-Klasse, da wir sie im Rahmen einer HTTP-Anfrage ausführen wollen。
Erstelle einen funktionalen Test für den会议控制器:
我们要是ob娱乐下载
anstelle冯PHPUnit) \ \ TestCase的框架
als基础- klasse für unsere测试nutzen, haben wir eine gute抽象für unsere Funktionalen测试。
死美元的客户
-变量simuliert einen Browser。Anstatt jedoch HTTP-Anfragen an den Server zu senden, ruft dieser die ob娱乐下载Symfony-Anwendung direkt auf。Dieses Vorgehen hat mehere Vorteile: Es ist viel schneller als eine tatsächliche Kommunikation zwischen Client and Server, und sie ermöglicht Es auch, in den Tests den Zustand der Services nach jedem HTTP-Request zu überprüfen。
diesel erste Test prüft, ob die首页eine HTTP-Response mit Status 200 zurückgibt。
断言是不是assertResponseIsSuccessful
werden zusätzlich zu PHPUnit hinzugefügt,嗯Dir die Arbeit zu erleichtern。ob娱乐下载Symfony stellt viele solcher断言zur Verfügung。
提示
我们有/
修复als URL verwendet, anstatt sie über den Router zu generieren。Dies geschieht absichtlich, da das Testen von produktiv - url Teil dessen ist,是wir Testen wollen。Sobald Du den Routenpfad änderst, werden die Tests fehlschlagen and diich dadurch freundlich daran erinner, dass Du die alte URL wahrscheinlich auf die neue umleiten solltest,嗯gegenüber Suchmaschinen and sites, die auf Deine Website verweisen, net zu sein。
配置测试- umgebung
Standardmäßig werden PHPUnit-Tests in der测验
ob娱乐下载Symfony-Umgebung ausgefuhrt。Das ist in der phpunit - konfigations - datei festgelegt:
Damit Tests funktionieren, müssen wir dasAKISMET_KEY
-秘密für diese Umgebung festlegen:
1
$ob娱乐下载Symfony控制台的秘密:集AKISMET_KEY——env =测验
麻省理工测试银行arbeiten
Wie wir schon eher gesehen haben, stellt die ob娱乐下载Symfony CLI automatisch dieDATABASE_URL
-Environment-Variable (Umgebungsvariable) bereit。Genauso als wenn PHPUnit ausgeführt wurde und verändert damit den Datenbank-Namen von主要
祖茂堂main_test
,因此dass die测试ihre特征Datenbank haben:
Das ist sehr wicichtig, weil wir wir稳定Daten brauchen um unsere测试auszuführen, und wir sicherlich niht die Daten in unserer Development-Datenbank überschreiben wollen。
Bevor wir unsere测试ausführen können, müssen wir die测验
-Datenbank "initialisieren" (Datenbank erstellen und migrieren):
1 2
$ob娱乐下载Symfony控制台原则:database:create——env=测验$ob娱乐下载Symfony控制台原则:迁移:migrate -n——env=测验
请注意
在Linux和类似的操作系统上,您可以使用APP_ENV =测试
而不是——env =测试
:
1
$APP_ENV =测验ob娱乐下载Symfony控制台原则:数据库:创建
Wenn Du nun模具测试ausführst, wd PHPUnit nicht mehr mit Deiner Development-Datenbank kommunizieren。Um nur die neuen Tests auszuführen, füge den Pfad zu deren Klassenpfad hinzu:
1
$ob娱乐下载symfony php bin/phpunit tests/Controller/ConferenceControllerTest.php
提示
Wenn ein Test fehlschlägt, kann es sinvoll sein, sich das Response-Objekt anzusehen。Greife超级客户端- > getResponse ()
和回声
Darauf zu,嗯zu sehen, wie es aussieht。
夹具erstellen
Um die Kommentarliste, Pagination und die Formularübermittlung testen zu können, müssen wir die Datenbank mit Daten befüllen。Außerdem wollen wir, dass die Daten bei allen Testläufen identisch sind, damit die Tests erfolgreich durchlaufen。fixture sind genau das,是wir brauchen。
Installiere das Doctrine安装包:
1
$ob娱乐下载Symfony作曲家需要orm-fixture—dev
Während der安装wurde ein neuessrc / DataFixtures /
-那是我的梦想,那是我的梦想。Füge vorerst zwei Konferenzen and einen Kommentar hinzu:
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
——/ src / DataFixtures / AppFixtures.php+ + + b / src / DataFixtures / AppFixtures.php@@ -2,6 +2,8 @@名称空间的应用程序\ DataFixtures;+使用App \实体\评论;+使用App \实体\会议;使用原则\包\ FixturesBundle \夹具;使用原则\ \ ObjectManager持久性;@@ -9,8 +11,24 @@类AppFixtures扩展Fixture{公共函数加载(ObjectManager $manager):无效{- // $product = new product ();- // $manager->persist($product);+ $amsterdam =新会议();+ $阿姆斯特丹- > setCity(阿姆斯特丹);+ $阿姆斯特丹- > setYear (' 2019 ');+ $阿姆斯特丹- > setIsInternational(真正的);+ $经理- >保存(阿姆斯特丹);++ $paris = new Conference();+ $巴黎- > setCity(巴黎);+ $巴黎- > setYear (' 2020 ');+ $巴黎- > setIsInternational(假);+ $经理- >保存(巴黎);++ $comment1 = new Comment();+ $ comment1 - > setConference阿姆斯特丹($);+ $ comment1 - > setAuthor(“法”);+ $ comment1 - > setEmail (fabien@example.com);+ $comment1->setText('This was a great conference.');+ $经理- >保存($ comment1);经理- >冲洗();}
Wenn wir die Fixtures laden, werden alle Daten entfernt, einschließlich der Admin-User。Um das zu vermeiden, fügen wir den Admin-User den Fixtures hinzu:
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
——/ src / DataFixtures / AppFixtures.php+ + + b / src / DataFixtures / AppFixtures.php@@ -2,13 +2,20 @@名称空间的应用程序\ DataFixtures;+使用App \实体\管理;使用App \实体\评论;使用App \实体\会议;使用原则\包\ FixturesBundle \夹具;使用原则\ \ ObjectManager持久性;+使用Syob娱乐下载mfony \组件\ PasswordHasher \切肉机\ PasswordHasherFactoryInterface;类AppFixtures扩展Fixture {+公共函数__construct(+ private PasswordHasherFactoryInterface+) {+}+public function load(ObjectManager $manager): void {$amsterdam = new Conference();@@ -30,6 +37,12 @@类AppFixtures extends Fixture $comment1->setText('这是一个伟大的会议。');经理- >保存($ comment1);+ $admin = new admin ();+ $管理- > setRoles ([' ROLE_ADMIN ']);+ $管理- > setUsername(管理);+ $管理- >是不是setPassword ($ this - > passwordHasherFactory - > getPasswordHasher (admin::类)- >哈希('管理'));+ $经理- >保存(管理);+经理- >冲洗();}}
提示
瀑布都是美好的,美好的,美好的服务都für eine bestimmte Aufgabe verwenden must, verwende调试:自动装配
关键词:mit einem
1
$ob娱乐下载Symfony控制台调试:自动装配散列器
Eine网站在Funktionalen测试爬行
Wie wir gesehen haben, simliert der in den test verwendete HTTP-Client einen Browser, sodass wir durch die Website navigieren können, als würden wir einen无头浏览器verwenden。
Füge einen neuen Test hinzu, der von der首页ausf auf eine Konferenzseite klickt:
12 3 4 5 6 7 8 9 10 11 12 13 14 16 17 18 19 20 21 22
——/ /控制器/ ConferenceControllerTest.php测试+ + + b /测试/控制器/ ConferenceControllerTest.php@@ -14,4 +14,19 @@类ConferenceControllerTest扩展WebTestCase $this->assertResponseIsSuccessful();$this->assertSelectorTextContains('h2', '给你的反馈');}++公共函数testConferencePage()+ {+ $client = static::createClient();+ $crawler = $client->request('GET', '/');++ $this->assertCount(2, $爬虫->过滤器('h4'));++客户端- > clickLink(“视图”);++ $ this - > assertPageTitleContains(阿姆斯特丹);+ $ this - > assertResponseIsSuccessful ();+ $this->assertSelectorTextContains('h2', '阿姆斯特丹2019');+ $this->assertSelectorExists('div:contains("有1个注释")');+}}
Lasse uns in einfachen Worten beschreiben, was in diesem
- Wie beim ersten Test gehen wir auf die主页;
- 死
请求()
-Methode gibt eine履带
-Instanz zurück, die hilft, Elemente auf der Seite zu finden (wie Links, Formulare oder alles, was Du mit CSS-Selektoren oder XPath erreichen kannst); - Mit Hilfe eines CSS-Selektors prüfen wir, dass zwei Konferenzen auf der首页aufgelistet sind;
- Dann klicken wir auf den Link“View”(Syob娱乐下载mfony kann nicht mehr als einen Link gleichzeeitig anklicken, darum wählt es automatisch den ersten, den es findet);
- Wir testen den Seitentitel, die Response und die Seitenüberschrift
< h2 >
,嗯sicher zu gehen, dass wir auf der richtigen Seite sind (wir hätten auch die zugehörige Route überprüfen können); - Schließlich prüfen wir, dass es einen Kommentar auf der Seite gibt。
div:包含()
ist zwar kein gültiger CSS-Selektor, ob娱乐下载Symfony hat sich jedoch einige nützliche Ergänzungen von jQuery abgeschaut。
原文原文;视图
), hätten wir den Link auch über einen CSS-Selektor auswählen können:
1
$客户端->点击($履带->过滤器('h4 + p a')->链接());
Überprüfe, ob der neue Test grün ist:
1
$ob娱乐下载symfony php bin/phpunit tests/Controller/ConferenceControllerTest.php
einem Funktionalen测试中的公式
Möchtest杜达斯nächste级erreichen?Versuche, einen neuen Kommentar mit einem Foto auf einer Konferenz auseinem Test heraus hinzuzufügen, indem Du das Abschicken eines Formulares simerst。Das scheint ehrgeizig zu sein, niht wahr?Schaue Dir den benötigten Code an: nicht komplexer als das, was wir bereits geschrieben haben:
12 3 4 5 6 7 8 9 10 11 12 13 14 16 17 18 19 20 21 22
——/ /控制器/ ConferenceControllerTest.php测试+ + + b /测试/控制器/ ConferenceControllerTest.php@@ -29,4 +29,19 @@ class ConferenceControllerTest extends WebTestCase $this->assertSelectorTextContains('h2', 'Amsterdam 2019');$this->assertSelectorExists('div:contains("有1个注释")');}++公共函数testCommentSubmission()+ {+ $client = static::createClient();+ $client->request('GET', '/conference/amsterdam-2019');+ $client->submitForm('提交',[+ 'comment_form[author]' => 'Fabien',+ 'comment_form[text]' => '自动功能测试的一些反馈',+ 'comment_form[email]' => 'me@automat.ed',+ 'comment_form[photo]' => dirname(__DIR__, 2).'/public/images/under-construction.gif',+));+ $ this - > assertResponseRedirects ();+客户端- > followRedirect ();+ $this->assertSelectorExists('div:contains("有2个注释")');+}}
公式übersubmitForm ()
abzuschicken, kannst Du die Namen der Felder über die Browser-DevTools oder über den Formular-Tab des ob娱乐下载Symfony Profilers finden。“正在建设中”-Bildes!
Führe模具测试erneut durch,嗯sicherzustellen, dass alles grün ist:
1
$ob娱乐下载symfony php bin/phpunit tests/Controller/ConferenceControllerTest.php
Wenn Du das Ergebnis在einem浏览器überprüfen将,停止den Webserver和启动ihn noch einmal在der测验
-Umgebung:
1 2
$ob娱乐下载symfony服务器:停止$APP_ENV =测验ob娱乐下载Symfony服务器:start -d
装置满载
Wenn Du die Tests ein zweites Mal ausführst, sollten sie fehlschlagen。在Datenbank gibt, ist die Assertion, welche die Anzahl der Kommentare überprüft, nicht mehr korrekt。Wir müssen德国杜尔克劳夫(Durchlauf)德国达滕银行(Datenbank) zwischen jedem jedem Durchlauf neu laden:
1 2
$ob娱乐下载Symfony控制台原则:fixture:load——env=测验$ob娱乐下载symfony php bin/phpunit tests/Controller/ConferenceControllerTest.php
Deinen Workflow mit einem Makefile automatisieren
Es ist ärgerlich, sich eine Reihe von Befehlen merken zu müssen,嗯die Tests auszuführen。die sollte zumindest dokumentiert werden。Eine Dokumentation sollte jedoch nur der letzte Ausweg sein。德国自动化工业总产值täglichen Aktivitäten ?Das würde als Dokumentation dienen, anderen Entwickler* inenhelfen,你的entendecken和ihre的劳动,和beschleunigen。
我的生活是美好的Makefile
ist eine Möglichkeit, Befehle zu automatisieren:
警告
Nach einer Regel für Make-Dateien (Makefiles)吵架die Einrückung auseinem einzelnen Tabulator-Zeichen anstelle von Leerzeichen bestehen。
Beachte das- n
- Befehls教义旗帜;全球之旗für世界之旗,世界之旗。ob娱乐下载
万恩immer Du die Tests ausführen möchtest, verwende做测试
:
1
$做测试
Die Datenbank nach jedem测试zurücksetzen
Das Zurücksetzen der Datenbank nach jedem Testlauf ist schön, aber wirklich unabhängige测试信得过。夜绒线,夜绒线测试stützt。Eine Änderung der Reihenfolge der Tests sollte das Ergebnis nicht verändern。他将在夜幕降临的瞬间死去。
Verschiebe窝testConferencePage
-测试线索testCommentSubmission
以及:
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 44
——/ /控制器/ ConferenceControllerTest.php测试+ + + b /测试/控制器/ ConferenceControllerTest.php@@ -15,21 +15,6 @@ class ConferenceControllerTest extends WebTestCase $this->assertSelectorTextContains('h2', '给出您的反馈');}-公共函数testConferencePage()——{- $client = static::createClient();- $crawler = $client->request('GET', '/');-- $this->assertCount(2, $爬虫->过滤器('h4'));--客户- > clickLink美元(“视图”);-- $ this - > assertPageTitleContains(阿姆斯特丹);- $ this - > assertResponseIsSuccessful ();- $this->assertSelectorTextContains('h2', '阿姆斯特丹2019');- $this->assertSelectorExists('div:contains("有1条评论")');- - - - - -}-公共函数testCommentSubmission() {$client = static::createClient();@@ -44,4 +29,19 @@ class ConferenceControllerTest extends WebTestCase $client->followRedirect();$this->assertSelectorExists('div:contains("有2个注释")');}++公共函数testConferencePage()+ {+ $client = static::createClient();+ $crawler = $client->request('GET', '/');++ $this->assertCount(2, $爬虫->过滤器('h4'));++客户端- > clickLink(“视图”);++ $ this - > assertPageTitleContains(阿姆斯特丹);+ $ this - > assertResponseIsSuccessful ();+ $this->assertSelectorTextContains('h2', '阿姆斯特丹2019');+ $this->assertSelectorExists('div:contains("有1个注释")');+}}
喷射schlagen模具测试fehl。
Installiere das DoctrineTestBundle, um die Datenbank zwischen den测试zurückzusetzen:
1
$ob娱乐下载Symfony作曲家配置extra.symfony.allow-contrib真正的
1
$ob娱乐下载交响乐作曲家要求“dama / doctrine-test-bundle: ^ 6”——开发
Du必须死Ausführung des Recipes bestätigen (da es sich nicht um ein“offiziell”unterstütztes捆绑handelt):
1 2 3 4 5 6 7 8 9 10 11
ob娱乐下载Symfony操作:1 recipe (a5c79a9ff21bc3ae26d9bb25f1262ed7) - WARNING dama/doctrin -test-bundle (>=4.0): From github.com/symfony/recipes-contrib:master此包的recipe来自“contrib”存储库,该存储库向社区开放。欧宝体育平台怎么样在https://github.com/symfony/recipes-contob娱乐下载rib/tree/master/dama/doctrine-test-bundle/4.0上查看食谱,你想要执行这个食谱吗?[y]是[n]否[a]对所有包都是,仅对当前安装会话是[p]永久是,永远不再要求此项目(默认为n): p
Aktiviere den PHPUnit-Listener:
12 3 4 5 6 7 8 9 10 11 12 13
——/ phpunit.xml.dist+ + + b / phpunit.xml.dist@@ -29,6 +29,10 @@< /包括> < / >报道+ <扩展>+ + < /扩展>+ .
和多数。Alle Änderungen,死在测试vorgenome werden, werden nun am Ende jedes测试automatisch zurückgesetzt。
模具测试solten wider grün盛:
1
$做测试
艾宁echten浏览器für Funktionale测试verwenden
Funktionale测试verwenden einen speziellen浏览器,der den Symfony-Layob娱乐下载er direckt aufruft。Aber Du kannst auch einen echten Browser und den echten HTTP-Layer dank ob娱乐下载Symfony Panther verwenden:
1
$ob娱乐下载Symfony作曲家req panther—dev
Du kannst dann测试schreiben, die einen echten谷歌chrome浏览器verwenden。大足benötigst杜die folgenden Änderungen:
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
——/ /控制器/ ConferenceControllerTest.php测试+ + + b /测试/控制器/ ConferenceControllerTest.php@@ -2,13 +2,13 @@名称空间应用\ \测试控制器;用Symfob娱乐下载ony \包\ FrameworkBundle \ \ WebTestCase测试;+使用Syob娱乐下载mfony \ \豹\ PantherTestCase组件;-class ConferenceControllerTest扩展WebTestCase+类ConferenceControllerTest扩展PantherTestCase{公共函数testIndex() {- $client = static::createClient();+ $client = static::createPantherClient(['external_base_uri' => $_SERVER['ob娱乐下载SYMFONY_PROJECT_DEFAULT_ROUTE_URL']]);客户端- >请求(‘得到’,‘/’);$ this - > assertResponseIsSuccessful ();
死的环境变量ob娱乐下载SYMFONY_PROJECT_DEFAULT_ROUTE_URL
enthält die URL des lokalen web服务器。
登richtigen测试类型wählen
Bisher haben wir drei verschiedene试验类型erstellt。Während wir das Maker-Bundle nur genutzt haben um Unit-Test-Klassen zu generieren, könnten wir es auch zur Generierung der anderen Test-Klassen nutzen:
1 2 3
$ob娱乐下载Symfony控制台制作:测验\ \ ConferenceController WebTestCase控制器$ob娱乐下载Symfony控制台制作:测验\ \ ConferenceController PantherTestCase控制器
Das Maker-Bundle unterstützt die Generierung der folgenden测试类型,abhängig davon wie Du Deine应用测试möchtest:
TestCase
:标准PHPUnit-Tests;KernelTestCase
:标准试验模具祖钢祖钢Symfony Diensten habob娱乐下载en;WebTestCase
: um浏览器-ähnliche Szenarios, aber ohne Javascript代码auszuführen;ApiTestCase
: für API-orientierte Szenarios;PantherTestCase
: für End-zu-End Szenarios;welche einen echten浏览器奥多http客户端和einen echten web服务器nutzen。
Funktionale“黑匣子”-测试mit Blackfire durchführen
Eine weitere Möglichkeit, Funktionale Tests durchzuführen, ist die Verwendung desBlackfire-Players.Zusätzlich zu dem,是Du mit Funktionalen测试machen kannst, kann der Blackfire-Player auch性能测试durchführen。
Schritt Schau Dir den Schritt über性能恩mehr zu erfahren。
Weiterfuhrendes
- 列出Symfony定义的断言ob娱乐下载für Funktionale测试;
- PHPUnit) Dokumentation;
- 死摊贩位于zur Erstellung现实主义装置;
- 死CssSelector组件文档;
- 死ob娱乐下载Symfony豹Bibliothek für Symfony-Anwendungen中的浏览器测试和网络爬行;ob娱乐下载
- 死使/ Makefile Dokumentation.