諸事情により Android Studio を使わないでライブラリはつくるようにしています。 その場合の Junit4 と Robolectric を使った 一番簡単なテストの書き方を覚え書きとしてここに残します。
更新 2022-10-07 : このエントリーの内容は古くなったので、そこそこ最近の環境にあわせたプロジェクトを作成しました。 こちらのエントリー(現時点での Android Robolectric テスト、一番簡単なプロジェクト例)をご覧ください。
com.example.color パッケージでつくる android-color というプロジェクトをサンプルとしてつくります。
はじめに、android-color というディレクトリを作成しておきます。 これがプロジェクトのルートディレクトリになります。
プロジェクトの全体像は以下の通り:
実行環境:
java
$ java -version
openjdk version "1.8.0_275"
gradle
$ gradle -version
------------------------------------------------------------
Gradle 6.5
------------------------------------------------------------
Kotlin: 1.3.72
Groovy: 2.5.11
Ant: Apache Ant(TM) version 1.10.7 compiled on September 1 2019
JVM: 1.8.0_275 (Private Build 25.275-b01)
OS: Linux 4.15.0-128-generic amd64
Android SDK などは適宜セットアップ済みとします。
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'maven'
buildscript {
ext.kotlin_version = '1.4.10'
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:4.0.2'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
android {
compileSdkVersion 30
defaultConfig {
minSdkVersion 19
targetSdkVersion 30
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
testOptions {
unitTests {
includeAndroidResources = true
}
}
}
repositories {
google()
jcenter()
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
testImplementation 'junit:junit:4.12'
testImplementation 'org.robolectric:robolectric:4.4'
}
android.useAndroidX=true
これを設定せずに実行すると:
Execution failed for task ':mergeDebugUnitTestResources'.
> This project uses AndroidX dependencies, but the 'android.useAndroidX' property is not enabled. Set this property to true in the gradle.properties file and retry.
とエラーになる。
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.color" />
sdk=28
Java8 環境では sdk=28 にする必要がある。
テスト対象のコードです。
android.graphics.Color.alpha, red, gree, blue 相当のメソッドを kotlin で再実装したものです。
package com.example.color
object ColorUtils {
fun alpha(color: Int): Int {
return color ushr 24
}
fun red(color: Int): Int {
return color shr 16 and 0xFF
}
fun green(color: Int): Int {
return color shr 8 and 0xFF
}
fun blue(color: Int): Int {
return color and 0xFF
}
}
ColorUtils.kt をテストするためのコード.
ColorUtils クラスが android.graphics.Color.alpha, red, gree, blue 相当のメソッドを kotlin で再実装したものであるため、 本物の Color.alpha, Color.red, Color.green, Color.blue メソッドと同じ値を返すかテストしています。
package com.example.color
import org.junit.Test
import org.junit.Assert
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
import android.graphics.Color
@RunWith(RobolectricTestRunner::class)
class ColorUtilsTest {
@Test
fun test1(){
val color = Color.argb(255, 128,64,32)
val a0 = Color.alpha(color)
val r0 = Color.red(color)
val g0 = Color.green(color)
val b0 = Color.blue(color)
val expected = listOf(a0, r0, g0, b0).joinToString(",")
val a1 = ColorUtils.alpha(color)
val r1 = ColorUtils.red(color)
val g1 = ColorUtils.green(color)
val b1 = ColorUtils.blue(color)
val actual = listOf(a1, r1, g1, b1).joinToString(",")
Assert.assertEquals(expected, actual)
}
}
テストを実行するには test タスクを指定します。
$ ./gradlew test
以上です。
わかってしまえば簡単というか、これだけのことなんですが、ググっても情報に辿りつくことができず苦労しました。
Android のクラスを含んだテストを実機なしでコマンドラインでテストできるのは便利です。 Robolectric はテスト時間がかかるにはかかるのですが、 コマンドラインだけでテストできるならば、速めのサーバ上で ssh 経由で行うなどすればよいかと。
ChromeOS では Android が動くわけだから、 ChromeOS 上での Android 開発時のテストが Robolectric なしでできるようになればいいのに。