🤜

Junit4でパラメータを色々変えたUIテストをしたい

2022/01/04に公開

キーワード

UI Test,JUnit4,繰り返し(loop),引数(argument),パラメータ(parameter)

したいこと

TextFieldに入力された文字列に応じてUIが変わるViewを実装をしたときに、このViewが予期した動きをするか調べたい。
どんな感じでやりたいかというと、以下のような感じ。


val valueTest = listOf(
	"Nyao",
	"Wan",
	"ChunChun",
)

@Test
fun manageTest() {
	valueTest.forEach { val ->
		inputTest(val)
	}
}

@Test
fun inputTest(str: String) {
	composeTestRule.onNodeWithText("Input").performTextInput(str)
	composeTestRule.onNode(expectValue(str)).assertIsDisplayed()
}

fun expectValue(str: String): String {
  var result = ""
  if(str == "Nyao") {
	  result = "(ΦωΦ)"
  } else if (str == "Wan") {
	  result = "U^ェ^U"
  } else {
	  result = "(´・ω・`)"
  }
  return result
}

やり方

Parameterizedテストでやる方法

yanzmさんの記事[1]を参考に、テストのクラスのコンストラクタ引数に入れてしまう方法です。

@RunWith(Parameterized::class)
class InputViewKtTestPara (private val str: String) {

	@Test
	fun inputTest() {
		composeTestRule.onNodeWithText("Input").performTextInput(str)
		composeTestRule.onNode(expectValue(str)).assertIsDisplayed()
	}
	
	companion object {
		@Parameterized.Parameters
		@JvmStatic
		fun data(): Iterable<String> {
		    return listOf(
			"Nyao",
			"Wan",
			"ChunChun",
		    )
		}
	    }
	fun expectValue(str: String): String {
		  var result = ""
		  if(str == "Nyao") {
			  result = "(ΦωΦ)"
		  } else if (str == "Wan") {
			  result = "U^ェ^U"
		  } else {
			  result = "(´・ω・`)"
		  }
		  return result
	}
}

このやり方だと、クラスでいくつかのメソッドを持った時に、各メソッドに違う値を入れたい時に少し苦労します。しかし、単一の種類のデータであれば、これが一番楽だと思います。

@Testアノテーションを付けないmethodを組み合わせる

例えば、"Wan"と入力した後に"Nyao"と入力した結果をテストしたい、など入力値の組み合わせや、methodごとに異なる種類のデータを入れたいときは、もっと柔軟にしたほうが良いことがあります。今回は、3つの値なので、1つの値を入れたときのテストは3種類、2つの値を入れるときは順序考慮で6通り、3つの値を入れるときは順序考慮で6通りあり、合わせて15通りあることになります。これを配列で用意するのは現実的ではなく、loop関数で自動で行いたいこともあるでしょう。
その時は@Testアノテーションを付けないmethodを用意して、実行するのが良いと思います。

val valueTest = listOf(
	"Nyao",
	"Wan",
	"ChunChun",
)

@Test
fun manageTest() {
	valueTest.forEach { val ->
		inputTest(val)
	}
}

fun inputTest(str: String) {
	composeTestRule.onNodeWithText("Input").performTextInput(str)
	composeTestRule.onNode(expectValue(str)).assertIsDisplayed()
}

fun expectValue(str: String): String {
  var result = ""
  if(str == "Nyao") {
	  result = "(ΦωΦ)"
  } else if (str == "Wan") {
	  result = "U^ェ^U"
  } else {
	  result = "(´・ω・`)"
  }
  return result
}
脚注
  1. Android で Parameterized テスト(JUnit4, Robolectric)を行う / yanzm http://y-anz-m.blogspot.com/2018/03/android-junit4-parameterized.html (2022-01-04閲覧) ↩︎

Discussion