5
3

More than 1 year has passed since last update.

【Android】テストを書くときに使う@get:RuleとかRuleChainってなんぞよ

Last updated at Posted at 2023-01-10

はじめに

Androidでインストゥルメント化単体テストを作成するとき、@get:Ruleを使ってテストを書いたことはありませんか?

@HiltAndroidTest
class AppTest {

    private val hiltRule = HiltAndroidRule(this)
    private val composeTestRule = createAndroidComposeRule<MainActivity>()

    @get:Rule
    val rule: RuleChain = RuleChain
        .outerRule(hiltRule)
        .around(composeTestRule)
    ...
}

この、@get:RuleRuleChain.outerRule().around()がよくわからない状態で、今まではテストを書いてきました。

ということで今回は、@get:RuleとかのRuleってなんぞやということをまとめていきたいと思います。

Ruleとは何なのか

公式ドキュメントにて、次の一文を発見しました。

JUnit ルールはテストの柔軟性を高め、必要なボイラープレート コードを削減します。
https://developer.android.com/training/testing/junit-rules?hl=ja

Guide to JUnit 4 Rulesの記事内で、次のような記述を見つけました。

JUnit 4 rules provide a flexible mechanism to enhance tests by running some code around a test case execution. In some sense, it’s similar to having @Before and @After annotations in our test class.

https://www.baeldung.com/junit-4-rules

そして、次の一文。

By using a rule, we can have everything isolated in one place and reuse the code easily from multiple test classes.
https://www.baeldung.com/junit-4-rules

つまり、今まで@Before@Afterを使って行っていた処理をルールとしてまとめることで、いろいろなテストから呼び出せるようになり再利用できるようになる。これこそがルールのメリットということです。

例えば、@Beforeでデータベースに接続して、@Afterで接続を解除するという処理をルールとしてまとめることで、いろいろなテストで何度も同じ処理を書かずに済むといったことが可能となります。

RuleChainとは何なのか

実は、RuleChainもルールです。なので、ドキュメントなどではThe RuleChain rule ...などと書かれたりします。

このRuleChainを使うと、ルールの順序づけを行うことができるようになります。

RuleChainが一番使われるユースケースは、複数のルールを順序通りに実行した上で各テストケースを実行したい場合です。

RuleChainを使わなくても、テストに複数のルールを配置することは可能です。しかし、その際に実行されるルールの順番はランダムになります。この順番をコントロールするために、RuleChainは使われます。

最初に実行したいルールをouterRule()を使って指定します。次に続くルールは順番にaround()を呼び出しすことで繋げていきます。

private val hiltRule = HiltAndroidRule(this)
private val composeTestRule = createAndroidComposeRule<MainActivity>()

@get:Rule
val rule: RuleChain = RuleChain
    .outerRule(hiltRule)
    .around(composeTestRule)

ちなみに、@get:Rule@Ruleの違いは?

Javaでは、@Ruleを使ってルールを指定します。

しかし、Kotlinで同じように@Ruleを使おうとするとエラーが出てしまうようです。

Kotlinでは、@get:Ruleを使ってルールを宣言することで、getterプロパティに対して@Ruleアノテーションを適用するという意味を持たせることができます。

これにより、エラーの発生を抑えて安心してルールを使えるようになります。

...省略

class Tests {
    // apply @Rule annotation to property getter
    @get:Rule val tempFolder = TemporaryFolder()

    @Test fun simple() {
        val f = tempFolder.newFile()
        assertEquals(42, getTheAnswer())
    }
}

まとめ

久しぶりに、Androidのインストゥルメント化単体テストを書こうと思ったときに、過去に自分が書いたテストに@get:Ruleが存在したため、ルールってなんだっけって思ったところがこの記事の出発点でした。

今回はあくまで用語解説に過ぎないので、いつかルールを自分で書いてみた記事も公開できればよいなと思います。

参考にした記事

5
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
3