(自分のブログ記事、大丈夫、テストは怖くないよ[技術は熱いうちに打て!]の転載です)
概要
どうも、@daiki1003です!
テスト、怖くないですか?
面倒くさくないですか?
分かりますよ。
この記事は、そんなあなたのテストへの恐怖心を取り除くために執筆しました。
こんなの出せたら、かっこいいですよね。
大丈夫です、この記事を読んでいただければ誰でも出せるようになります!
本記事の構成
・ファイルの作り方、お作法
・テストの記述
・テストの単位
・テストの実行
・coverage
大体、この様な構成で書いて行きます。
最短でテストを動かせる様になる事を最優先するため、
基本的な知識をすっ飛ばすこともあるかと思いますが、
その辺は他の記事も参考にしながら勉強してみてください。
Flutterにおけるテストファイルの作り方・お作法
さて、まずはテストファイルを作らないことには始まらないので早速作ってみましょう。
ファイルの作り方
ルート階層に存在している、test
フォルダ以下に
テストを記述するファイルを作成します。
基本的に、どんなファイル名でどんな階層でもテストは実行出来ますが。
少しだけお作法があるので守りましょう。
後の自分や仲間を守ることになります。
ファイルを作る際のお作法
ファイル末尾を_test.dart
にする
hoge_repository.dart
のテストファイル名はhoge_repository_test.dart
にしましょう。
test階層以下をlib
階層以下と同等にする
lib/hoge/repository/fuga_repository.dart
のテストのファイル階層はtest/hoge/repository/fuga_repository_test.dart
にしましょう。
Flutterにおけるテストの記述
さて、ファイルを作ったところで早速テストを書いてみましょう。
まず、雛形です。
import 'package:test/test.dart';
void main() {
}
テストファイルは必ず、main
関数を持ちます。
この中にテストを記述していきます。
一つ一つのテストの記述
仮に、一つテストを記述してみましょう。
test('variable test', () {
var sampleValue = 'sample';
expect(sampleValue, 'sample');
});
割と直感的ですよね?
test(テスト名, () {
// 前処理
expect(処理や変数, 処理による結果や変数の期待値);
});
テストの一つ一つはこの様な書式で記述します。
test
と言う関数を記述することで、
一つのテストを作る事が出来ます。
そして、この中に
この処理をしたらまたはこの値はこうなってほしい
と言う意味を持つexpect
関数を0個以上記述します。
全てが「こうなってほしい」を満たすことによってテストが一つ通った (Passed) と言うことになります。
Flutterにおけるテストの単位
groupを使いこなそう
test('add test', () {
expect(42 + 42, 84);
});
test('minus test', () {
expect(42 - 42, 0);
}):
以上2つのテストがあるとします。
問題なく、通りそうですね。
これで終わりでも良いんですが、この2つ良くみてみると両方とも
整数値に対する処理を行っていますよね?
こう言う場合は、group
関数を使ってまとめる事が出来ます。
group('integer test', () {
test('add test', () {
expect(42 + 42, 84);
});
test('minus test', () {
expect(42 - 42, 0);
});
});
記述式はtest
と一緒で第一引数に名前、第二引数に実行するテストです。
groupによるメリット?
group
化をすることにより、実行結果を以下の様に見やすくする事が出来ます。
この場合、まだ数が少ないのでメリットを感じにくいかもしれませんが
数が多くなってくるとより顕著になってきます。
Flutterにおけるテストの実行
それでは、ここまで書けたところでテストを実行してみましょう。
import 'package:test/test.dart';
void main() {
group('integer test', () {
test('add test', () {
expect(42 + 42, 84);
});
test('minus test', () {
expect(1 / 0, double.infinity);
});
});
}
コマンドによる実行
全テスト実行
$flutter test
00:03 +2: All tests passed!
指定ファイルのみの実行
$flutter test [test_file_name]
00:02 +2: All tests passed!
指定したテストのみの実行
$flutter test --plain-name 'test_name' [test_file_name]
例えば
$flutter test --plain-name 'minus test' test/widget_test.dart
00:01 +1: All tests passed!
coverage
coverageとは?
テストについて調べていると、テストカバレッジやcoverage
なんて
言葉が目に入ってくると思います。
これは、全プログラムの実行フローに対してどこまでテストによって保証されているかを示す率
です。
ちょっと具体例を出してみましょう。
int add(int a, int b) {
return a + b;
}
test('add test', () {
expect(add(1, 2), 3);
});
この場合、coverage
は100%となります。
では、以下の場合はどうでしょう?
int divide(int numerator, int denominator) {
if (denominator != 0) {
return numerator / denominator;
} else {
return double.nan;
}
}
test('divide test', () {
expect(divide(4, 2), 2);
});
この場合、coverage
は50%となります。
なんとなく分かりましたか?
else文の方の処理を通らないので、2個のうち1つだけがテストで保証されている状態、
つまり50%となります。
coverageの出し方
では、Flutterでどうやってこのcoverage
を出すのでしょうか?
$flutter test --coverage
と、実行したいテストに--coverage
を付け足してあげるだけです。
ですが、これを実行すると
coverage/lcov.info
と言う何やら怪しいファイルが生成されるだけです。
しかも、中を見ても良く分からない...。
でも安心してください。
ここまで来ればもうちょっとで、最初に示した表が出せるのでもう一踏ん張りです!
coverageの可視化
lcovのインストール
このファイルを解析するための、ツールを一つ下記コマンドでインストールします。
$brew install lcov
これが終わり次第、以下を実行してみてください。
$genhtml coverage/lcov.info -o coverage/result
こちらが実行終わりましたら、-o
で指定したフォルダが
生成されているはずです。
この中にあるindex.html
をブラウザで表示すると
最初に示した表が表示されるはずです!
いかがでしたでしょうか?
テストへの恐怖心が少しでも減ってくれれば嬉しいです!
また、ここ分からなかったよ!とかがあれば気楽に@daiki1003まで
リプライお待ちしております!