こんにちは、2014年入社の野際です。
もうすぐ入社して一年経つわけですが、まだまだ学ぶことがたくさんあって楽しいです。
さて、今回初めて技術系の記事を書くことになりました。
そこで、WEB+DB vol.85のSeleniumの記事を読んで、PerlでSeleniumを触ってみたときのことを記事にしたいと思います。 実際にブラウザが操作されている様子を確認できるので、実際にユーザが利用するときの流れに近いテストが可能です。
アプリケーションの準備
今回は以下のような簡単なフォーム画面を使ってE2Eテストを行いたいと思います。
アプリケーションの準備
今回は以下のような簡単なフォーム画面を使ってE2Eテストを行いたいと思います。
本来はJavaScriptが絡んでくるような、複雑な画面でこそ真価を発揮するものなんですが・・実験的なものなので、まあよしとします。
すべてのパラメータが送信されていれば、フォームの下にメッセージを表示するといった感じです。
送信前
送信後
HTML
Seleniumの準備
Seleniumを使うためにはSelenium Serverというものが必要になります。
Selenium Server
Selenium::Remote::Driverの準備
さっそく簡単な起動テストしましょう。
Perl
出力
Selenium::Remote::Driver->set_implict_wait_timeout( string $milliseconds )
テストの実施
出力
送信前
送信後
HTML
SeleniumTest SeleniumTest
Seleniumの準備
Seleniumを使うためにはSelenium Serverというものが必要になります。
Selenium Server
java -Dwebdriver.chrome.driver="chromedriver.exe" -jar selenium-server-standalone-2.44.0.jar
10:57:55.642 INFO - Launching a standalone server 10:57:56.109 INFO - Java: Oracle Corporation 24.71-b01 10:57:56.109 INFO - OS: Windows 7 6.1 amd64 10:57:56.193 INFO - v2.44.0, with Core v2.44.0. Built from revision 76d78cf 10:57:56.637 INFO - RemoteWebDriver instances should connect to: http://127.0.0.1:4444/wd/hub 10:57:56.639 INFO - Version Jetty/5.1.x 10:57:56.639 INFO - Started HttpContext[/selenium-server/driver,/selenium-server/driver] 10:57:56.639 INFO - Started HttpContext[/selenium-server,/selenium-server] 10:57:56.639 INFO - Started HttpContext[/,/] 10:57:57.293 INFO - Started org.openqa.jetty.jetty.servlet.ServletHandler@7e0ef515 10:57:57.293 INFO - Started HttpContext[/wd,/wd] 10:57:57.314 INFO - Started SocketListener on 0.0.0.0:4444 10:57:57.314 INFO - Started org.openqa.jetty.jetty.Server@113dbe08
お、なんか無事に起動したっぽいですね。ここでアクセスログを確認できるので別ペインで開いておくといいと思います。
Selenium::Remote::Driverの準備
cpanm Selenium::Remote::Driver
さっそく簡単な起動テストしましょう。
Perl
use strict; use warnings; use utf8; use Selenium::Remote::Driver; my $driver = Selenium::Remote::Driver->new( 'browser_name' => 'chrome' ); # ブラウザの起動 $driver->get('http://www.google.com'); print $driver->get_title(); $driver->quit(); # ブラウザの終了
出力
このように、ブラウザの起動→処理→ブラウザの終了が一連の流れになります。
先に、後ほど使うメソッドを簡単に紹介しておきます。本当はもっとあるんですがここでは書ききれませんでした。
Selenium::Remote::Driver->set_implict_wait_timeout( string $milliseconds )
要素の検索時にタイムアウトする時間を設定する。
組み込みのsleep関数とかと違って、要素が見つかればが処理が再開されます。
Selenium::Remote::Driver->get( string $url )
GETリクエストを送信する。
Selenium::Remote::Driver->find_element( string $target, string? $schema )
Selenium::Remote::WebElement->send_keys( string @strings )
Selenium::Remote::WebElement->click()
要素をクリックする。
Selenium::Remote::Driver->get( string $url )
GETリクエストを送信する。
Selenium::Remote::Driver->find_element( string $target, string? $schema )
ちなみにCSSが推奨らしいです。
Selenium::Remote::WebElement->send_keys( string @strings )
要素にキーを送信する。
フォームに値を入力するのに使います。
Selenium::Remote::WebElement->click()
要素をクリックする。
テストの実施
さて、ここまでで結構長くなってしまいましたがいよいよテストを実施します。
テストコードはTest::Classモジュールを使って書きました。
package SeleniumTest; use strict; use warnings; use utf8; use parent 'Test::Class'; use Test::More; use Selenium::Remote::Driver; use constant NAME => 'noge'; use constant AGE => 23; SeleniumTest->runtests; sub startup : Test( startup ) { my ( $self ) = @_; $self->{ driver } = Selenium::Remote::Driver->new( 'browser_name' => 'chrome', ); $self->{ driver }->set_implicit_wait_timeout( 5 ); return; } sub setup : Test( setup ) { my ( $self ) = @_; $self->{ driver }->get( 'http://192.168.60.168:3003/selenium/' ); $self->{ text_name } = $self->{ driver }->find_element( 'input[name=name]' , 'css' ); $self->{ text_age } = $self->{ driver }->find_element( 'input[name=age]' , 'css' ); $self->{ submit } = $self->{ driver }->find_element( 'input[type=submit]', 'css' ); $self->{ reset } = $self->{ driver }->find_element( 'input[type=reset]' , 'css' ); return; } sub t001_submit_name_and_age : Tests { my ( $self ) = @_; $self->{ text_name }->send_keys( NAME ); $self->{ text_age }->send_keys( AGE ); $self->{ submit }->click; is( $self->{ driver }->find_element( 'p[class=message]', 'css' )->get_text, NAME . 'さんの年齢は' . AGE . '才です。' ); return; } sub t002_submit_name : Tests { my ( $self ) = @_; $self->{ text_name }->send_keys( NAME ); $self->{ submit }->click; is( $self->{ driver }->find_element( 'p[class=message]', 'css' )->get_text, '' ); return; } sub t003_submit_age : Tests { my ( $self ) = @_; $self->{ text_age }->send_keys( AGE ); $self->{ submit }->click; is( $self->{ driver }->find_element( 'p[class=message]', 'css' )->get_text, '' ); return; } sub t004_reset : Tests { my ( $self ) = @_; $self->{ text_name }->send_keys( NAME ); $self->{ text_age }->send_keys( AGE ); $self->{ reset }->click; is( $self->{ text_name }->get_text, '' ); is( $self->{ text_age }->get_text, '' ); return; } sub shutdown : Test( shutdown ) { my ( $self ) = @_; $self->{ driver }->quit; return; }
出力
ok 1 - t001 submit name and age ok 2 - t002 submit name ok 3 - t003 submit age ok 4 - t004 reset ok 5 - t004 reset 1..5
無事に成功しました!!
本当はテスト結果をGIFアニメにしたかったんですが、終了が速過ぎて捉えきれませんでした・・
とにかく早いんで見ていて爽快です。是非お試しください!!