1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Instrumented Testの実行中に画面が消えないようにする

Posted at

Instrumented Testで画面を動かしている途中で画面が消灯してしまうと、多くの場合テストに失敗する。
ということで、その対処法をお手軽順に書いておく。

スリープモードにしない

設定の[開発者向けオプション]-[スリープモードにしない]を有効にする。
常用していない端末ならこれで済む。
常用端末を開発でも使っている場合は、この機能は必ずしも嬉しくないので次へ。

UiDevice#wakeUp()

UIAutomatorのAPIで、定期的に起こす案。
実行時間が長いテストは多くの場合何かしらの繰り返しになっているはずで、繰り返しの先頭にこれを入れれば何となく動く(かもしれない)。
かなり雑な対応で、必ず成功するかはなんとも言えない。
とはいえ、これを一箇所入れれば解決する、ということであれば選択肢としてはあり。

MainActivityTest.kt
@RunWith(AndroidJUnit4::class)
class MainActivityTest {

    @Rule
    @JvmField
    val rule: ActivityTestRule<MainActivity> = ActivityTestRule(MainActivity::class.java, false, false)

    lateinit var uiDevice: UiDevice

    @Before
    fun setup() {
        uiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
    }

    @Test
    fun test() {
        for (i in 0..100) {
            uiDevice.wakeUp()
            // test code
        }
    }

}

ActivityTestRuleを拡張する

ActivityTestRuleを継承したクラスを作成し、WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ONを使って画面点灯状態を維持する。
ActivityからTYPE_APPLICATIONにaddViewする場合はパーミッション不要なので、変更箇所も少なくて済む。
API25〜27で動作確認済み。おそらく19とかでも動くと思う。

FooActivityTestRule.kt
class FooActivityTestRule<T : Activity> : ActivityTestRule<T> {

    lateinit var view: View
    lateinit var windowManager: WindowManager

    constructor(cls: Class<T>) : super(cls)
    constructor(cls: Class<T>, initialTouchMode: Boolean) : super(cls, initialTouchMode)
    constructor(cls: Class<T>, initialTouchMode: Boolean, launchActivity: Boolean) : super(cls, initialTouchMode, launchActivity)

    override fun afterActivityLaunched() {
        super.afterActivityLaunched()
        runOnUiThread {
            windowManager = activity.windowManager
            view = View(activity)
            windowManager.addView(view, WindowManager.LayoutParams(0, 0
                    , WindowManager.LayoutParams.TYPE_APPLICATION
                    , WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                    or WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
                    or WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
                    , PixelFormat.TRANSLUCENT))
        }
    }

    override fun finishActivity() {
        runOnUiThread {
            windowManager.removeViewImmediate(view)
        }
        super.finishActivity()
    }

}

テストコードの方は、ActivityTestRuleを置き換えるだけで良い。

MainActivityTest.kt
@RunWith(AndroidJUnit4::class)
class MainActivityTest {

    @Rule
    @JvmField
//  val rule: ActivityTestRule<MainActivity> = ActivityTestRule(MainActivity::class.java, false, false)
//  ↓
    val rule: ActivityTestRule<MainActivity> = FooActivityTestRule(MainActivity::class.java, false, false)

    @Test
    fun test_all() {
        // test code
    }
}
1
0
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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?