【テスト初心者向け】新卒が「テストコードを書く」を習慣化させるために大切なこと


# 【テスト初心者向け】新卒が「テストコードを書く」を習慣化させるために大切なこと

[Ateam Lifestyle Inc. Advent Calendar 2020](https://qiita.com/advent-calendar/2020/ateam-lifestyle) の9日目は新卒２年目エンジニアの@hurikake06が担当します。

## はじめに

私は学生時代、テストコードをほとんど書いたことはありませんでした。
railsチュートリアルで書いた程度、なんとなく概念はわかっている程度、です。
また配属当初はチーム全体でも、テストを書こうという意識は低く、
過去の成果物にもほとんどテストは書かれていませんでした。

ですが、今は個人・チーム共に
**「テストコードを書く」を習慣化**し、継続的に取り組むことが出来ています。

この記事では、「テストコードを書く」を習慣化出来た理由や、コツについて記述できればと思います。

## こんな人に読んで欲しい

学生・社会人問わず、以下のような不安や課題を持っている方に読んでいただきたいです。

- テストコード**本当に大事？**
- これから社会人エンジニアになるけどテストコード**書いたことがなくて不安**
- テストコード大事なのはわかるけど、**習慣化できていない**

特に、「**個人で出来ること**」に着目して
記述するので、学生の方にも参考にしていただければ幸いです。

## 「テストコードを書く」を習慣化するには

大切だと思うポイントは３つです。

- **メリットを理解する**
- **テストコードを書くハードルを下げる**
- **自己を律する仕組みを作る**

これらを抑えることで、一度きりのモチベーションではなく
継続的にテストコードを書くようになると思います。

## 大切だと思うポイント

### メリットを理解する

まず、テストコードを書くことで「何が嬉しいのか」を理解する必要があります。

テストコードが「保守管理」の面で重要なのはご存知かと思います。
ですが、長期運用時のメリットだけでは、
どうしても目先の工数削減や学習コストを考えて
敬遠されてしまいがちだと思います。

ですが、私は短期で見てもテストコードのメリットは多いと思っています。

一般的な「テストコードのメリット」については多くの方が記事を書いていると思うので、
ここでは「**新人エンジニアのモチベーション**」に直結する部分に、フォーカスを絞って記述できればと思います。

#### メリット①

**設計の指針になる**

処理をどの単位でメソッドに分けるべきか、
フレームワークを利用していれば、モデルに持たせるべき処理か、コントローラーに持たせるべきか、など

「動けばいい」と思っていた学生時代では意識しなかった部分も、
業務・チームでの開発では考慮が必要です。

テストが書きづらいプログラムというのは「大抵、設計が間違っています」。（個人の感想です）

なので、「テストを書くこと」・「テストを意識した設計やTDD」を行うことで

- 長すぎる関数
- 間違った処理の配置

をある程度抑制できると思います。


#### メリット②

**レビューのしやすさにつながる**

先輩方の工数を使ってしまうレビュー依頼に対して、
申し訳なさのある新人エンジニアも多いのではないでしょうか。

私もその1人でしたが、しっかりとテストを書くことで、
レビュワーは

- 何を期待した関数・クラスなのか
- 要件の抜け漏れはないか
- 最低限のバグは無いか

などをすぐに確認することができ、
レビューの速度・質の向上につながります。

#### メリット③

**リリース時の精神衛生**

なんといってもテストの書かれていないコードのリリースは（精神的に）怖いです。
配属後すぐに本番でバグを出そうものなら、冷や汗が止まりません。

テストコードが書かれていることで、バグを**全て無くせるわけでは無い**ですが、
書かれていることで

- 必ず担保されている要件が可視化出来る

ので、バグが発生した際も
「**問題の切り分け**」や「**リリース切り戻し**」の判断材料になります。

---
### ハードルを下げる

ここまでで、「テストコードのメリット」についてはご理解頂けたかと思います。

次に、大事なのは
実際に書き始めるまでのハードルを下げることです。

つらつらとテストコードのメリットを前述しましたが、
実際に体験して見ないことには身になりません。

実践してみて、
テストコードへのハードルが下がった！
と思うものを紹介していきます。

#### 日本語で書く

いきなりテストコードを書き始める前に、
一度日本語で記述してみることで、
**必要なテストケース**やその関数に**期待していること**が
自分の中で明確になっていきます。
（人に説明することで考えが整理されるみたいなもの）

そこから、英語に変換していくと自然と綺麗なテストコードになるかと思います。

例）`rspec`で例を紹介します

```ruby
def fizz(num)
  num % 3 == 0 ? 'Fizz' : ''
end
```

一度日本語で書いてみる

```
関数fizzを検証する do
  引数が３の倍数の場合 do
    文字列'Fizz'を返す
  end
  引数が３の倍数では無い場合 do
    空の文字列を返す
  end  
end
```

英語に直す

```ruby
RSpec.describe '#fizz' do
  subject { fizz(num) }
  context 'when num is a multiples of 3' do
    let(num) { 6 }
    it { is_expected.to eq 'Fizz' }
  end
  context 'when num is a multiples of 3' do
    let(num) { 7 }
    it { is_expected.to be_empty }
  end
end
```

慣れるにつれて、日本語で書くときの感覚でテストコードを書けるようになっていきます。

#### テスト環境を整える

主にテストデータの話になりますが、
いくらテストを書きたくてもテストデータが用意できないと始まりません。

私の場合は、`rails`を利用しているので
主要なモデルの`factory bot`を書くところから始まりました。

マスター系のテーブルは`fixture`などを利用しても良いと思います。

テストを書きたいときに、欲しいテストデータが
すぐに手に入る状況を作りましょう。

### 自己を律する仕組みを作る

最後は、**自己を律する仕組み作り**です。

といっても簡単な話で、
開発しているとどうしても・・・

- 「今回は小さい関数だし、テストはいいか..」
- 「納期がギリギリなので後からテスト書こう..」

といった誘惑が出てくるかと思います。

そういった誘惑を断ち切る手段を持たない以上、「習慣化」は難しいです。

現在、チームでは以下のような取り組みをすることで
テストの「習慣化」を促進させています。

- **機械的な仕組み**
    - テストカバレッジを可視化（注意は人がする）
    - CI/CDでテストを回し、テストが通らない場合はリリース出来ない
- **人的・組織的な仕組み**
    - レビュー時点でテストが書かれているかを確認する
    - テストカバレッジが下がっていたら指摘する
    - TDDの推奨
        - コーディング前の設計レビューの段階でテストを書いておく
- **目標設定**
    - チームで
        - ◯月に全体カバレッジ◯％
    - 個人で
        - これから作成する◯◯モデルのテストカバレッジは１００％に保つ

## まとめ

> - **メリットを理解する**
> - **テストコードを書くハードルを下げる**
> - **自己を律する仕組みを作る**

以上が「テストコードを書く」を習慣化するのに大切だと思うポイントは３つでした。
３つのポイントが少しでもテストコードを書くエンジニアの助けになれば幸いです。

ただ、テストコードを書いていくと色々な壁にぶつかる事も多いです。
自分だと以下のような..

- 過去のコードが複雑すぎてテストに落とし込めない
- ブロック引数がある場合どう書くの？
- コールバックのせいで期待する値が得られない

それでも、モックや周辺パッケージを利用すればだいたいなんとかなります。
まずは、「簡単・書きやすい・データを用意しやすい」箇所から
書き始めて見ることをお勧めします。

## おわりに

最後まで読んで頂きありがとうございました。

まだまだ自分もテストコード初心者です。@jnchitoさんの記事めっちゃ読んでます。
他にもテストコードに大切だと思う事、指摘や感想などありましたら、ぜひコメントをお願いします。

また、自分は個人目線・いちメンバー目線での内容でしたが、
「チームをマネージメントする目線」でのテストコードについて
[Ateam Lifestyle Inc. Advent Calendar 2020](https://qiita.com/advent-calendar/2020/ateam-lifestyle)の１日目で
[マネジメント目線から考える「テストコードを書く」を習慣化させるために大切なこと](https://qiita.com/aiji42/items/a3b8062043295b52f745)
という記事もあるので、是非一度読んでみてはいかがでしょうか。