Help us understand the problem. What is going on with this article?

星1個のアプリなんて作りたくない

Labomartの軌跡。構想から運用まで@unotovive
ゆめみ Advent Calendar 2019 の前回の記事

はじめに

Android アプリ開発者のみなさん、Google I/O 2018 の下記のセッションは見ましたか?

ちなみに、私は、、、、、、見てないです :rolling_eyes:

セッションでは、Play Store で星1レビューのついた原因分析を公開して

原因の42% は「アプリのクラッシュを含む安定性の問題」だったみたい。


出典: Youtube (Improve app performance and stability with Firebase (Google I/O'18))

星1レビューもらいたくない

テストを書きましょう笑

よくテストを書く時間がないと聞きますが、、

たぶん仕様調整やテストの時間がないだけです笑

きちんと仕様調整やテストの時間をもらいましょう :no_good:

そして、プログラムや仕様のバグを洗い出すのです :sunglasses:

千里の道も一歩から

テストを書くことは思っているより簡単。

まずは1つテストを書いてみましょう!!

テストって?

テストの種類には下記のようなものがあって

  • 単体テスト
  • 結合テスト
  • UI テスト

今回は単体テストに焦点を当てて話をしていきます!

Android の単体テスト

Android の単体テストには下記のようなものがあります

  • Local Unit Test
  • Instrumented Unit Test

何が違うん??って感じですが、簡単にいうと実機やエミュレーターが必要かどうかです。

今回は、実機やエミュレーターが必要ない Local Unit Test をやっていきます!

強い意志でテストを書こう

テストを書くのに強い意志は必要ありませんw

なんか物足りなかったので付けました笑

さて、テストを書いていこうと思いますが

せっかくなので最新の技術を使っちゃいます :nerd:

今回は JUnit5Truth を使います!

※ Truth は assertThat 使うために入れてます。ただそんだけですw

準備

ここからやっとコード書いていきます〜

下記の変更をして、Sync Now しちゃえばおk

ExampleUnitTest.kt は要らないので削除してね

app/build.gradle
android {
    ...
+   kotlinOptions {
+       jvmTarget = '1.8'
+   }
}

dependencies {
    ...
-   testImplementation 'junit:junit:4.12'

+   testImplementation 'org.junit.jupiter:junit-jupiter-api:5.5.2'
+   testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.5.2'
+   testImplementation "org.junit.jupiter:junit-jupiter-params:5.5.2"
+   testImplementation 'com.google.truth:truth:1.0'
}

テストするもの

今回は下記のような String の拡張関数作って

よくあるパスワードチェック処理をテストしていきます!

extensions/StringExtension.kt
package {自分のパッケージ名}.extensions

/**
 * パスワードの条件
 *
 * 半角英小文字・大文字・数字をそれぞれ1種類以上含む
 * 8文字以上10文字以下
 */
fun String.isPassword(): Boolean {

    val regex = Regex("""
        ^(?=.*?[a-z])(?=.*?[A-Z])(?=.*?\d)[a-zA-Z\d]{8,10}${'$'}
    """.trimIndent())

    return matches(regex)
}

テスト実行!!!!

test パッケージの下に下記のファイルを作成します!

extensions/StringExtensionKtTest.kt
package {自分のパッケージ名}.extensions

import org.junit.jupiter.api.Test

import com.google.common.truth.Truth.assertThat

internal class StringExtensionKtTest {

    @Test
    fun isPassword() {

        val password = "1234abcdAB"

        assertThat(password.isPassword()).isTrue()
    }
}

そして、isPassword() メソッドの左にある実行マーク押して

テストを動かしてみてください!

テストが成功すると気持ちいいですよね!

テストが成功する度に緑のチェックマークがクセになっていきます

複数パターン一気にテストしたいよ

さっきのテストでは1つしかテストできてない。。

一気に10個とかやっちゃいたい、、どうすれば、、、

はい、そんなときのために ParameterizedTest があります :sunglasses:

使ってみましょ〜

extensions/StringExtensionKtTest.kt
package {自分のパッケージ名}.extensions

import com.google.common.truth.Truth.assertThat
import org.junit.jupiter.api.extension.ExtensionContext
import org.junit.jupiter.params.ParameterizedTest
import org.junit.jupiter.params.provider.Arguments
import org.junit.jupiter.params.provider.Arguments.arguments
import org.junit.jupiter.params.provider.ArgumentsProvider
import org.junit.jupiter.params.provider.ArgumentsSource
import java.util.stream.Stream

internal class StringExtensionKtTest {

    @ParameterizedTest
    @ArgumentsSource(TestCase::class)
    fun isPassword(password: String, expected: Boolean) {

        assertThat(password.isPassword()).isEqualTo(expected)
    }

    private class TestCase : ArgumentsProvider {
        override fun provideArguments(context: ExtensionContext?): Stream<out Arguments> = Stream.of(
            arguments("1234abcdAB", true),
            arguments("abcdAB1234", true),
            arguments("1234abcdab", false)
        )
    }
}

はい、JUnit5 最高

これで複数ケース簡単にテストできますね♪

じゃんじゃんテストケース追加していってください :relaxed:

実は、、

テストが失敗するケースがあります笑

みなさん見つけられましたかね?

見つけられていない方はテストケース追加しまくってくださいね :heart:

おわりに

ちゃんとテストを書いて、少しでもバグを減らして

星5のレビューたくさんもらえるようになりましょ〜 :star2:

明日は @ihcamonoihS さんの記事 :hand_splayed:

参考文献

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした