テストをする
テストをする
アプリケションにどんどん機能を追加し始めているので,テストにいて話す適切なタミングでしょう。
面白いことに,このチャプタ,でテストを書いている時に私はバグを見,けました。
欧宝娱乐app下载地址Symfonyは,PHPUnitを使ってユニットテストをしています。:
1
$欧宝娱乐app下载地址Symfony作曲家req phpunit—dev
ユニットテストを書く
SpamChecker
が,最初にテストを書くクラスです。ユニットテストを生成します:
1
$欧宝娱乐app下载地址Symfony控制台制作:测验TestCase SpamCheckerTest
SpamCheckerのテストでAkismet APIを叩かないようにするのは少々困難です。ここでは,Akismet APIをモックします。
APIがエラ,を返した際のテストを書いてみましょう:
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;+使用Sy欧宝娱乐app下载地址mfony \ \ HttpClient \ MockHttpClient组件;+使用Sy欧宝娱乐app下载地址mfony \组件\ HttpClient \ \ MockResponse反应;+使用Sy欧宝娱乐app下载地址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
クラスを使えば,HTTP服务器をモックすることができます。MockHttpClient
は,期待するボディとレスポンスヘッダ,を含んでいるMockResponse
ンスタンスの配列を取ります。
getSpamScore ()
メソッドを呼び出し,PHPUnitのexepectException ()
メソッドから例外が投げられたかチェックします。
テストを実行し,成功することを確認してください:
1
$欧宝娱乐app下载地址Symfony PHP bin/phpunit
正常系のテストを追加してください:
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];+}}
PHPUnit)のデータプロバイダーを使うと,複数のテストケースで同じテストのロジックを再利用することができます:
コントロ,ラ,のファンクショナルテストを書く
コントロ,ラ,のテストは一般的なPHPのクラスのテストとは少し異なります。コントロ,ラ,のテストでは,HTTPリクエストのコンテキスト内で実行する必要があるからです。
会议コントロ、ラ、のファンクショナルテストを作成してください:
PHPUnit) \ \ TestCase的框架
の代わりに欧宝娱乐app下载地址
を使うことにより,機能テストの便利な機能を利用することができます。
美元的客户
変数は,ブラウザをシミュレ,トします。サーバーへのHTTP呼び出しをするのではなく,Sy欧宝娱乐app下载地址mfonyアプリケーションを直接呼び出します。この方法を使うことの利点は次の通りです。クラアントとサバの間の往復をしないので処理が速くなることです。そして,各httpリクエストの後のサ,ビスの状態を調べるテストが可能になることです。
最初のテストは,ホ,ムペ,ジがHTTP响应が200を返すか調べることです。
PHPUnitのみならず,さらにassertResponseIsSuccessful
のようなアサ,ションを使うことで確認作業が楽になります。符号によって定義されたこういったアサ,ションはたくさんあります。
提示
ル,タ,から生成するのではなく,/
をurlとして使ってきました。エンドユ,ザ,のurlをテストとするため,故意にそうしていました。ル,トパスを変更すると,テストは失敗するようになります。そして,失敗することが,サーチエンジンやWebサイトにリンクがあった際に,古いURLを新しいURLにリダイレクトさせるようにするべきということに気づくリマンドになります。
テスト環境を設定する
デフォルトでは,PHPUnitテストはPHPUnitの設定ファルに設定されている通り,测验
という欧宝娱乐app下载地址Symfony環境で実行されます:
テストを動かすために,この测验
環境のためのAKISMET_KEY
を設定する必要があります:
1
$欧宝娱乐app下载地址Symfony控制台的秘密:集AKISMET_KEY——env =测验
テストデ,タベ,スを使う
既に見たように,欧宝娱乐app下载地址Symfony CLIは自動的にDATABASE_URL
環境変数を読み取ります。APP_ENV
が测验
のとき(PHPUnit実行時に指定したときのように),欧宝娱乐app下载地址Symfony CLIはデタベス名を主要
からmain_test
に変更して,テストが専用のデ,タベ,スを使えるようにします。
テストを実行するために安定したデータが必要であり,また,当然開発用データベースに保存したデータを上書きしないようにするため,環境によるデータベース名の変更は重要なのです。
テストを実行する前に,测验
データベースを”初期化”する(つまり,データベースを作成して,マイグレーションする)必要があります:
1 2
$欧宝娱乐app下载地址Symfony控制台原则:database:create——env=测验$欧宝娱乐app下载地址Symfony控制台原则:迁移:migrate -n——env=测验
请注意
在Linux和类似的操作系统上,您可以使用APP_ENV =测试
而不是——env =测试
:
1
$APP_ENV =测验欧宝娱乐app下载地址Symfony控制台原则:数据库:创建
これ以降テストを実行すると,PHPUnitはもう開発用デ,タベ,スを使わなくなりました。新しいテストだけを実行するには,コマンド引数としてクラスパスを渡します:
1
$欧宝娱乐app下载地址symfony php bin/phpunit tests/Controller/ConferenceControllerTest.php
提示
テストが失敗した際は,レスポンスオブジェクトを調べると良いです。客户端- > getResponse ()
でレスポンスオブジェクトを取得し回声
してどうなっているか確認してください。
フィクスチャを定義する
コメントの一覧,ページネーション,フォーム投稿のテストをするには,データをデータベースへ投入する必要があります。そして,テスト実行の間同じデ,タにしておきたいです。このニ,ズを満たしてくれるフィクスチャの出番です。
Doctrine Fixture bundleを:
1
$欧宝娱乐app下载地址Symfony作曲家需要orm-fixture—dev
ンスト,ルすると,src / DataFixtures /
ディレクトリとサンプルクラスが作成されますので,カスタマ。ここでは,カンファレンスを2,コメントを1追加します:
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);经理- >冲洗();}
フィクスチャをロ,ドすると,管理者ユ,ザ,も含め,全てのデ,タは削除されます。フィクスチャに管理者ユ,ザ,も追加しておきましょう:
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持久性;+使用Sy欧宝娱乐app下载地址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::类)- >哈希('管理'));+ $经理- >保存(管理);+经理- >冲洗();}}
提示
実行しようとするタスクで,どのサ,ビスが必要か覚えていないときは,キ,ワ,ドと调试:自动装配
で確認してください:
1
$欧宝娱乐app下载地址Symfony控制台调试:自动装配散列器
ファンクショナルテスト内でWebサトをクロルする
これまで見てきたように,テストで使用するHTTPクライアントは,ブラウザをシミュレートしますので,ヘッドレスブラウザを使っているかのようにWebサイトをナビゲートすることができます。
ホ,ムペ,ジから特定のカンファレンスペ,ジをクリックするテストを新しく追加してください:
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个注释")');+}}
このテストで何が行われたかを説明しましょう:
- 最初のテストのようにホ,ムペ,ジを開きます;
请求()
メソッドは,ページ内の要素(リンクやフォームなどCSSセレクターやXPathで探せるもの全て)を探すのに便利な履带
ンスタンスを返します;- CSSセレクターを使って,ホームページにカンファレンスが2つ表示されているのを確認することができます;
- そして,“视图”リンクをクリックします(同時に複数のリンクをクリックできないので,Symfo欧宝娱乐app下载地址nyは最初に見つけたリンクを選択します);
- ペジタトル,レスポンス,ペジの
< h2 >
が正しいペ,ジのものであるかアサ,トします(ル,トがマッチするかも確認することができます); - 最後に,ペ,ジにコメントが1あることをアサ,トします。
div:包含()
は、CSSセレクターとしては無効ですが,S欧宝娱乐app下载地址ymfonyにはjQueryの機能から一部持ってきた便利な追加機能があります。
テキスト(すなわ视图
)をクリックしなくても,cssセレクタ,を使ってリンクを選択することもできます:
1
$客户端->点击($履带->过滤器('h4 + p a')->链接());
新しいテストが通ることを確認してください:
1
$欧宝娱乐app下载地址symfony php bin/phpunit tests/Controller/ConferenceControllerTest.php
ファンクショナルテストでフォ,ムを投稿する
フォ,ムの投稿をシミュレ,トしてカンファレンスに写真付きのコメントを追加してみましょう。以下の必要なコ,ドを見てください。今までに書いたものと同じように複雑ではありません:
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个注释")');+}}
submitForm ()
でフォームをサブミットするのに,ブラウザの開発ツールもしくは,S欧宝娱乐app下载地址ymfonyのプロファイラパネルから输入の名前を見つけてください。工事中の▪メ▪ジが再利用されているのに気づきましたか?
テストをもう一度実行し,全てパスすることを確認してください:
1
$欧宝娱乐app下载地址symfony php bin/phpunit tests/Controller/ConferenceControllerTest.php
もし結果をブラウザで見たければ,一度Webサ,バ,を停止して,测验
環境で実行し直してください:
1 2
$欧宝娱乐app下载地址symfony服务器:停止$APP_ENV =测验欧宝娱乐app下载地址Symfony服务器:start -d
フィクスチャをリロ,ドする
テストをもう一度走らせると,テストは失敗します。それは,データベースにコメントが追加されたからで,コメントの数を調べるアサーションが壊れてしまっているからです。テスト実行の前にフィクスチャをリロードして,テスト実行毎にデータベースの状態をリセットする必要があります:
1 2
$欧宝娱乐app下载地址Symfony控制台原则:fixture:load——env=测验$欧宝娱乐app下载地址symfony php bin/phpunit tests/Controller/ConferenceControllerTest.php
Makefileを使ってワ,クフロ,を自動化する
テスト実行のコマンドの順番を覚えておく必要があるのは,面倒ですね。少なくともドキュメント化しておいて欲しいですが,ドキュメントは最後の手段ですので別の方法を考えましょう。毎日のアクティビティを自動化することでドキュメントとしても役立ます。こうすることで,他の開発者が見けやすくなったり,助けになります。
コマンドを自動化する方法の1として,Makefile
を使用します:
警告
Makefileの規則により,etc / etc / etc / etc / etc / etc / etc / etc / etc / etc / etc必要があります。
教义コマンドには,- n
フラグが付いています。これは,欧宝娱乐app下载地址Symfonyコマンドのグロ,バルなフラグで,etc .ンタラクティブにならないようにします。
テストを実行したいときは,做测试
を使用してください:
1
$做测试
各テストの後にデ,タベ,スをリセットする
各テストを実行した後にデータベースをリセットするのは便利ですが,テストの依存を無くす方がベターです。前のテストの結果に次のテストを依存させるといったことはしたくはありません。テストの順番を変更しても結果は同じであるべきです。今のところは問題となっていませんが,ここで見てみましょう。
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个注释")');+}}
テストは失敗するようになりました。
テスト間でデータベースをリセットするには,DoctrineTestBundleをインストールしてください:
1
$欧宝娱乐app下载地址Symfony作曲家配置extra.symfony.allow-contrib真正的
1
$欧宝娱乐app下载地址交响乐作曲家要求“dama / doctrine-test-bundle: ^ 6”——开发
DoctrineTestBundleは,”公式に”サポートされたバンドルではないので,レシピの実行を確認する必要があります:
1 2 3 4 5 6 7 8 9 10 11
欧宝娱乐app下载地址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-cont欧宝娱乐app下载地址rib/tree/master/dama/doctrine-test-bundle/4.0上查看食谱,你想要执行这个食谱吗?[y]是[n]否[a]对所有包都是,仅对当前安装会话是[p]永久是,永远不再要求此项目(默认为n): p
PHPUnitリスナ,を有効化してください:
12 3 4 5 6 7 8 9 10 11 12 13
——/ phpunit.xml.dist+ + + b / phpunit.xml.dist@@ -29,6 +29,10 @@< /包括> < / >报道+ <扩展>+ + < /扩展>+ .
これで準備ができました。テストに変更があると,自動的に各テストの最後にロ,ルバックするようになりました。
テストは再びグリ,ンになったはずです:
1
$做测试
実際のブラウザを使用して,ファンクショナルテストをする
ファンクショナルテストは,欧宝娱乐app下载地址Symfonyを直接呼び出す特別なブラウザを使用しています。しかし,欧宝娱乐app下载地址Symfony豹を使えば,実際のブラウザとHTTPを使うことが可能です:
1
$欧宝娱乐app下载地址Symfony作曲家req panther—dev
次の変更を,谷歌Chromeのブラウザを使用してテストを書くことができます:
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 @@名称空间应用\ \测试控制器;用Symf欧宝娱乐app下载地址ony \包\ FrameworkBundle \ \ WebTestCase测试;+使用Sy欧宝娱乐app下载地址mfony \ \豹\ PantherTestCase组件;-class ConferenceControllerTest扩展WebTestCase+类ConferenceControllerTest扩展PantherTestCase{公共函数testIndex() {- $client = static::createClient();+ $client = static::createPantherClient(['external_base_uri' => $_SERVER['欧宝娱乐app下载地址SYMFONY_PROJECT_DEFAULT_ROUTE_URL']]);客户端- >请求(‘得到’,‘/’);$ this - > assertResponseIsSuccessful ();
環境変数的S欧宝娱乐app下载地址YMFONY_PROJECT_DEFAULT_ROUTE_URLには,ローカルのWebサーバーのURLが入っています。
適切なテストタ@ @プを選ぶ
ここまで,3の異なるタプのテストを作りました。ユニットテスト用のクラスを作るときだけMakerBundleを使っていましたが,他のテストクラスを作るときにも利用できます:
1 2 3
$欧宝娱乐app下载地址Symfony控制台制作:测验\ \ ConferenceController WebTestCase控制器$欧宝娱乐app下载地址Symfony控制台制作:测验\ \ ConferenceController PantherTestCase控制器
アプリケーションをどのようにテストしたいのかによって,MakerBundleは次のタイプのテストクラス作成に対応しています:
TestCase
:基本的なPHPUnitのテストクラスKernelTestCase
: 欧宝娱乐app下载地址Symfonyサ,ビスにアクセスする基本的なテストクラスWebTestCase
: JavaScriptのコ,ドを実行しないときのブラウザのようなシナリオ用テストクラス。ApiTestCase
: api向けのシナリオ用テストクラスPantherTestCase
: e2eシナリオ用テストクラス。本物のブラウザまたはhttpクラアントと本物のウェブサバを使います。
Blackfireでブラックボックスなファンクショナルテストを実行する
黑焰的球员を使ってファンクショナルテストを実行することもできます。そうすれば,ファンクショナルテストに加えて,パフォ,マンステストもすることができます。
詳細を知るには,性能を参照してください。
より深く学ぶために
- 欧宝娱乐app下载地址Symfonyに定義されているアサ,ションのリストファンクショナルテスト用;
- PHPUnitドキュメント;
- リアルなフィクスチャデ,タを生成するFakerラブラリ;
- CssSelectorコンポ,ネントのドキュメント;
- 欧宝娱乐app下载地址SymfonyアプリケションでブラウザでテストやWebクロルを行うラブラリ欧宝娱乐app下载地址Symfony豹;
- Make/Makefileドキュメント