CodeceptionでPHPテストをすぐに開始
公開: 2022-03-11CodeceptionとPHPに移る前に、基本をカバーし、最初にアプリケーションでテストする必要がある理由を説明することから始める必要があります。 少なくとも今回は、テストに時間を無駄にすることなくプロジェクトを完了することができたのではないでしょうか。
もちろん、すべてをテストする必要はありません。 たとえば、さらに別のホームページを作成したい場合です。 プロジェクトに1つのルーターでリンクされた静的ページが含まれている場合は、おそらくテストは必要ありません。
ただし、次の場合は必ずテストする必要があります。
- チームはBDD/TDDを使用しています。
- Gitリポジトリには、2つ以上のコミットが含まれています。
- あなたは適切な専門家であり、深刻なプロジェクトに取り組んでいます。
専用のテスト部門、つまりテストを実施し、必要に応じて新しいテストを作成する人々のグループがすでにあると言って、言い訳をすることができます。 しかし、プロジェクトに新しい機能を追加してからバグ修正にかかる時間を想像できますか?
テストは何を解決しますか?
まず、テストによってどのような問題が解決されるかを判断しましょう。 テストですべてのエラーを取り除くことはできませんが、テストケースで予想される動作を説明することはできます。 エラーはテストケース内にある可能性があります。 テストケースを使用しても、スパゲッティコードはスパゲッティコードのままです。
ただし、後でコードが変更されることを確認できるため(エラーを修正するか、新しい機能を追加することにより)、テストで説明されているエラーがコードに含まれなくなります。 さらに、ドキュメントでは、一般的なシナリオがどのように展開され、期待される動作を確認できるかを確認できるため、適切に記述されたテストでさえ使用されることがあります。 テストは、将来的には小さいながらも重要な投資であると言えます。
では、どのようなテストを採用できるのでしょうか。
- 単体テスト:コードの小さな部分をチェックする低レベルのテスト-他のコードから分離されたクラスのメソッド。
- 統合テスト:統合テストはアプリケーションの一部をチェックします。複数のクラスまたはメソッドが含まれている場合がありますが、1つの機能に制限する必要があります。 このテストでは、さまざまなクラスがどのように相互作用しているかも確認する必要があります。
- 機能テスト:アプリケーションへの特定の要求(ブラウザーの応答、データベースの変更など)をテストします。
- 受け入れテスト:ほとんどの場合、受け入れテストとは、アプリケーションがすべてのクライアント要件を満たしているかどうかを確認することを意味します。
明確にするために、建物などの具体的なものでプロセスを説明するとします。 建物は、壁を形成する小さなブロックで構成されています。 各ブリックは、指定された要件を満たす必要があります。 必要な荷重に耐え、特定の体積と形状などを備えている必要があります。 これらは単体テストです。 統合テストの考え方は、レンガが互いにどれだけしっかりと正確に付着しているか、建物の特定の要素にどのように統合されているかを確認することです。 機能テストは、建物の1つの壁でのテスト、内部が要素から保護されているかどうか、窓から太陽が見えるかどうかのテストに例えることができます。 検収試験では、建物全体を完全な製品としてテストします。ドアを開け、中に入って、ドアを閉め、電気をつけ、2階に登って、建物の外の庭を見てください。
Codeceptionに会う
ただし、この分割は条件付きであり、異なる種類のテストを混合する誘惑に抵抗するのが難しい場合があります。
多くの開発者は単体テストを使用し、それで十分だと主張しています。 私はかつてそのような開発者の一人でした。 さまざまな種類のテストにさまざまなシステムを使用することは、非常に困難で時間がかかることがわかりました。 少し前に、PHPUnitよりも便利なものを見つけることにしました。 コードのテストを上手にしたかったのですが、大量のドキュメントを読んで学び、落とし穴を探したくありませんでした。 それが私がCodeceptionを発見した方法です。 最初は懐疑的でしたが(このプロジェクトは5年前なので、技術的には「新しい」とは言えません)、数日間遊んだ後です。 、Codeceptionは非常に便利で強力なシステムであると結論付けました。
では、Codeceptionをどのようにインストールしますか? それはそれが得るのと同じくらい簡単です:
$ composer require "codeception/codeception" $ php vendor/bin/codecept bootstrap
インストール後、プロジェクトにtestsという名前の新しいフォルダーがあり、acceptance、functional 、 unitという名前のサブフォルダーがいくつかあります。 テストを書き始めることができるようです。 かっこいいですが、次は何ですか?
ここで、標準の受け入れHelloWorldテストを追加してみてください。
$ php vendor/bin/codecept generate:cept acceptance HelloWorld
これで、次の内容の受け入れテストファイルtests / acceptance/HelloWorldCept.phpが取得されます。
<?php $I = new AcceptanceTester($scenario); $I->wantTo('perform actions and see result');
$I
という名前のデフォルト変数は、単なる文字ではありません。 キャラクターです。 何がテストを実施しますか? テスター、明らかに。 このテスターは、Webサイトのページまたはクラスを開き、それを使用して何かを実行し、そのアクションの最終結果を表示します。 何がうまくいき、何がうまくいかなかったかがわかります。 そのため、このオブジェクトの名前$I
であり、 wantTo()
、 see()
、またはamOnPage()
というメソッドが含まれています。
それで、テスターがページの操作性をチェックする方法について考えるように考えてみましょう。 最初のアプローチは、ページを開いてフレーズを検索することです。 これは、ページが訪問者に利用可能であることを証明します。
これは簡単なはずです:
<?php $I->amOnPage('/'); $I->see('Welcome');
このコマンドを使用して、Codeceptionのテストを実行できます。
$ php vendor/bin/codecept run
何かがおかしいことがすぐにわかります。 一見、メッセージが長すぎて不明瞭に見えますが、よく見るとすべてがわかります。
1つのテスト、 Acceptanceがあり、エラーが検出されました。
Acceptance Tests (1) Perform actions and see result (HelloWorldCept) Error ---------- 1) Failed to perform actions and see result in HelloWorldCept (tests/acceptance/HelloWorldCept .php) [GuzzleHttp\Exception\ConnectException] cURL error 6: Could not resolve host: localhost (see http://curl.haxx.se/libcurl/c/libcurl-errors.html)
これが原因です:ローカルホストは利用できません。
そして、これが私たちのテストのシナリオステップです:
1. $I->amOnPage("/")
では、tests / acceptance.suite.ymlを開いて、 url: http://localhost/
を実際に利用できるものに変更しましょう。 私の場合、それは私のローカルテストホスト、 url: https://local.codeception-article.com/
テストを再度実行すると、次のようになります。
Acceptance Tests (1) --------------------------------------------------------------------------------------- Perform actions and result (HelloWorldCept) Ok
やったー! 私たちの最初の成功したテスト!
もちろん、使用可能なテストメソッドはamOnPage()
だけではありません。この例では、amOnPage()を選択しただけです。 すべてのCodeceptionテスト方法は、次のグループに分けることができます。
- ページとの相互作用:
fillField()
、selectOption()
、submitForm()
、click()
- アサーション。
see()
、dontSee()
、seeElement()
、seeInCurrentUrl()
、seeCheckboxIsChecked()
、seeInField()
、seeLink()
。 これらすべてのメソッドにサフィックスを追加して、何かが見つからないときにテストシナリオを中断しないメソッドが必要な場合に使用できます。 - Cookieメソッド:
setCookie()
、grabCookie()
、seeCookie()
- テストシナリオのコメントと説明:
amGoingTo()
、wantTo()
、expect()
。 これらの方法を使用して、十分にコメントされ、説明されたテストを取得します。これは、テストの目標を思い出すのに役立ちます。
したがって、パスワードリセットの電子メールページをテストする場合は、次のように行うことができます。
<?php $I = new AcceptanceTester($scenario); $I->wantTo('Test forgotten password functionality'); $I->amOnPage('/forgotten') $I->see('Enter email'); $I->fillField('email', '[email protected]'); $I->click('Continue'); $I->expect('Reset password link not sent for incorrect email'); $I->see('Email is incorrect, try again'); $I->amGoingTo('Fill correct email and get link'); $I->see('Enter email'); $I->fillField('email', '[email protected]'); $I->click('Continue'); $I->expect('Reset password link sent for correct email'); $I->see('Please check your email for next instructions');
これでうまくいくように見えますが、ページにAjaxがロードされたパーツがある場合はどうなりますか? そのようなページをテストできますか? 答えは、CodeceptionがデフォルトでSymfonyBrowserKitとGuzzleに基づくPhpBrowserを使用するということです。 シンプルで高速で、カールするだけで使用できます。

Seleniumを使用して、実際のブラウザーでページをテストすることもできます。 はい、遅くなりますが、JavaScriptもテストできます。
まず、Seleniumドライバーをインストールし、acceptance.suite.ymlを変更して、AcceptanceTesterクラスを再構築する必要があります。 この後、メソッドwait()
およびwaitForElement()
)を使用できます。 さらに興味深いことに、 saveSessionSnapshot()
loadSessionSnapshot()
を使用することで、時間とリソースを節約できます。 この方法では、セッションの状態を保存し、以前のセッションで新しいテストを開始できます。 これは、テスト認証プロセスなど、一部の状況で役立ちます。
したがって、多くの機能をテストするためのシンプルでありながら強力な機能が得られます。
機能テスト
では、機能テストに移りましょう。
$ php vendor/bin/codecept generate:cept functional HelloWorld
そして、これは私たちが得るものです:
<?php $I = new FunctionalTester($scenario); $I->amOnPage('/'); $I->see('Welcome');
待って、何?
いいえ、それは間違いではありません。 機能テストは、統合テストと同じ方法で作成する必要があります。 違いは、機能テストがアプリケーションと直接相互作用していることです。 つまり、機能テストを実行するためにWebサーバーは必要なく、アプリケーションのさまざまな部分をテストするためのより多くの容量があります。
すべてのフレームワークのサポートが不足していることを意味しますが、サポートされているフレームワークのリストは広範囲です:Symfony、Silex、Phalcon、Yii、Zend Framework、Lumen、Laravel。 これは、ほとんどの場合とほとんどの開発者にとって十分なはずです。 Codeceptionのモジュールのドキュメントを参照して、使用可能な関数のリストを取得してから、 functional.suite.yml
でオンにしてください。
ユニットテストに進む前に、少し余談をさせてください。 お気づきかもしれませんが、キーセプトを使用してテストを作成しました。
$ php vendor/bin/codecept generate: cept acceptance HelloWorld
これは、テストを作成する唯一の方法ではありません。 cestテストもあります。 違いは、1つのクラスで複数の関連するシナリオを構成できることです。
$ php vendor/bin/codecept generate:cest acceptance HelloWorld <?php class HelloWorldCest { public function _before(AcceptanceTester $I) { $I->amOnPage('/forgotten') } public function _after(AcceptanceTester $I) { } // tests public function testEmailField(AcceptanceTester $I) { $I->see('Enter email'); } public function testIncorrectEmail(AcceptanceTester $I) { $I->fillField('email', '[email protected]'); $I->click('Continue'); $I->see('Email is incorrect, try again'); } public function testCorrectEmail(AcceptanceTester $I) { $I->fillField('email', '[email protected]'); $I->click('Continue'); $I->see('Please check your email for next instructions'); } }
この例では、メソッド_before()
と_after()
が各テストの前後に実行されます。 AcceptanceTester
クラスのインスタンスが各テストに渡されるため、cestテストと同じように使用できます。 このスタイルのテストは特定の状況で役立つ可能性があるため、覚えておく価値があります。
ユニットテスト
いくつかのユニットテストの時間。
CodeceptionはPHPUnitに基づいているため、PHPUnit用に作成されたテストを使用できます。 新しいPHPUnitテストを追加するには、次のアプローチを使用します。
$ php vendor/bin/codecept generate:phpunit unit HelloWorld
または、 \PHPUnit_Framework_TestCase
でテストを継承します。
しかし、もっと何かが必要な場合は、Codeceptionのユニットテストを試してみてください。
$ php vendor/bin/codecept generate:test unit HelloWorld <?php class HelloWorldTest extends \Codeception\TestCase\Test { /** * @var \UnitTester */ protected $tester; protected function _before() { } protected function _after() { } // tests public function testUserSave() { $user = User::find(1); $user->setEmail('[email protected]'); $user->save(); $user = User::find(1); $this->assertEquals('[email protected]', $user->getEmail()); } }
今のところ珍しいことは何もありません。 メソッド_before()
および_after()
は、 setUp()
およびtearDown()
の類似物であり、各テストの前後に実行されます。
このテストの主な利点は、 unit.suite.yml
にオンにできるモジュールを含めることでテストプロセスを拡張できることです。
- 変更を追跡するためのmemcacheとデータベースへのアクセス(MySQL、SQLite、PostgreSQL、MongoDBがサポートされています)
- REST/SOAPアプリケーションのテスト
- キュー
各モジュールには独自の機能があるため、実際のテストに進む前に、ドキュメントを確認し、各モジュールに必要な情報を収集することをお勧めします。
さらに、Codeception / Specifyパッケージ( composer.json
に追加する必要があります)を使用して、次のような説明を書くことができます。
<?php class HelloWorldTest extends \Codeception\TestCase\Test { use \Codeception\Specify; private $user; protected function _before() { $this->user = User::find(1); } public function testUserEmailSave() { $this->specify("email can be stored", function() { $this->user->setEmail('[email protected]'); $this->user->save(); $user = User::find(1); $this->assertEquals('[email protected]', $user->getEmail()); }); } }
これらのクロージャ関数内のPHPコードは分離されているため、内部の変更が残りのコードに影響を与えることはありません。 説明は、テストを読みやすくし、失敗したテストを簡単に識別できるようにするのに役立ちます。
オプションの追加機能として、BDDのような構文のパッケージCodeception\Verify
を使用できます。
<?php public function testUserEmailSave() { verify($map->getEmail())->equals('[email protected]'); }
そしてもちろん、スタブを使用できます。
<?php public function testUserEmailSave() { $user = Stub::make('User', ['getEmail' => '[email protected]']); $this->assertEquals('[email protected]', $user->getEmail()); }
評決:Codeceptionは時間と労力を節約します
では、Codeceptionに何を期待する必要がありますか? 誰のためですか? 注意点はありますか?
私の意見では、このテストフレームワークは、大小さまざまなチームに適しています。大小の初心者や、戦いに強いPHPの専門家、人気のあるフレームワークを使用している人、フレームワークを使用していない人などです。
いずれにせよ、それはすべてこれに要約されます: Codeceptionは最高の時間の準備ができています。
これは成熟した十分に文書化されたフレームワークであり、多数のモジュールによって簡単に拡張できます。 Codeceptionは最新のものですが、定評のあるPHPUnitに基づいているため、あまり実験したくない開発者を安心させることができます。
それはうまく機能します、それはそれが速くて、あまり多くの時間と労力を必要としないことを意味します。 さらに良いことに、習得するのは比較的簡単であり、豊富なドキュメントは手間のかからない学習プロセスを支援するはずです。
Codeceptionは、インストールと構成も簡単ですが、多くの高度なオプションを備えています。 ほとんどのユーザーはそれらのすべて(または実際にはほとんど)を必要としませんが、それはすべてあなたがそれで何をしようとしているのかに依存します。 基本から始めることができ、追加機能は遅かれ早かれ便利になります。