Truthのアサーション記述例を紹介します。
Kotlinは「is」が予約語になっているので、Hamcrestで記述すると「`is`」になってしまいます。Java⇒Kotlinの自動変換を行ったら現れたのです。最初、変換ミスかと思いました。
動作に関係のない文字が入るのは嫌いです。
何か解決策はないかと、最近購入した書籍「みんなのKotlin」を見ていたらTruthがあるのを知りました。なかなか良いかも!
なので、今までHamcrestを使っていましたがTruthへ乗り換えます。
目次
スポンサーリンク
Truthとは
TruthはAssertJやHamcrestと同じアサーションライブラリの一つです。
AndroidX Testの一部としてリリースされていて、現在(2020年9月)最新版はVer1.3.0になっています。積極的な開発が行われているようです。また、Truthの標準的なアサーション構文に加えて、Android向けの構文が存在しています。とても興味深いところです。今後、Androidと親和性が増していきそうな感じです。
Truthのさらなる情報はここを参照してください。
スポンサーリンク
環境設定
Truthを使うためにライブラリの依存リストへ次の一行を追加します。
dependencies { ... androidTestImplementation 'androidx.test.ext:truth:1.3.0' ... }
\--- androidx.test.ext:truth:1.3.0 +--- androidx.test:core:1.3.0 (*) +--- com.google.guava:guava:27.0.1-android +--- com.google.truth:truth:1.0 \--- androidx.annotation:annotation:1.0.0
AndroidX(androidx.test.ext:truth)に組み困れているTruth本体(com.google.truth:truth)のバージョンはリリースノートを参照してください。
スポンサーリンク
アサーション記述例(標準的な構文)
※アサーション記述例は全てPassします
※Kotlinのコードのみ
Null
Kotlin
@Test fun Nullテスト() { val s: String = "Yamada" val n: String? = null assertThat(n).isNull() // nは Null である assertThat(s).isNotNull() // sは Null でない }
Number
Kotlin
@Test fun Numberテスト() { val n: Int = 5 assertThat(n).isEqualTo(5) // nは 5 と同じである assertThat(n).isNotEqualTo(0) // nは 0 と同じでない assertThat(n).isGreaterThan(4) // nは n>4 である assertThat(n).isLessThan(6) // nは n<6 である assertThat(n).isAtLeast(5) // nは n≧5 である assertThat(n).isAtMost(5) // nは n≦5 である assertThat(n).isIn(1..10) // nは 1~10 内である assertThat(n).isNotIn(6..10) // nは 6~10 内でない assertThat(n).isAnyOf(4, 5, 6) // n は 4,5,6 のいずれかである }
Boolean
Kotlin
@Test fun Booleanテスト() { val t: Boolean = true val f: Boolean = false assertThat(t).isEqualTo(true) // tは true と同じである assertThat(f).isNotEqualTo(true) // fは true と同じでない assertThat(t).isTrue() // tは true である assertThat(f).isFalse() // fは false である }
String
Kotlin
@Test fun Stringテスト() { val s: String = "abcdefg" val e: String = "" assertThat(s).isEqualTo("abcdefg") // sは "abcdefg" と同じである assertThat(s).isNotEqualTo("hijklmn") // sは "hijklmn" と同じでない assertThat(s).startsWith("abc") // sは "abc" で始まる assertThat(s).endsWith("efg") // sは "efg" で終わる assertThat(s).contains("cde") // sは "cde" を含む assertThat(s).doesNotContain("c_e") // sは "c_e" を含まない assertThat(s).matches("a.*g") // sは 正規表現:"a.*g" に一致する assertThat(s).doesNotMatch("h.*n") // sは 正規表現:"h.*n" に一致しない assertThat(s).containsMatch("c.e") // sは 正規表現:"c.e" に一致する部分を含む assertThat(s).doesNotContainMatch("j.k") // sは 正規表現:"j.k" に一致する部分を含まない assertThat(s).isAnyOf("123", "abcdefg", "456") // sは 指定要素 のいずれかである assertThat(e).isEmpty() // eは空である assertThat(s).isNotEmpty() // sは空でない assertThat(s).hasLength(7) // sは 7 の長さを持つ }
Array
Kotlin
@Test fun Arrayテスト(){ val c: Array<String> = arrayOf("abc", "def", "ghi") val e: Array<String> = arrayOf() assertThat(c).isEqualTo(arrayOf("abc", "def", "ghi")) // cは 指定配列 と同じである assertThat(c).isNotEqualTo(arrayOf("abc", "jkl", "ghi")) // cは 指定配列 と同じでない assertThat(c).hasLength(3) // cは 3 の長さを持つ assertThat(e).isEmpty() // eは空である assertThat(c).isNotEmpty() // cは空でない }
List
Kotlin
// ・containsAllOf()/containsAllIn() はTruth 0.46で廃止されました。 // 代わりにcontainsAtLeast()/containsAtLeastElementsIn()を使います。 @Test fun Listテスト(){ val l: List<String> = listOf("Tokyo", "Osaka", "Nagoya") val e: List<String> = listOf() // ※Listは順番を問うコレクションである assertThat(l).isEqualTo(listOf("Tokyo", "Osaka", "Nagoya")) // lは 指定リスト (順番&数一致)と同じである assertThat(l).isNotEqualTo(listOf("Tokyo", "Osaka", "A")) // lは 指定リスト (順番&数一致)と同じでない assertThat(l).isNotEqualTo(listOf("Nagoya", "Osaka", "Tokyo")) // lは 指定リスト (順番&数一致)と同じでない assertThat(l).isNotEqualTo(listOf("Tokyo", "Osaka")) // lは 指定リスト (順番&数一致)と同じでない assertThat(l).contains("Osaka") // lは 指定の要素 を含む assertThat(l).doesNotContain("A") // lは 指定の要素 を含まない assertThat(l).containsExactly("Tokyo", "Nagoya", "Osaka") // lは 指定要素 の全て(順番不問、数一致)を含む // assertThat(l).containsAllOf("Nagoya", "Tokyo") // lは 指定要素 の全て(順番不問、数不問)を含む assertThat(l).containsAtLeast("Nagoya", "Tokyo") // lは 少なくとも指定要素(順番不問、数不問)を含む assertThat(l).containsAnyOf("A", "Nagoya", "B") // Lは 指定要素 のいずれかを含む assertThat(l).containsNoneOf("A", "B") // lは 指定要素 の全てを含まない // assertThat(l).containsAllIn(listOf("Nagoya", "Tokyo")) // Lは 指定リスト の要素の全て(順番不問、数不問)を含む assertThat(l).containsAtLeastElementsIn(listOf("Nagoya", "Tokyo"))// Lは 少なくとも指定リスト の要素(順番不問、数不問)を含む assertThat(l).containsAnyIn(listOf("A", "Nagoya", "B")) // Lは 指定リスト の要素のいずれかを含む assertThat(l).containsNoneIn(listOf("A", "B")) // lは 指定リスト の要素の全てを含まない assertThat(l).containsNoDuplicates() // L は 重複した要素 を含まない assertThat(l).hasSize(3) // Lは 3 のサイズを持つ assertThat(e).isEmpty() // eは 空 である assertThat(l).isNotEmpty() // lは 空 でない }
Map
Kotlin
@Test fun Mapテスト(){ val m: Map<String, Int> = mapOf("Tokyo" to 3, "Nagoya" to 52, "Osaka" to 6) val e: Map<String, Int> = mapOf() // ※Mapは順番を問わないコレクションである assertThat(m).isEqualTo(mapOf("Tokyo" to 3, "Nagoya" to 52, "Osaka" to 6)) // mは 指定マップ(順番不問&数一致)と同じである assertThat(m).isEqualTo(mapOf("Nagoya" to 52, "Osaka" to 6, "Tokyo" to 3)) // mは 指定マップ(順番不問&数一致)と同じである assertThat(m).isNotEqualTo(mapOf("Tokyo" to 3, "Nagoya" to 52, "A" to 0)) // mは 指定マップ(順番不問&数一致)と同じでない assertThat(m).isNotEqualTo(mapOf("Tokyo" to 3, "Nagoya" to 52)) // mは 指定マップ(順番不問&数一致)と同じでない assertThat(m).containsEntry("Osaka", 6) // mは 指定エントリー を含む assertThat(m).doesNotContainEntry("A", 0) // mは 指定エントリー を含まない assertThat(m).containsKey("Osaka") // mは 指定キー を含む assertThat(m).doesNotContainKey("A") // mは 指定キー を含まない assertThat(m).containsExactly("Nagoya", 52, "Osaka", 6, "Tokyo", 3) // mは 指定エントリーの全て(順番不問、数一致)を含む assertThat(m).containsExactlyEntriesIn(mapOf("Osaka" to 6, "Tokyo" to 3, "Nagoya" to 52)) // isEqualToと同じ assertThat(m).hasSize(3) // mは 3 のサイズを持つ assertThat(e).isEmpty() // eは空である assertThat(m).isNotEmpty() // mは空でない }
Instance
Kotlin
// ・isSameAs()/isNotSameAs() はTruth 0.45で廃止されました。 // isSameInstanceAs()/isNotSameInstanceAs()を使います。 @Test fun Instanceテスト(){ val s: SampleA = SampleA() val t: SampleA = SampleA() val u: SampleB = SampleB() val o: SampleA = s // assertThat(s).isSameAs(o) // sは o と同じインスタンスである assertThat(s).isSameInstanceAs(o) // sは o と同じインスタンスである // assertThat(s).isNotSameAs(t) // sは t と同じインスタンスでない assertThat(s).isNotSameInstanceAs(t) // sは t と同じインスタンスでない assertThat(s).isInstanceOf(SampleA::class.java) // sは SampleAクラス のインスタンスである assertThat(s).isNotInstanceOf(SampleB::class.java) // sは SampleBクラス のインスタンスでない }
Exception
Kotlin
@Test fun Exception(){ val e: Exception = IllegalArgumentException("Must be AAA") val x: Exception = Exception("Argument?", e) assertThat(e).isInstanceOf(IllegalArgumentException::class.java) // ↑ eは IllegalArgumentExceptionクラス のインスタンスである assertThat(e).hasMessageThat().isEqualTo("Must be AAA") // ↑ eが持つメッセージは "Must be AAA" と同じである assertThat(x).isInstanceOf(Exception::class.java) // ↑ xは Exceptionクラス のインスタンスである assertThat(x).hasMessageThat().isEqualTo("Argument?") // ↑ xが持つメッセージは "Argument" と同じである assertThat(x).hasCauseThat().isInstanceOf(IllegalArgumentException::class.java) // ↑ xが持つCauseは IllegalArgumentExceptionクラス のインスタンスである assertThat(x).hasCauseThat().hasMessageThat().isEqualTo("Must be AAA") // ↑ xが持つCauseのメッセージは "Must be AAA" と同じである }
スポンサーリンク
アサーション記述例(Android向け構文)
表にあげた構文がサポートされています。
さらなる詳細は各Subjectのドキュメントを参照してください。
Subject | Package | 記述例 |
---|---|---|
BundleSubject | androidx.test.ext.truth.os | 〇 |
IntentSubject | androidx.test.ext.truth.content | 〇 |
NotificationActionSubject | androidx.test.ext.truth.app | |
NotificationSubject | ||
PendingIntentSubject | ||
MotionEventSubject | androidx.test.ext.truth.view | |
PointerCoordsSubject | ||
PointerPropertiesSubject |
※アサーション記述例は全てPassします
※Kotlinのコードのみ
Bundle
Kotlin
@Test fun Bundleテスト(){ val b: Bundle = Bundle() b.putInt("ikey", 1) b.putLong("lkey", 2L) b.putBoolean("bkey", true) b.putString("skey", "abc") val bSub_b: BundleSubject = BundleSubject.assertThat(b) bSub_b.containsKey("ikey") // bは Key="ikey" を含む bSub_b.doesNotContainKey("xkey") // bは Key="xkey" を含まない bSub_b.integer("ikey").isEqualTo(1) // bのintegerは 1 と同じである bSub_b.longInt("lkey").isEqualTo(2L) // bのlongは 2 と同じである bSub_b.bool("bkey").isTrue() // bのboolは true である bSub_b.string("skey").isEqualTo("abc") // bのstringは "abc" と同じである }
Intent
Kotlin
@Test fun Intentテスト(){ val i: Intent = Intent() i.putExtra("ikey", 1) i.putExtra("lkey", 2L) i.putExtra("bkey", true) i.putExtra("skey", "abc") val uri = Uri.parse("file:///sdcard/SampleText.txt") val j: Intent = Intent(Intent.ACTION_VIEW) j.setDataAndType(uri, "text/plain") val m: Intent = Intent(Intent.ACTION_VIEW) m.setDataAndType(uri, "text/plain") val context: Context = InstrumentationRegistry.getInstrumentation().targetContext val k: Intent = Intent(context, MainActivity::class.java) val bSub_i: BundleSubject = IntentSubject.assertThat(i).extras() val iSub_i: IntentSubject = IntentSubject.assertThat(i) val iSub_j: IntentSubject = IntentSubject.assertThat(j) val iSub_k: IntentSubject = IntentSubject.assertThat(k) bSub_i.integer("ikey").isEqualTo(1) // iのintegerは 1 と同じである bSub_i.longInt("lkey").isEqualTo(2L) // iのlongは 2 と同じである bSub_i.bool("bkey").isEqualTo(true) // iのboolは true と同じである bSub_i.string("skey").isEqualTo("abc") // iのstringは "abc" と同じである iSub_i.hasNoAction() // iは Action を持たない iSub_j.hasAction(Intent.ACTION_VIEW) // jは Action=ACTION_VIEW を持つ iSub_j.hasData(Uri.parse("file:///sdcard/SampleText.txt")) // jは Uri="file:..." を持つ iSub_j.hasType("text/plain") // jは Type="text/plain" を持つ iSub_j.filtersEquallyTo(m) // jは m と同じフィルターである iSub_k.hasComponentClass("パッケージ名.MainActivity") // kは Class=MainActivity を持つ iSub_k.hasComponentClass(MainActivity::class.java) // kは Class=MainActivity を持つ iSub_k.hasComponentPackage("パッケージ名") // kは Package=パッケージ名 を持つ }
スポンサーリンク
スポンサーリンク