同じテストメソッドを複数パラメータでテストする
テストを実行する際、同じシナリオに対して異なるパラメータを入力して繰り返しテストしたい場合があります。
JUnit4では、このような場合に利用できる仕組みとして、Parameterized Runnerが用意されています。
Parameterized Runnerでは、テストクラス実行時にパラメータのリストを読み込み、各テストメソッドをパラメータの行数分繰り返し実行します。
PitaliumではCapability(実行ブラウザ)の指定にParameterizedの機能を利用しており、テスト用に独自のパラメータを追加する際には工夫する必要があります。
独自パラメータの追加
Parameterized利用前:パラメータを直接テストコードに記載
例として、以下のようなテストを考えます。
- hifiveトップページを開く。
- 検索フォームにキーワードを入力して検索ボタンを押す。
- 検索結果のリンクをクリックする。
- 遷移先のページのタイトルを確認する。
テストコード内に直接パラメータを記載する場合、次のようになります。
/**
* hifiveトップページを開き、検索を行う。
*/
@Test
public void searchTest() {
// トップページを開く
driver.get("");
// ロードの完了を待つ(hifiveサイトではfacebookプラグインの表示)
PtlWebDriverWait wait = new PtlWebDriverWait(driver, 1800);
wait.until(ExpectedConditions
.presenceOfElementLocated(By.cssSelector("iframe[title=\"fb:like_box Facebook Social Plugin\"]")));
// キーワードで検索
driver.findElementById("headerglobalsearchinput").sendKeys("hifive");
driver.findElementByCssSelector("#globallinks > form > div > input.button").click();
// 検索結果のリンクをクリック
driver.findElementByLinkText("リリースノート一覧").click();
// ページタイトルを確認
wait.untilLoad();
assertThat(driver.getTitle(), is("リリースノート一覧 - hifive"));
}
}
Parameterized利用後
この例において、次の3項目をパラメータとして読み込むことを考えます。
- 検索キーワード:"hifive"
- クリックするリンクのタイトル:"リリースノート一覧"
- 表示されるページのタイトル(期待結果):"リリースノート一覧 - hifive"
必要な変更は以下の2点です。
- パラメータ項目(今回は上記の3つ)を格納する変数をそれぞれ追加する。
- パラメータ変数に値を渡すメソッドを記述する。その際、Pitaliumで元々読み込んでいるCapabilityの値も併せて渡すようにする。
パラメータ変数の追加
まず、パラメータ項目を格納するメンバ変数を追加します。
変数にはそれぞれ@Parameter(パラメータ番号)のアノテーションをつけます。
なお、@Parameter(0)はCapabilityの読み込みに使用しているため、@Parameter(1)以降を使用して下さい。
/**
* 検索キーワード
*/
@Parameter(1)
public String keyword;
/**
* クリックするリンクの文字列
*/
@Parameter(2)
public String linkText;
/**
* 表示されるページのタイトル(期待結果)
*/
@Parameter(3)
public String expectedTitle;
パラメータの値をセットするメソッドの追加
@Parameters アノテーションをつけたメソッドで、パラメータ配列のリストを返すように実装します。
すると、配列の各要素がパラメータ変数に代入され、各テストがリストの長さ分だけ繰り返し実行されるようになります。
※ name = "{0}, keyword={1}, linkText={2}, expectedTitle={3}" の部分は、
JUnit実行時のパラメータの表示名を定義しています。上記のように指定すると、パラメータ毎のテストの実行結果が
searchTest [Capabilities[{os=Windows, browserName=firefox,(略)}, keyword=hifive, linkTest=リリースノート一覧, expectedTitle=リリースノート一覧 - hifive]
のように表示されます。
定義しない場合、searchTest[0] searchTest[1] のような表示になります。
* パラメータの値を読み込んでセットする。
*/
@Parameters(name = "{0}, keyword={1}, linkText={2}, expectedTitle={3}")
public static Iterable<Object[]> readTestParam() {
List<PtlCapabilities[]> capabilities = readCapabilities(); // capabilitiesを取得
// パラメータに代入する値のリスト
Object[][] data = new Object[][] {
{ "hifive", "リリースノート一覧", "リリースノート一覧 - hifive" },
{ "pitalium", "Pitalium(hifiveリグレッションテストライブラリ)", "Pitalium(hifiveリグレッションテストライブラリ) - hifive" }
};
List<Object[]> parameters = new ArrayList<>();
for (PtlCapabilities[] capability : capabilities) {
for (int i = 0; i < data.length; i++) {
parameters.add(new Object[] { capability[0], data[i][0], data[i][1], data[i][2] }); // 最初の要素はcapabilityとする
}
}
return parameters;
}
テストコード内のパラメータを変数に置換
"hifive" "リリースノート一覧" などの値を記載していた部分を、定義したパラメータ変数に置き換えます。
変更後のコード
完成したコードは次のようになります。
// @Parameter(0) はCapabilityに使用
/**
* 検索キーワード
*/
@Parameter(1)
public String keyword;
/**
* クリックするリンクの文字列
*/
@Parameter(2)
public String linkText;
/**
* 表示されるページのタイトル(期待結果)
*/
@Parameter(3)
public String expectedTitle;
/**
* パラメータの値を読み込んでセットする。
*/
@Parameters(name = "{0}, keyword={1}, linkText={2}, expectedTitle={3}")
public static Iterable<Object[]> readTestParam() {
List<PtlCapabilities[]> capabilities = readCapabilities(); // capabilitiesを取得
// パラメータに代入する値のリスト
Object[][] data = new Object[][] {
{ "hifive", "リリースノート一覧", "リリースノート一覧 - hifive" },
{ "pitalium", "Pitalium(hifiveリグレッションテストライブラリ)", "Pitalium(hifiveリグレッションテストライブラリ) - hifive" }
};
List<Object[]> parameters = new ArrayList<>();
for (PtlCapabilities[] capability : capabilities) {
for (int i = 0; i < data.length; i++) {
parameters.add(new Object[] { capability[0], data[i][0], data[i][1], data[i][2] }); // 最初の要素はcapabilityとする
}
}
return parameters;
}
/**
* hifiveトップページを開き、検索を行う。
*/
@Test
public void searchTest() {
// トップページを開く
driver.get("");
// ロードの完了を待つ(hifiveサイトではfacebookプラグインの表示)
PtlWebDriverWait wait = new PtlWebDriverWait(driver, 1800);
wait.until(ExpectedConditions
.presenceOfElementLocated(By.cssSelector("iframe[title=\"fb:like_box Facebook Social Plugin\"]")));
// キーワードで検索
driver.findElementById("headerglobalsearchinput").sendKeys(keyword);
driver.findElementByCssSelector("#globallinks > form > div > input.button").click();
// 検索結果のリンクをクリック
driver.findElementByLinkText(linkText).click();
// ページタイトルを確認
wait.untilLoad();
assertThat(driver.getTitle(), is(expectedTitle));
}
}
外部ファイルからのデータ読み込み
@Parametersアノテーションをつけたメソッドで値を外部ファイルから読み込むようにすれば、
外部ファイルで定義したパラメータをもとにテストを実行することも可能です。
以下、CSVファイルからの読み込み例です。(CSVの読み込みに、OpenCSVのライブラリを使用しています)
sample.csv
hifive,リリースノート一覧,リリースノート一覧 - hifive
pitalium,Pitalium(hifiveリグレッションテストライブラリ),Pitalium(hifiveリグレッションテストライブラリ) - hifive
readTestParamメソッド
* パラメータの値を読み込んでセットする。
*/
@Parameters(name = "{0}, keyword={1}, linkText={2}, expectedTitle={3}")
public static Iterable<Object[]> readTestParam() {
List<PtlCapabilities[]> capabilities = readCapabilities(); // capabilitiesを取得
// CSVファイルを読み込み
List<String[]> additionalParams = null;
try (InputStream inputStream = new FileInputStream("sample.csv");
InputStreamReader isReader = new InputStreamReader(inputStream, "UTF-8");
CSVReader reader = new CSVReader(isReader, ',', '"', 1); // ヘッダを読み飛ばす
) {
additionalParams = reader.readAll();
} catch (FileNotFoundException e) {
// TODO: Error Handling
e.printStackTrace();
} catch (IOException e) {
// TODO: Error Handling
e.printStackTrace();
}
List<Object[]> parameters = new ArrayList<>();
for (PtlCapabilities[] capability : capabilities) {
for (String[] params : additionalParams) {
parameters.add(new Object[] { capability[0], params[0], params[1], params[2] });
}
}
return parameters;
}