yuichiro.__blog__

テスト(単体)を走らせるときにデータベースをどこで削除(DELETE FROM)するか

Qiitaで読む

1/19/2018 GitHubで開く

リハビリを兼ねて記事を書いてみます。現在大学生活をながらベンチャー企業でプログラミングのインターンをしています。個人でプログラミングをするのとグループでするのでは驚くほど違いがたくさんありますが、テストもその一つだと思います。(まあ今まで一人で書いてきたコードなんて、なんか欲しい、でちょちょっと作ってほぼほぼメンテナンスなんかしないで放置みたいなものばっかでしたし単体テストなんか書いたことなかったんですけど)

いま会社で作っているサービスでも単体テストを走らせていて1から勉強して自分でも書いていたのですが、そこで仕組みというか順序なんかで気になることがあったので記事を書くことにしました。

ユニットテスト中のデータベースの扱い

記事を書きながら軽く、他ではどうなのか調べていますが、僕が現在いじっているサービスでは文字通り単体でテストが動くように、テストごとに実際にデータベースに必要な値を挿入して(テスト用のデータベース)、テストが終わったら削除するという実装になっています。

てすと1 {
     (データベースから挿入 ユーザー情報とか)

          テスト実行

     (データベースから削除)
}

毎回同じ状態にする(復元)ためにデータベースから削除する、ところではすべてのデータをバッサリ全部DELETEしています。それぞれのテストで必要なデータが同じだったらある一定の状態に保つってのもありなのかもですが、、

失敗した時の対応

上の形式でテストを組んでいるのできっちり、他のテストに左右されずに、単体でも問題なく(ログイン処理の途中とか複雑な設定でも)動いてくれます。

が、

問題は失敗したときにあります。

てすと1 {
     (データベースから挿入 ユーザー情報とか)

          テスト実行 ==> "えらー!"

     (データベースから削除)
}

まあ見ればわかりますがテストの最中のアサート文でエラーが発生するので削除までたどり着かず次のテストが走り出してしまうわけですね。

これだとまっさらな状態(一番最初に走らせているときなど)と同じ状態ではなくなってしまうので、十中八九テスト落ちるし、仮に通ったとしても単体テストの趣旨からはずれてしまいます。

リセット処理(削除処理)はテストの頭に書く

てすと2 {
     (データベースから削除)
     (データベースから挿入 ユーザー情報とか)

          テスト実行

}

単体のテストを書くときは頭に削除処理を書いておくと(もしくは挿入の前にリセットを強制するとか)失敗が連鎖したり予期せぬ動作が減って幸せになれるんじゃないかなと思いました。幸あれ

結び

この話を書いた背景ですが、テストの仕組みをよくわかっていないまま、ガリガリテスト動かして、周りのコード真似して、エラーが出たらそこを直すっていう風にカバレッジを上げるのを最優先で進めてたんですが、テストを全部実行すると何のエラーもなく全部通るか、バタバタといくつもテストが落ちて問題箇所が探しにくい、、ということがよくあって、いままでは-vvxみたいにテストが落ちたら強制終了、みたいにして問題箇所を修正していたのですが、本質的じゃないなあと思って、残しておこうと思いました。

適当なこと書いてる部分があったらごめんなさいすぐなおします

< Macのキーボードの隠しコマンドShellScriptでフラグ >