10/12社内で開催したSelenium勉強会で使用したスライド
Selenium勉強会arm4
View Slide
今日、話すことそもそもテストって何?LaravelのテストSelenium概要&環境構築手順テスト実行デモンストレーションSeleniumコード実装時の注意事項LaravelでPHPUnitを書く時の注意事項PHPUnit(Laravelテスト)との比較
そもそもテストって何?
単体テストクラスや関数といった単位のプログラムのテスト結合テスト単体テストで検証したプログラムを組みわせて行うテスト機能テスト結合したプログラムを1つの機能として行うテストシステムテスト個々のプログラムや機能を結合したプログラムが仕様通りに動くかを検証するためのテストhttps://qiita.com/ktarow/items/8c3d94d6c21a0c86b79
いきなりいっぱいある!!難しい専門用語ばっかり!!正直、面倒くさそうwwwテストばっか書いてられないし。。こんなに大それたテストじゃなくていいから、普通に人間がテストしてるようなのを自動でやってくれないかな。
たとえば、面倒なテストって言えば....広範囲に影響がある共通メソッドをいじったから全ページ落ちてないか確認。GETのパラメによって表示する内容が変わる系ページの全パターン網羅。とりあえず一通りの保存編集削除が壊れてないか確認。
だいたいこういうテストは何パターンかやったら、「うん。よさそうだな。」になる。だいたいバグ報告は、こういう「うん。よさそうだな。」から漏れてる箇所。だいたい「え?そこ?」みたいな斜め上からやってくる。あーーーこんな簡単で面倒なテスト誰か代わりにやってくれないかなー。
それ、あるよ!E2Eテスト
E2EテストE2EとはEnd to Endの略。Face to Faceの友達。端から端までテストするよという意味。
より狭義的に言うとコードを使ってブラウザを操作し、ユーザが実際に操作するのと同じことを再現するテストのこと。ブラウザテストとも呼ばれる。要するに私たちが普段、手でやってるテスト!!!!
ブラウザテストツールはこんなにっ★ブラウザテストツール総まとめ・2016年夏版https://qiita.com/cognitom/items/6cce719b57341769c
ベル子の優しいまとめヘッドレスブラウザを使ったテストSeleniumを使ったテストこの2種類があるって覚えておけばおk
ヘッドレスブラウザを使ったテストリアルなブラウザとは違うので挙動がちょっと違うこともあるGUIがないからテストの実行速度が速いGUIがないからLinuxでも安心
Seleniumを使ったテストリアルなブラウザのエンジンを使うので挙動での差がないGUIがあるからテストの実行速度がやたら遅いGUIがあるからLinuxでは頑張らないと使えない
現状では、挙動での差がないSeleniumを選択する現場が多いようです。
Laravelのテスト
PHPUnitというテスティングフレームワークをベースにLaravelが使いやすいように、いろいろ施したやつ。PHPUnitを使う上で押さえておきたい知識PHPUnitの主なAssertメソッド一覧http://www.dn-web64.com/archives/web/phpunit_knowledge/https://qiita.com/rev84/items/12fbd16d210d6a86eff9
実は、Laravelのテストを使えば、単体テスト、結合テスト、機能テスト、システムテストをひと通り書ける。と、思う。↓詳しくはこちらhttps://laravel.com/docs/5.2/testing
こんな感じでページのクローリングもできる。//public function testTimeline(){$this->visit('/timeline')->seePageIs('/timeline')->see(' ');}
あれ?それならSelenium必要ないんじゃね?
ただ、Laravelのテストには致命的な問題が存在していた!!
JavaScriptが理解できないお(´・ω・`)
JavaScriptが理解できないイコール、Vue.jsが書き出すhtmlが読めないイコール、Vue.jsが死んでて何も表示されなくても分からないイコール、モーダルで何かやってるやつ系全部ムリイコール、ajaxで何かやってるやつもムリ
Selenium概要&環境構築手順
超訳Selenium概要https://www.kaitoy.xyz/2017/07/12/2017-selenium-headless-browsers/ブラウザテスト創世記にはこうある。神は「光あれ」と言われた。するとSeleniumがあった。神はその光を見て、良しとされた。神はその光と闇とを分けられた。神は光をSelenium RC (aka Selenium 1)と名づけ、闇を SeleniumWebDriver (aka Selenium 2)と名づけられた。
ちゃんとしたSelenium概要Seleniumの原型は2004年に誕生し、いろいろな経緯があってSelenium RC(Selenium 1)が誕生。Selenium RCはJavaやPythonなどの言語で書いたスクリプトを元に、 JavaScriptを生成しそれをテストページに埋め込んでブラウザを操作するという仕組みだったので、 ブラウザのセキュリティ制限によって多くの動作制約を受けた。そこで、すごい人がネイティブなブラウザ機能あるいはブラウザ拡張を用いてブラウザを直接操作する仕組みを模索し始める。
2007年、WebDriverの開発が始動。2011年7月、Selenium RCとWebDriverを統合した、Selenium WebDriver(Selenium 2)がリリース。現在、Seleniumのバージョンは3。3は2の単なるバグフィックス。3ではSelenium RCのAPIはサポートされなくなった。現在、WebDriverのAPIはW3Cで標準化が進められている。
ドライバを使ってブラウザを動かす方法RESTful API(JSON Wire Protocol)に従いHTTPリクエストを発行し、返って来たレスポンスを解釈して用途に合わせてまたHTTPリクエストを発行するというような仕組みになっている。https://app.codegrid.net/entry/selenium-1
そんな難しいこと知ったこっちゃない。大丈夫、Selenium公式がサポートしているクライアントのライブラリがあるYO★
対応言語JavaRubyPythonC#JavaScript(Node.js)
でたーーwwwPHPがないwwww
大丈夫!!Facebook様がライブラリ作ってくれたよ!でも、非公式言語だから、Selenium Server Standaloneという別言語からでもアレできる何かを入れる必要があるの☆メンゴ
Selenium WebDriverはAPIを介してブラウザを直接操作するため、ブラウザ毎にドライバーが用意されている。使いたいドライバーが複数あれば全てインストールしなければならない。Firefox, GeckoDriverChrome, ChromeDriverMS Edge, Microsoft WebDriver
すごくてうれしいまとめSeleniumとは...ある特定の単体ライブラリの名称ではない。WebDriverを使ったブラウザを自動操作して行うテスト環境(エコシステム)全体のこと。
詳しい導入手順(お手製)https://qiita.com/Arm4/items/92ef786378b544c7ffe4
Laravelに自力でfacebook/php-webdriver(以下phpdriver)を入れるコツ
phpdriverはphpunitのバージョンをrequireしているため、各OSSのgithubページのcomposer.jsonを確認し、全員に怒られないバージョンを特定し記述する必要がある。Laravel以外のフレームワークもComposer.jsonを使用していれば、だいたい要領は同じ。
Laravelのcomposer.jsonこれのbranchを切り替えればそれぞれのcomposer.jsonの確認ができる。https://github.com/laravel/laravel/blob/master/com
phpdriverのcomposer.jsonphpdriverのほうはTagでバージョン管理してるようなので、タブをTagsにしてそちらで切り替えて確認。https://github.com/facebook/php-webdriver/blob/community/composer.json
参考Composerのバージョン指定方法でのチルダ(~)とキャレット(^)の違いhttp://blog.a-way-out.net/blog/2015/06/19/composer-version-tilde-and-caret/
テスト実行デモンストレーション
selenium-serverはデフォルトでポート4444で立ち上がるので、コード内でlocalhost:4444と指定している人はポートを指定する必要はない。selenium-server
アプリルートで実行./vendor/bin/phpunit tests/BrowserTest.php
Seleniumコード実装時の注意事項
操作したいHTML要素がロードされるまで待ってから操作を始めないといけないファーストビューで見えない位置にある要素をクリックしようとするとエラーが出るので、コードでスクロールさせないといけないLaravelのDebug Barがじゃまで一番下の要素のクリックができないのでテストの前にはAPP_DEBUG=falseに
本当にブラウザを立ち上げて自動で操作しているだけなので、コード上でAPP_ENV=testingにしても効いてくれないテスト時のみサブドメインを設定してconfig/app.phpで判定させてみたが、テスト実行時にエラーが出てしまう。うまい解決法が見つかっていない。'env' => strpos(url('/'), 'http://testing.') !== false ? 'test
ChromeだとgetTextだとうまくテキストが取得できない場合があるのでgetAttribute("innerText")でテキストを取得する$element = $this->driver->findElement(WebDriverBy::cssSelreturn $element->getAttribute("innerText");
Select2の入力時などinput入力にJSが絡んでくる場合、最後にenterを付け加えてやるとうまくいく// 選択$element = $this->findBySelector('.visions-group-member-s$action->moveToElement($element)->click()->perform();$this->driver->findElement(WebDriverBy::cssSelector(".vis
Ajaxを使ったDBへのデータ追加を伴う処理のあと、リダイレクトでページが表示されてすぐに、またDB操作をしたりするとデータがないと怒られるため、sleepさせるなどして適度に待ってやらないといけない
LaravelでPHPUnitを書く時の注意事項
LaravelでsetUpを使う場合は継承の関係上、このように書かないといけない。public function setUp(){parent::setUp();}
PHPUnit(Laravelテスト)との比較
PHPUnit Seleniumテストコードが何をやってるか分かりにくい分かりやすいVue.jsのコンポーネントテスト ×○ajaxを使った保存テスト △ ○モーダルを使ったUIのテスト ×○
PHPUnit Selenium.env.testingの利用 ○ ×APIの返すjsonレスポンスの検証○ ×メソッド単位のテスト ○ ×数値比較テスト ○ △バリデーションのテスト ○ △
参考【Laravel】フォームリクエストバリデーションのテストコード作成https://qiita.com/n_mogi/items/57a946205df2a69889c
ここまで話しておいて何ですが....
Laravel 5.4からLaravelのテスト仕様が大幅に変更になりました。
Why?いくらページのクロールができたとしても、JavaScriptが理解できないとJSフレームワークを利用したサイトでのテストは難しい。Selenium環境を構築するのって面倒Seleniumでテストできたら、事実上、PHPUnitのほうでアプリケーションテスト(システムテスト)をする必要がない。
Laravelの出した結論単体テストPHPUnitでやりましょう。(Unit)結合テストPHPUnitでやりましょう。(Laravelでは定義されてないが、Unitに入れるのがよさげ)機能テストPHPUnitでやりましょう。(Feature)
システムテストSeleniumでやりましょう。Laravelが使いやすいライブラリを作っておきました。https://laravel.com/docs/5.5/dusk
APIテストPHPUnitでやりましょう。Laravelが使いやすいメソッドを作っておきました。https://laravel.com/docs/5.5/http-tests
詳しくはこちらをどうぞhttps://laravel.com/docs/5.5/testing
ご清聴ありがとうございました★