Seleniumテスト結果を見やすくするツール「Sahagin」を公開しました - Part 2
Part 1からの続きです。
インストール&利用方法(Java)
ここからは、Sahaginのインストール手順と利用方法について説明していきます。※1
1. 依存関係と実行時引数にsahagin.jarを追加
まずはsahagin.jarをJavaのテストコード中から利用するための設定です。
Mavenを使っている場合
この場合、pom.xmlファイルに対し、図1のように、dependenciesにsahaginを追加し、テスト実行時の引数にsahagin.jarを追加します。※2
<properties> <!-- バージョン番号は、その時の最新を指定 --> <sahagin.version>0.10.1</sahagin.version> </properties> ...中略.... <dependencies> <dependency> <groupId>org.sahagin</groupId> <artifactId>sahagin</artifactId> <version>${sahagin.version}</version> </dependency> </dependencies> ...中略.... <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.18(もしくはその他のバージョン)</version> <configuration> <argLine> -javaagent:${settings.localRepository}/org/sahagin/sahagin/${sahagin.version}/sahagin-${sahagin.version}.jar </argLine> </configuration> </plugin> </plugins> </build>
Gradleを使っている場合
この場合、build.gradleファイルに対し、図2のように、dependenciesとテスト実行時引数を指定します。
// バージョン番号は、その時の最新を指定 def sahaginVersion = '0.10.1' ...中略... dependencies { compile 'org.sahagin:sahagin:' + sahaginVersion } ...中略... test { doFirst { // ローカルキャッシュからsahaginのJarファイルを検索 def sahaginJar = project.configurations.testCompile.find { it.name == 'sahagin-' + sahaginVersion + '.jar' } jvmArgs '-javaagent:' + sahaginJar } }
ビルドツールを使わず、直接Jarを参照する場合
この場合、こちらからsahagin-0.10.1.zipをダウンロードして解凍し、sahagin-0.10.1.jarと、dependencyフォルダ以下にある依存Jarを、全てクラスパスに追加します。
テスト実行時には、JVMの引数に
-javaagent:<sahagin.jarのパス>
を指定します。
2. @TestDocアノテーションを付加
ページクラスのメソッドや共通メソッドに、@TestDocアノテーションを付けます(図4)。ページクラスがある場合は、クラス宣言に@PageDocアノテーション※3 を付けることで、現在のページ名をSahaginレポートに表示できます。
import org.sahagin.runlib.external.PageDoc; import org.sahagin.runlib.external.TestDoc; @PageDoc("問い合わせページ") public class ContactPage { @TestDoc("名前に「{name}」をセットする") public void setName(String name) { .... } @TestDoc("名前") public String getName() { .... } @TestDoc("メールアドレスに「{0}」をセットする") public void setMail(String email) { .... } .... }
@TestDocが無いメソッドもレポートに表示できるので、最初から全てのメソッドに@TestDocを付ける必要はありません。
その他注意点は次の通りです。
- {変数名}もしくは{0はじまりの引数インデックス}を指定することで、@TestDocに引数の内容を含めることができます。
- 「getName」などのget系メソッドの@TestDocは、「名前」のように名詞にするのがよいです。こうすると、例えば「assertEquals(contactPage.getName(), "ユーザーA")」は「『名前』が『ユーザーA』に等しいことをチェック」のように綺麗な日本語になります。
3. テスト前処理にコードを1行追加
JUnitの@Beforeのメソッドなどで、テストごとに利用するWebDriverインスタンスを「WebDriverAdapter.setAdapter」メソッドに渡します。(図5)
import org.sahagin.runlib.external.adapter.webdriver.WebDriverAdapter; public class SampleTest { @Before public void setUp() { wd = new FirefoxDriver(); WebDriverAdapter.setAdapter(wd); .... } }
ここで渡したWebDriverインスタンスは、画面キャプチャの取得に使用されます。
FluentLeniumを使用している場合はこちらの手順に、Appium・Selendroid・ios-driverを使用している場合はこちらの手順に従ってください。
4. 設定ファイルsahagin.ymlを作成
Javaプロジェクトの最上位ディレクトリに「sahagin.yml」という名前でファイルを作成し、図6のように設定を記述します。
# Sahagin設定ファイル。YAML形式で記述する。 java: # Javaのテストコードのあるディレクトリ # (絶対パスまたはこのYAMLファイルの場所からの相対パスで指定)。 # テストメソッドや@TestDocを付けたメソッドは、 # 全てこのディレクトリの下に存在する必要がある。 testDir: src/test/java
testDirの値は、テストコードのJavaファイルが置かれているディレクトリを指定してください。
5. テスト実行
準備ができたらJUnitテストを実行します。
Mavenを使っている場合
1.で作成したpom.xmlを使い、「mvn test」コマンドなどでテストを実行します。
- Mavenのコマンドを使ってテスト実行しないと、エラー等でうまくレポートが生成されないので注意してください。
- Mavenのデフォルトの設定では、ファイル名が「Test*.java」「*Test.java」「*TestCase.java」のテストしか実行されないので注意してください。
Gradleを使っている場合
1.で作成したbuild.gradleを使い、「gradle test」コマンドなどでテストを実行します。Gradleのコマンドを使ってテスト実行しないと、エラー等でうまくレポートが生成されないので注意してください。
ビルドツールを使わず、直接Jarを参照する場合
javaagent引数を指定して、Eclipseなどからテストを実行します。
テスト結果レポート
テストが完了すると、sahagin.ymlと同じディレクトリにsahagin-report/index.htmlが作成されています。(図7)
index.htmlの画面は見栄えがよくないので、もう少しなんとかしたいと思っています。
6. Jenkinsプラグインの設定
JenkinsのSahaginプラグインを使うと、出力されたSahaginレポートの内容をJenkinsの画面上で確認することができます。
まず、「Jenkinsの管理」>「プラグインの管理」>「利用可能」から「Sahagin Plugin」を選択してインストールし(図8)、Jenkinsを再起動します。
続いて、プロジェクトの「設定」の「ビルド後の処理の追加」から「Publish Sahagin HTML Report」を選択し、sahagin.ymlのパスを指定します。(図9)
この状態で、1.で作成したpom.xmlやbuild.gradleを使い、JenkinsからJUnitテストを実行すると、ビルド結果の画面にSahaginのレポート一覧へのリンクが表示されます。(図10)
プラグインを利用する場合も、「1.依存関係と実行時引数にsahagin.jarを追加」から「5.テスト実行」までのセットアップ手順は全て必要なので注意してください。プラグインだけで結果レポートが自動生成されるわけではありません。また、sahagin.jarのバージョンと、Sahagin Pluginのバージョンは、いつも同じ番号を使用するようにしてください。
さらに、「ビルド後の処理」で「JUnitテスト結果の集計」を行っている場合は、「Additional test report features」から「Add Sahagin test report link to each test result」を追加しておきましょう。(図11)
これでJUnitの各テスト結果画面にSahaginのレポートへのリンクが表示されます。 (図12)
Q&A
Q: 1つのテスト中で複数のWebDriverインスタンスを利用している場合、「WebDriverAdapter.setAdapter」メソッドの呼び出しはどうすればよいですか?
A: 現在利用しているWebDriverインスタンスが切り替わるたびに、setAdapterメソッドを呼び出してインスタンスを渡してください。
Q: 画面キャプチャ取得の際に独自の処理を行うには、どうすればよいですか?
A: 図13のようにして、画面キャプチャロジックに独自のものを使用できます。※4
import org.sahagin.runlib.external.adapter.webdriver.WebDriverAdapter; import org.sahagin.runlib.external.adapter.AdapterContainer; import org.sahagin.runlib.external.adapter.ScreenCaptureAdapter; public class SampleTest { @Before public void setUp() { wd = new FirefoxDriver(); // 独自の画面キャプチャ取得ロジックを指定する場合も、setAdapterは呼び出す WebDriverAdapter.setAdapter(wd); AdapterContainer.globalInstance().setScreenCaptureAdapter(new ScreenCaptureAdapter() { public byte[] captureScreen() { ((TakesScreenshot) wd).getScreenshotAs(OutputType.BYTES) // など独自の画面キャプチャ取得ロジック } }); .... } }
Q: 画面キャプチャを取得したくない場合はどうすればよいですか?
A: 図14のようにsetScreenCaptureAdapterメソッドにnullを指定することで、画面キャプチャを取得しないようにすることができます。なお、現状WebDriverインスタンスは画面キャプチャ取得にしか利用していませんが、今後他の用途にも利用する可能性があるので、画面キャプチャが不要な場合もsetAdapterは呼び出しておくことをお勧めします。
import org.sahagin.runlib.external.adapter.webdriver.WebDriverAdapter; import org.sahagin.runlib.external.adapter.AdapterContainer; public class SampleTest { @Before public void setUp() { wd = new FirefoxDriver(); WebDriverAdapter.setAdapter(wd); AdapterContainer.globalInstance().setScreenCaptureAdapter(null); .... } }
Q: sahagin.ymlのファイル名や配置ディレクトリを変更するには、どうすればよいですか?
A: Mavenを使っている場合は図15、Gradleを使っている場合は図16、ビルドツールを使わず直接sahagin.jarを参照している場合は図17のように、「sahagin.configPath」システムプロパティでSahagin設定ファイルのパスを指定してください。 (以前は-javaagentオプションの引数で指定していましたが、バージョン0.8.1以降では非推奨です。)
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <configuration> <argLine> -Dsahagin.configPath={Sahagin設定ファイルのパス} </argLine> </configuration> </plugin> </plugins> </build>
test { systemProperty 'sahagin.configPath', 'Sahagin設定ファイルのパス' }
-Dsahagin.configPath=<Sahagin設定ファイルのパス>
Q: Sahaginレポートの出力先ディレクトリを変更するにはどうすればよいですか?
A: sahagin.yml中に図18の設定を追加し、reportOutputDirの値を変更してください。
common: # レポートの出力先 reportOutputDir: sahagin-report
Q: JUnit3のテスト結果レポートがうまく表示されません。
A: Sahaginのバージョンを0.8以上にし、sahagin.yml中に図19の設定を行ってください。
java: # テストをJUnit3形式として扱う。大文字小文字に注意 testFramework: jUnit3
Q: TestNGのテスト結果レポートがうまく表示されません。
A: Sahaginのバージョンを0.8以上にし、sahagin.yml中に図20の設定を行ってください。
java: # テストをTestNG形式として扱う。大文字小文字に注意 testFramework: testNG
Q: 最近のJenkinsでテスト結果レポートが崩れて表示されます。
A: ブラウザのコンソールでエラーが出ていないか確認してください。エラーが出ている場合は、JenkinsのセキュリティポリシーによりJavaScriptが実行できなくなっている可能性が高いです。対処策はこちらの記事を参考にしてください。
既知の問題
- 「@Test(expected = ...)」やExpectedExceptionで例外が出ることを確認しているテストをうまく扱えない。
- 継承元メソッド・オーバーライドされたメソッド・抽象メソッドの内容がうまくレポートに表示されない。(→バージョン0.3で対応済)
- Safariでレポートがうまく表示されない。
- Windows上のFirefoxでレポートがうまく表示されない。(→バージョン0.3.1で対応済)
- Windows上でレポートの画面キャプチャがぼやけて見える。
- ParameterizedやTheoriesを使ったデータ駆動テストへの対応。
- 英語と日本語が混在しているので、適切に言語設定できるように。(→バージョン0.3で対応済)
- return、if、for、whileなどのキーワードに対応。※5
上記は早めに対応する予定です。その他の問題はissuesに記載しています。他に要望等があれば、このブログへのコメントか、GitHubの日本語issueにお願いします。
あとは、CucumberなどのBDD系ツールで記述されるGiven・When・Then等のキーワードの内容も取り込んでレポートに表示すれば、テストの仕様も実装も分かりやすく同じレポートで表示できていいんじゃないかと思っています。
注釈・出典
- 記事中のバージョン番号等は、随時最新のものに更新しています。
- メソッド呼び出しをフックするためにバイトコード操作を行っているので、-javaagentオプションでJarファイルを指定する必要があります。
- 以前は@Pageアノテーションを使用していましたが、バージョン0.8.1以降では非推奨です。
- Sahaginバージョン0.6以前の場合、メソッド名が「captureScreen」でなく「captueScreen」になっています。バージョン0.7以降をご利用ください。
- 対応キーワードについては、全て対応してしまうとプログラミング言語丸ごと日本語化することになってしまうので、Seleniumテストを記述する上で必要な語彙に絞って対応していく予定です。