ThoughtWorks StudiosはTwistの最新バージョンであるTwist 2.0をリリースした。Twistはアジャイルテスト自動化ツールだ。Twist 2.0はテスターや開発者、ビジネス分析者が協力してテストすることを支援する。振る舞い駆動開発(BDD)とドメイン特化言語(DSL)の技術を使ってテスト自動化を実現し、動的言語であるGroovyを使ってテストスクリプトを書くこともできる。
Twistは再利用可能なテスト自動化スクリプトを作成するユーザインターフェイスを提供する。このスクリプトは手動テストでも自動の機能テストでも利用できる。また、テスト実行記録をプロジェクトやチームを横断して可視化する。最新バージョンの特徴は、
- ハイブリットなテスト拡張: 手動テストと自動テストの各ステップで同じテストシナリオで実行できます。これによって自動テストと手動テストを効果的に組み合わせられます。
- テストシナリオの再利用: テストシナリオやステップ(自動または手動)を高いレベルで再利用できます。また複数のプロジェクトで共有して利用することも可能です。
- Sahi Web Driverのサポート: テスターはウェブのテストのためにSahiまたはSeleniumを選択することができます。
- SWTBOTのサポート: SWTベースのアプリケーションのテストが可能です。
- データ駆動シナリオ: テスト範囲の増大に対応するため素早くデータ駆動型テストを構築できます。
InfoQはThoughtWorks StudiosチームのChad Wathington氏にこの自動テストツールの最新バージョンについて詳細を聞いた。
InfoQ:Twistの新しいバージョンをリリースした主な目的は何でしょうか。
Twist 2.0には大規模な機能テスト自動化を成功させるのに必要な機能の実装を続けてきました。データ駆動型のテストを簡単に記述できるようにしましたし、Groovyをサポートすることでテストの記述をより素早く簡単にできるようにしました。作成したテストに新しい抽象レイヤを被せるのも簡単になりました。また、探索型テストを行うユーザを支援するために手動または自動でテストの各ステップを実行する機能を追加しました。つまり、私たちはテスターや開発者、ビジネスユーザが大規模なテストスイートを構築して利用し、メンテナンスすることを支援するツールを提供するというミッションを続けてきたということです。
InfoQ:ビジネスユーザが要求を表現するためにTwistを使ってシナリオを記述するときのことを詳しく教えてください。例えば、記述するにはどのような文法に通じてる必要があるのか、要求などを(入力補完を使って)ドキュメント化するのにTwistをどのように使えばいいのか、といったことです。
ビジネスユーザは最低でもTwistのシナリオを簡単に読めるだろうと想定しています。簡単なロジックが理解できてどのようなテストシナリオを作成すべきか考えられる、進んだユーザは機能テスト用のDSL(ドメイン特化言語)を使ってエディタでテストを構築できるでしょう。Twistは手動のテストもサポートしています。なので、技術に明るくないユーザがまずは手動テストを作成して、準備ができたら技術に詳しいユーザがそれを自動テストに変換するという方法もあります。
TwistのScenario Editor の正体はリッチテキストエディタです。このエディタを使えば、ビジネスユーザはテストに関連することなら何でも柔軟に記述できます。テストシナリオの実行可能な部分はDSLによって記述することができますが、ここは普通の英語(またはほとんどの他の言語)で記述できます。なので、実際は何か特別な文法を学ぶ必要はありません。私たちは既存のATDDやBDDのフレームワークよりも柔軟な方法を意識的に選択しました。マジックワードや負担になる文構造は必要ありません。
Control-Spaceを押せばエディタのどんな機能を使っていても自動補完/文脈補助機能を呼び出せます。なのでDSLを再利用するのはとても簡単になります。また、ダブルクオートで囲まれた文字列なら何でもパラメータとして解釈しますので、変数に関する複雑な文法はありません。とても簡単です。
InfoQ:JBehave、easyb、Cucumberのような他のBDDフレームワークと比べてTwistはどうでしょうか。
いくつか大きな違いがあります。まず、TwistはフレームワークというよりもIDEです。Twistはテスターや開発者、ビジネスユーザに対してIDEのサポートを提供するという考えに基づいて構築されています。個別のテストではなくテストスイートの取り扱いを簡単にすること、そして最終的にはテストスイートを管理することを支援します。テストスイートの管理はとても大きな課題です。また、Twistを使うことで、入力補完機能を使って作成したDSLがどのようなテストなのか簡単に把握することができます。さらに、コードだけでなく、作成したテストの挙動に対して抽象レイヤを被せることが簡単にできるようになりました。テストスイートのリファクタリングも簡単にできます。手動テストと自動テストを組み合わせる機能もあります。ほとんどのBDDツールは開発者のためのツールでテスターも少し使えるくらいのものですが、私たちが作ったのはテスター、開発者、そしてビジネスユーザのためのツールです。
InfoQ:Twist 2.0のデータ駆動テストシナリオ機能はDBUnitのようなほかのフレームワークと比べてどのような違いがありますか。
扱う対象が違うと思います。DBUnitの目的はテスト実行時にデータベースの整合性を維持するためのフレームワークです(実はTwistでテストを実行するときもDBUnitで準備と後処理をすることができます)。私たちは巨大なデータセットを使ってテストシナリオを実行する方法を提供しようとしてきました。例えば、下記のようなテストをTwistで書くことができます。ログイン時の銀行口座の統合:
ログインページ
- "johndoe"でパスワード"abc123"としてログイン
口座統合ページ
- 統合を促すプロンプトが表示されたら"受理"する
- プライマリの口座として"johndoe"を選択する
- ライセンス条項を同意する
- 口座の統合が成功したことを検証する
このテストを記述した後、異なる組み合わせのテストを分岐して作成したい場合は、クオートで囲まれた文字列に違う値を設定すれば実現できます。最後にこのテストを右クリックすれば自動的にデータテーブルが生成できます。このテーブルは特定のデータセットが設定でき、これを利用して任意の回数テストを実行できます。Twistが変数を管理してくれるのでテストシナリオをきれいなまま読みやすくしておけます。シナリオの中に変数を埋め込む必要はありません。このテーブルはFITのようなツールに見られる昔ながらの固定列に意味と意図が設定されているものと見なすことができるでしょう。
InfoQ:開発者がGroovyを使うことによって得られる現代的なプログラミングの特徴とはどんなものでしょう。
Groovyは動的言語なので十分な簡潔さと読みやすさを備えています。Groovyがクロージャをファーストクラスとして扱いますので、Javaでは厄介な作業も明らかに簡単になります。よく挙げられる例としてはコレクションの列挙があります。クロージャを使うことでコードも読みやすくなります。例えば、Groovyのオブジェクトのwith()は、SeleniumのフラットなAPIをよりきれいに見せることができます。Javaで下記のように書くかわりに、selenium.open("http://foo.com"); selenium.click("link=foobar"); assertTrue (selenium.isTextPresent("myfoo"));Groovyでは、
selenium.with { open "http://foo.com" click "link=foobar" assertTrue isTextPresent("myfoo") }
- また、Groovyの標準ライブラリはJavaが提供するものより優れています。例えば、多くの場合、よく使われるJDBCよりもgroovy.sqlのほうがDB関係の処理をシンプルに実現できます。またJavaの資産にアクセスできるのも大きな魅力です。
- さらにメタプログラミングのテクニックを利用できます。例えば、Seleniumに新たな機能を付け加えたい場合は、Seleniumのクラスにちょっとしたパッチをすぐに適用できます。Twistのテストシナリオにドライバを注入するのはデフォルトではSpringを使いますが、Groovyを使えば新しいサブクラスを作ってSpringを利用して実現するよりもすばやくパッチを適用できます。
InfoQ:"メンテナンスをシンプルに - アプリケーションの変更をテストスクリプトのリライトなしで" この一文はTwistの発表に含まれていました。この一文を詳しく説明していただけませんか。Twistはどのようにしてテストスクリプトの書き直しを防ぐのでしょう。
Twistは、十分に抽象的なテストシナリオはメンテナンスをしやすい、という考えに基づいて作られています。そしてそのようなシナリオは意味がしっかりしていて宣言的です。このボタンをクリックして、この文をウィジェットに記入して、このボックスにチェックをして...というやり方はSeleniumのような標準的なフレームワークで典型的に実施されている方法ですがメンテナンスしにくいです。こういった、どのように実行するかを気にすることなく、ウィジェットxを自分のショッピングカートに追加し、自分の請求先住所"abc"を追加してチェックアウトする、というように記述できれば、テストスイートのの部品となるブロックを手に入れられます。こうすることで一連の動作の基本になる仕組みが変更された場合は一箇所直すだけで済むようになります。GUIアプリのテストも失敗しにくくなります。
また、リファクタリングも重要な点です。TwistはDSLベースのテストシナリオとテストコード(Groovyのあるケースを除く)の間の双方向のリファクタリングをサポートします。なのでテストスイート全体にわたる変更がかなり簡単になります。例えば、アプリケーションのログインをユーザ名だけの入力からユーザ名とパスワードの入力へ変更したいとします。この場合、ログインのテストシナリオをユーザ名とパスワードを利用するように書き換えれば、テスト全体だけでなくコードにもその変更が適用されます。したがって、テストコードレベルでは、自動的に引数導出のリファクタリングをする必要はありません。テストシナリオが新しい引数を同じように反映してくれます。また、OpenIDを使いたいとします。この場合もコードレベルでログイン処理をオーバーロードすれば、テストシナリオはユーザ名とパスワードの組み合わせか、またはOpenIDを受け付けるようになります。つまり、複数のテストの書き直しをしなくても大きな変更を実施できます。
InfoQ:HudsonやSubversionのようなCIツールと組み合わせて独立した製品として利用することはできますか。
はい、Twistのテストシナリオは普通のテキストなのでどのようなソースコントロールシステムにもチェックインすることができます。また、どんなCI環境 (カスタムのAntタスクも一緒に同梱しています)とも一緒に利用できます。レポートの形式はJUnitの形式に従っていますので、標準的なビルドツールやCIツールでもレポートを解析できます。
InfoQ:機能拡充の観点からTwistのこれからのロードマップについて教えてください。
Scenario Editorの改善を続け、テストの作成とメンテナンスをよりシンプルで充実したものにするつもりです。探索型のテストもさらに簡単にできるようにしたいと思っています。テストの管理ももっと簡単にしたいですね。そして、他の私たちの製品であるMingleとCruiseとの統合も進めていきたいです。ほかにも色々なことを計画していますが、今のところ言えるのはこれだけです。