Thucydidesをためす
Jenkins User Conferenceのタイムテーブルで存在を知って,ちょっと気になってたThucydidesを試したよ。
→ satta-2 : Jenkinsによる自動受け入れテストから継続的デリバリーまで
Thucydides,まず読めないw。ググってみたらギリシャの歴史家のお名前で「wikipedia:トゥキディデス」と読むらしい。作者は「Java Power Tools(asin:0596527934)」や「Jenkins: The Definitive Guide(asin:1449305350)」のJohn Smartさん。
→ GitHub - thucydides-webtests/thucydides: Thucydides is a tool that lets you use WebDriver-based unit or BDD tests to write more flexible and more reusable WebDriver-based tests, and also to generate documentation about your acceptance tests, including a narrative description of test, along with the corresponding screen shots, and also high-level summaries and aggregations of the test results
→ http://www.wakaleo.com/resources/thucydides-automated-testing-library
→ http://www.wakaleo.com/thucydides/
何やるツールかというと「ユーザ受入テスト(UAT)」をしてくれる。ざっと特徴を挙げると,
- Mavenのプラグインとして提供されていて,
- JUnitのTestSuite的なモノ(Application)にユーザ要求を定義して,
- ユーザ要求に対応するテストシナリオをeasyb(もしくはJUnit)で記述
- テストシナリオ中の個々のテスト手順をStepsというクラスに定義し,
- そのStepsからSeleniumのWebDriverを用いたWeb画面に相当するクラスを呼び出す。
って感じ(ワケワカラン)。「ユーザ受入テスト」だと範囲が広すぎてアレだけど,どうやらSelenium2(WebDriver)を利用して,もうちょっとユーザフレンドリなテストシナリオを書いて実行するテストツールと言った感じ。
特徴的な機能は,先ほどのStepsであるおまじない(@Stepアノテーションを付与)をすると,その時のブラウザのスクリーンショットを撮りながらテストを進めてくれる。当然,レポートにはそのスクリーンショットが添付される。
スゴそう&面白そうなんで試してみたんだけど,やっぱり大変w で,まあ仕事で使う事はないだろうなってのが今のところの結論。そうは言っても保守的な仕事環境じゃ難しいという意味なので,興味のある人はバトンを引き継いで欲しい。:-)
以下,備忘録を兼ねた簡単な使い方メモ。
プロジェクトの作り方
Mavenのプロジェクトとして作成する。UATはプロダクトコードとは独立して作成できるので,プロダクトコードのプロジェクトがどんな形態だとしても,こっちが影響受けることもない(し,向こうも同等)。
$ mvn archetype:generate
でプロジェクトを作成して,archetypeに"net.thucydides.thucydides-easyb-archetype"を選ぶ。いろいろ細かい事はこちらを参照のこと。
→ http://www.wakaleo.com/thucydides/_creating_a_new_thucydides_project.html
テストの構成
だいたいこんな構成で,Applicationってのが,TestSuite的というかテストの目次みたいなものになってる。
この @Feature ってのが,テストの括りみたいなもんんで,そん中の内部クラスに意味がある様子。というか,この内部クラスが,個々のテストシナリオに相当する。
public class Application { @Feature public class Search { public class SearchByKeyword {} public class SearchByKeyword_Ja {} } @Feature public class Search2 { public class SearchByBlogEntry {} } }
テストシナリオの実体は別に記述する。JUnitかeasybか(他にもJBehaveも?)選べるみたい。とりあえず,easyb使ってみたけど,おまじないがいろいろあるみたいなので,素直にJUnit使っとけばよかったかなとも思わなくもなし。:-P
package com.mycompany import com.mycompany.steps.BuildShokuninSteps import com.mycompany.requirements.Application.Search2.SearchByBlogEntry using "thucydides" thucydides.uses_default_base_url "http://build-shokunin.org/" thucydides.uses_steps_from BuildShokuninSteps thucydides.tests_story SearchByBlogEntry scenario "Looking up the keyword of 'JUC'", { given "BuildShokuninのトップページに訪れる", { build_shokunin.is_the_home_page() } when "キーワード 'JUC' でブログエントリを検索する", { build_shokunin.looks_for "JUC" } }
'thucydides.uses_steps_from'とか'thucydides.tests_story'ってのがおまじないっぽい(あまり良くわかってない)。あと,scenario に日本語使ったらコケた。
テストシナリオ中に出てくる,
build_shokunin.is_the_home_page()
なのがStepsクラス。たとえば,上記の実体は BuildShokuninSteps でJavaで書く。どうも,Stepsクラスから"Steps"を抜いて,キャメルケースをスネークケースに暗黙的に変換してるっぽい。なんで,
BuildShokuninSteps => build_shokunin
となるみたい(たぶん...。
そのStepsクラスはこんな感じ。
public class BuildShokuninSteps extends ScenarioSteps { public BuildShokuninSteps(Pages pages) { super(pages); } private BuildShokuninPage onBuildShokuninPage() { return getPages().currentPageAt(BuildShokuninPage.class); } @Step public void is_the_home_page() { onBuildShokuninPage().open(); } @Step public void looks_for(String keyword) { onBuildShokuninPage().enter_keywords(keyword); onBuildShokuninPage().lookup_terms(); } }
見ての通り「手順」を記述してく。どうやら @Stepアノテーション に意味があるらしく,このアノテーションが付いたステップを実行するともれなくスクリーンショットを取ってくれるらしい。なので,ステップの内部処理(テストシナリオから直接呼ばれないメソッド)も @Stepアノテーション付けとくと,スクリーンショットの取得対象になる。
んで,ここではテストしたいWebページに相当するPageオブジェクトてのが必要になるらしく,それはそれで別途定義する(だんだんイヤになってきたw
@DefaultUrl("http://build-shokunin.org/") public class BuildShokuninPage extends PageObject { @FindBy(id = "searchbox") private WebElement searchBox; @FindBy(name = "s") private WebElement searchButton; public BuildShokuninPage(WebDriver driver) { super(driver); } public void enter_keywords(String keyword) { element(searchBox).type(keyword); } public void lookup_terms() { element(searchButton).click(); } }
ここでやっとこSeleniumのWebDriverが登場する。つまり,テストしたいWebサイトのWebページ分のPageオブジェクトを用意して/それを意味ある操作にまとめたStepsクラスを作り/ユーザ要求に相当するテストシナリオから利用する,ようだ。
だれがどこを分担するのか分からんけど,これ使ってマジメにテストしようと思ったら,結構な苦労してPageオブジェクトを作る事になるんじゃ無かろうか?などと余計なことを考えてしまった。
逆にある程度,ルールまたは使うWebフレームワークが決まってしまえば,Pageオブジェクトを自動生成することはできそうな予感もする。
なので,Thucydidesを使う上での最大の障壁はPageオブジェクトの準備なのかなって思った次第。
テストの実行
これでテスト実行:
$ mvn test thucydides:aggregate
これでレポート作成(レポートは './target/site/thucydides'にできる):
$ mvn thucydides:thucydides
あとテストで使うブラウザはpom.xmlに指定する。
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <thucydides.version>0.7.10</thucydides.version> <webdriver.driver>iexplorer</webdriver.driver> </properties>
その他
残念な事が2つほど。1つは,テストケースに日本語使うとレポートで中途半端に文字化けする。もう1つは,スクリーンショットが途中までしか撮れない。どうもオートスクロールさせてページ全体のスクリーンショットを撮ろうとして,思い通りに行ってない感じ。テストで使ったのがIE6だったので,それが原因かも知れない...。
なんとか手軽にユーザ受入テストの自動化できないかなーと思うのだけれど,なかなかピタっとはまるモノはないねー。:-)
→ https://github.com/masanobuimai/thucydides-sample