テストを書く
テストケース
テストは tests/TestCase/EndToEnd/ (レガシー構成では app/Test/Case/EndToEnd/) に置き、 PantherTestCase を継承します (docs/examples/ArticlesTest.php)。
<?php
declare(strict_types=1);
namespace App\Test\TestCase\EndToEnd;
use ClassRegistry;
use PieceOfCake2\Panther\TestSuite\PantherTestCase;
class ArticlesTest extends PantherTestCase
{
/**
* @var array<string>
*/
public $fixtures = ['app.article'];
/**
* @return void
*/
public function testIndexShowsTheFixtureRecords(): void
{
$client = static::createPantherClient();
$client->request('GET', '/articles');
$this->assertPageTitleContains('Articles');
$this->assertSelectorTextContains('table', 'First article');
}
/**
* @return void
*/
public function testAdd(): void
{
$client = static::createPantherClient();
$crawler = $client->request('GET', '/articles/add');
// FormHelper puts a hidden input before each checkbox: click the checkbox itself
$crawler->filter('#ArticlePublished')->click();
$client->submitForm('Submit', [
'data[Article][title]' => 'Written in the browser',
'data[Article][body]' => 'Hello',
]);
$this->assertSelectorTextContains('.message', 'The article has been saved.');
$this->assertSame(1, ClassRegistry::init('Article')->find('count', [
'conditions' => ['Article.title' => 'Written in the browser', 'Article.published' => true],
]));
}
}static::createPantherClient() はブラウザーを返します。実行中の最初の呼び出しで Web サーバーと Chrome が 起動し、それ以降の呼び出しでは同じブラウザーが返されます。
ページを開く
$client = static::createPantherClient();
$crawler = $client->request('GET', '/articles?page=2'); // a path of the application
$crawler = $client->clickLink('Next');
$client->back();
$client->getCurrentURL(); // http://127.0.0.1:9080/articles?page=2
$crawler->filter('h1')->text(); // the visible text
$client->executeScript('return document.title;');
$client->takeScreenshot('tmp/articles.png');クライアントは BrowserKit のクライアントで、クローラーは要素が WebDriver の要素である DomCrawler の クローラーです。Panther のドキュメント をご覧ください。
フォーム
submitForm() は、ボタンを含むフォームのフィールドを name で指定して入力し、フォームを送信します。
$client->submitForm('Log in', [
'data[User][email]' => 'user@example.com',
'data[User][password]' => 'secret',
]);data[User][email] のように、CakePHP の完全な名前を指定してください。ネストした配列はサポートされて いません。FormHelper のチェックボックスは、その前に同じ名前の hidden の input を出力するので、送信する 前にチェックボックスをクリックしてください: $crawler->filter('#UserRememberMe')->click()。 フォームはブラウザーが送信するので、SecurityComponent のトークンも機能します。
JavaScript を待つ
$crawler->filter('#load-more')->click();
$client->waitFor('.comment'); // in the DOM
$client->waitForVisibility('#dialog');
$client->waitForElementToContain('#total', '3 items');
// or as assertions
$this->assertSelectorWillContain('#total', '3 items');
$this->assertSelectorWillNotBeVisible('.spinner');Cookie とログイン
Panther と同じように、ブラウザーは Cookie とともにテストからテストへ引き継がれます。ログアウトした状態で 始める必要があるテストでは、まず Cookie をクリアします。
$client = static::createPantherClient();
$client->request('GET', '/');
$client->getCookieJar()->clear();ベースクラスのヘルパーメソッドでログインフォームからログインするか、後続のテストのために意図的に ログインしたままにしておいてください。
複数のブラウザー
static::createAdditionalPantherClient() は、別の独立したブラウザーを開きます。たとえば、チャットの 2 人目のユーザーに使います。アサーションは最後に作成されたブラウザーを確認します。
モバイルのビューポート
Panther にはデバイスのプリセットがなく、ヘッドレスの Chrome は --window-size で ウィンドウを 500 ピクセルより狭くしません。php-webdriver の DevTools プロトコルでスマートフォンをエミュレートし、 ブラウザーは次のテストに引き継がれるので、最後にリセットしてください。
use Facebook\WebDriver\Chrome\ChromeDevToolsDriver;
$client = static::createPantherClient();
$devTools = new ChromeDevToolsDriver($client->getWebDriver());
$devTools->execute('Emulation.setDeviceMetricsOverride', ['width' => 390, 'height' => 844, 'deviceScaleFactor' => 3, 'mobile' => true]);
try {
$client->request('GET', '/');
$this->assertSelectorIsVisible('.menu-toggle');
} finally {
$devTools->execute('Emulation.clearDeviceMetricsOverride');
}Emulation.setUserAgentOverride と Emulation.setTouchEmulationEnabled も、同じ方法で User-Agent と タッチイベントを変更します。
アサーション
PantherTestCase には、Symfony と Panther の WebTestAssertionsTrait のアサーションがあります。 これらは最後に作成されたブラウザーのページを確認します。ロケーターは CSS セレクター、または / で 始まる XPath 式です。
| アサーション | 確認する内容 |
|---|---|
assertSelectorExists($selector)、assertSelectorNotExists($selector) | 一致する要素があること |
assertSelectorCount($count, $selector) | 一致する要素の数 |
assertSelectorTextContains($selector, $text)、assertSelectorTextNotContains()、assertSelectorTextSame() | 最初に一致した要素の表示されているテキスト |
assertPageTitleSame($title)、assertPageTitleContains($title) | <title> |
assertInputValueSame($name, $value)、assertInputValueNotSame() | フィールドの現在の値。名前で指定します。例: data[Article][title] |
assertCheckboxChecked($name)、assertCheckboxNotChecked($name) | チェックボックス。名前で指定します |
assertBrowserHasCookie($name)、assertBrowserNotHasCookie($name)、assertBrowserCookieValueSame($name, $value) | ブラウザーの Cookie |
assertSelectorIsVisible($locator)、assertSelectorIsNotVisible() | 最初に一致した要素が表示されているかどうか |
assertSelectorIsEnabled($locator)、assertSelectorIsDisabled() | 有効かどうか |
assertSelectorAttributeContains($locator, $attribute, $text)、assertSelectorAttributeNotContains() | 属性。$text = null は属性が設定されていないことを確認します |
assertSelectorWillExist()、assertSelectorWillNotExist()、assertSelectorWillBeVisible()、assertSelectorWillNotBeVisible()、assertSelectorWillContain()、assertSelectorWillNotContain()、assertSelectorWillBeEnabled()、assertSelectorWillBeDisabled()、assertSelectorAttributeWillContain()、assertSelectorAttributeWillNotContain() | 上と同じ内容を、そうなるまで待ってから確認します (Panther の waitFor*()) |
Symfony のレスポンスのアサーション (assertResponseIsSuccessful() など) はありません。WebDriver は ステータスコードを公開しないためです。これらには IntegrationTestTrait を使ってください。
エラー時のスクリーンショットとインタラクティブモード
テスト報告書 には、成功・失敗を問わずすべてのテストのスクリーンショットが載ります。それに加えて 失敗したテストごとに PNG のファイルを保存するには、PANTHER_ERROR_SCREENSHOT_DIR を設定します (既定では 設定しません)。設定して拡張を使うと、ブラウザーを作成した後に失敗またはエラーになったテストは、ブラウザーごとに スクリーンショットを保存します。ファイル名は日付、失敗の種類、テストから付けられます。

PANTHER_NO_HEADLESS=1 と PHPUnit の --debug を使うと、失敗した後に Enter キーを押すまで実行が 一時停止するので、ブラウザーの状態を確認できます。
PANTHER_NO_HEADLESS=1 vendor/bin/phpunit --testsuite EndToEnd --debugAPI リファレンス
PantherTestCase
PieceOfCake2\Panther\TestSuite\PantherTestCase は CakeTestCase を継承し、Panther の PantherTestCaseTrait と、このパッケージの WebTestAssertionsTrait を使います。
| メンバー | 説明 |
|---|---|
static createPantherClient(array $options = [], array $kernelOptions = [], array $managerOptions = []) | ブラウザー。最初の呼び出しで Web サーバーとブラウザーを起動します (Panther) |
static createAdditionalPantherClient() | 別の独立したブラウザー (Panther) |
static createHttpBrowserClient(array $options = []) | HTTP を通して動く、JavaScript なしのクライアント (Panther) |
static startWebServer(array $options = []) | CakePHP 向けのデフォルトで Web サーバーを起動します。その後は Panther と同じ動作です |
static stopWebServer()、static isWebServerStarted() | Panther |
static defaultWebServerDir(?string $projectRoot = null) | プロジェクトの webroot/ または app/webroot/ (protected) |
tearDown() | CakeTestCase::tearDown() の後、失敗したテストのスクリーンショットを保存します |
ROUTER | CakePHP のルータースクリプトのパス |
CHROME、FIREFOX、SELENIUM | browser オプションの値 |
WebTestAssertionsTrait
PieceOfCake2\Panther\TestSuite\WebTestAssertionsTrait: アサーション を提供します。 PantherTestCaseTrait を使うクラスで使ってください。
ServerExtension
PieceOfCake2\Panther\ServerExtension は、Panther の ServerExtension と同じことを行います。最後の テストまで Web サーバーとブラウザーを動かしておき、失敗したテストのスクリーンショットを撮り、 インタラクティブモードでは一時停止します。また、最後のテストの後に PantherTestCase の Web サーバーと ブラウザーを停止します。Panther の拡張の代わりにこれを登録してください。
