テストについて相談しにいった内容をまとめる

チームのテストについての進め方についてアドバイスをもらう機会があり、これからの進め方についても参考になったのでまとめる。

前提・背景

  • アプリ開発チーム。
  • Model,Controllerは必須で単体テストを書くというルールで開発している。
  • 振る舞いテストも一部コード化してリリース前に自動で回している。

今のチームでの課題

  • 単体テスト書いてきたが、なかなかメリットが享受できていない気がする
  • ふるまいテスト書いてみたはいいが、この先どう展開していくのが良いのだろう?
  • viewにビジネスロジックが積まれていてなかなかテストが書けない。構造見直ししたいがアーキテクチャの指針なくできない。

viewにビジネスロジック問題

viewにビジネスロジックが書かれていてテスト書きづらい。 どうにかしたいが、リファクタするにはテストがいる。 じゃあテスト書きたいけど書きづらい!の堂々めぐりになってしまう問題。

実装の構造に依存する・実装に近いテスト(例:ユニットテスト)は書きづらいので、実装から遠いテスト(例:ふるまいテスト)を書いてリファクタする準備をまずしましょう、というのが次のアクション。なるほど!

振る舞いテストで安心してリファクタできるようになれるのか

たしかに、怖くてリファクタできない!けど構造変えなくては!の打ちてに対して実装に依存しないようなシステムの外からのテストを書けばよい!というところには納得。 現状、今のチームではアプリをリリースする前に毎回行っているアプリの根幹の機能(主に遷移周り)のテストを書いている。でも、粒度もすごく大きいテストケースなので、それで安心してリファクタできるイメージが湧きません!

それに対してのアクションは、まずカバレッジをとりましょう。まずどこがカバーされているテストがあるのか、どこのコードが通っているテストがあるのかを可視化する必要がある。テストが通っているところから構造変えていくようにすればよい。

この話をふまえると、これから構造よくしていきたいところにユニットテストを書いていくより、ふるまいテストの拡充を優先度を上げた方がいいのだろうな。まずは外から、だんだん中に入っていってカバレッジなどをあげていく。 今までカバレッジなどは気にしないで「書けるところを書いていこう」の指針でずっと来てしまったので、きちんと数値とっていかないとダメですね。

振る舞いテスト(≒スモークテスト)の運用

今チームの中で振る舞いテストと言ってるものは「スモークテスト」と呼ばれる「このテストが落ちると、リリースしてはいけないというレベルのもの」になる。 このスモークテストを今までリリース前に最後のチェックとして行ってきた。本当はリリース前に煙が出てもしょうがないので、普段から本当は回すべき。プルリクがマージされた時などに自動でテストが回るような仕組みにしておくと早めに重大な問題に気づくことができてGood!

アーキテクチャ決まってない問題

アーキテクチャに関しては最初は「王道なもの」を採用してやってみると良い。同じ挑戦している人の人数も多いし、ぶつかった人も多いので、導入もしやすいだろう。MVPならMVPと決めてやってみると処理を書く場所があらかじめ決まっているのでテスト書かなきゃいけない処理も決まってくる。一回入れてみて問題が出てきたらまた考えても遅くなさそう。

[おまけ]テスト自体は品質をあげるものではない

テストコードを書くこと自体は 品質をあげるものではない。 テストコードを書くことで、プロダクションコードに影響を与える(リファクタできれいになる、使いやすいように引数の種類変えてみようかとか)ことで品質があがっていく。なので、テストコード書いてプロダクションコードが変わらないのは別に品質あげてないよ。もちろんデグレを防ぐみたいな役割もあるかもしれないけど、品質はあがってないよね、下げるのを防いではいるけど。 という思想があるので、テストファーストに越したことはないが、テストファーストをするためにはプロダクトの実装の仕方(構造が悪いとか)にも寄るしある程度のスキルが必要なので、テストファーストにこだわらなくてもよい。大事なのはプロダクションコードにプラスの影響を与えられているか。

[おまけ]mock使う派?使わない派?

テスト駆動開発界には流派が2つあるらしく、mock使う派(テストは分離した方がよい)と使わない派(本物のデータを使う方がよい)とがいるらしい。

mockする派

テストしたいクラスを狭めることができる。mockしていなかったら依存しているクラスの中もテストしていることになるけど、mockすると純粋にそのクラスのロジックをテストできる

mockしない派

自作自演のテストになる可能性がある。mockしている実体が変わったら意味がなくなっちゃうから。テストは通るけど結合したらうまくいきませんーみたいなことが起きてしまう。 最近のmockライブラリは強力なので、なんでもできてしまう。そもそもmockが必要になるというのは設計としていかがなものか?を気づく基準にもなるけど、強いmockライブラリがいるとスルーしてしまう可能性。この話は先輩からも聞かされたなぁ〜。

さいごに

今までどう打ちてを打っていいかわからないところをアドバイスもらえて次の一手が見つかった気がする。テストの世界では当たり前の考え方なのかもしれないけど、ぺーぺーの自分にとってはすごく有益なアドバイスをいただける機会でした。