
[RSpec][作業効率化] flakyテストを毎回再現させる方法
はじめに
flakyテストの修正を行うことが今回多く開発効率を高める方法をまとめたいと思った。
修正着手時から、再現、デバッグ、修正後の確認などの様々なタイミングで、失敗パターンを引き当てるのが面倒臭い、何回実行させる気だ。。。となった。
flakyテストとは
テスト実行時の前提をランダムとしている場合、実行タイミングによってテストが成功したり、失敗したりするようなテストのこと。
テスト実行時の前提とは、テストする環境やテストデータなど。
何が悩ましいのか
テストデータをランダムに生成している場合、特定のパターンになると落ちる事象が発生する。今回直面したのは、booleanのデータ6つが全てfalseになるとテスト失敗するというもの(確率にして1/64)
最初、なぜ落ちているかわからないため、修正するためには、失敗したパターンで、デバッグする必要がある。今回で言うと、1/64を引くためにテストを何回実行すればいいんだ!となる。
(50回実行で1回以上失敗する確率は、54.5%らしい。。)
flakyに対して便利な手法
バッチスクリプト(別名:シェルスクリプト)
複数のコマンドを一括で実行する簡易プログラムのこと。
ターミナルで、以下のコマンドを叩くことで、複数回の実行を一気に行うことができる。
例えば、実行だけしておいてトイレ行って帰ってきて、ログを確認すれば結果が一覧で見れる。
[command]部分には、bundle exec rspec test_spec.rb などが入る
for i in {1..10}; do [command]; done
シード値
マインクラフトで御用たちのシード値。
マイクラもワールドは基本ランダム生成されるが、シード値を設指定することで、ランダムではなく、そのシード値から一意に算出される値でワールドが生成される。
これと同様、ランダムなテストデータや周辺環境を一意な前提を作成できる。
システム的な言葉を使うと、擬似乱数生成器の初期値。
bundle exec rspec test_spec.rb --seed 12345
バッチスクリプトとシード値の融合
再現するために、複数回の実行を一括で行いつつ、毎回のseed値を指定する。
これによって、以下のように効率の良い作業が行える。
1. コマンドを実行
2. 落ちたテストのseed値を確認
3. そのseed値でテストを実行しつつ、デバッグ作業
for i in {1..10};
echo "Running with seed $i..."
[テスト実行コマンド] --seed $i
done
おわりに
今回、記事を書き始めたとき、バッチスクリプトとシード値の融合までは、思いついていなかったので、書いて良かった。
記事に起こすことで、気づきや理解を深めることができるので、今後もゆったり続けていきたいと思った。