『初めての自動テスト ―Webシステムのための自動テスト基礎』読んだ感想_まとめ

# はじめに
こんにちは。今回も書籍の感想まとめ兼、紹介になります。
最近のプライベートはコードを書くよりも技術書を読むことの方が多いもので…
書籍の中から印象に残った部分をまとめてみます。

### 記述履歴
1/7(火)：1〜4章追記
1/8(水)：5章,6章追記
1/9(木)：6章追記
1/11(土)：7〜10章追記
1/12(日)：11章12章追記

## 書籍紹介
表題のものです。

https://www.oreilly.co.jp/books/9784873118161/

## 読んだきっかけ
勤務中にテストコードのないロジックを見た時に、どうすれば良いのだろうと思ったのがそもそものきっかけでした。
そもそも自分自身が良いテストコードを書けているのだろうか…？と思って改めて入門書レベルから読んでみようと、本書を手に取ってみました。

# 各章まとめ

## 1章

### 親指の法則
- UI、統合、ユニットの各テストはピラミッド型にする = 土台であるユニットテストが重要
  - 実体験的にも同じことを感じる
  - ユニットテストが存在していないと常に不安がつきまとう…
- テストは可能な限り下の層(統合、ユニット)に持っていく
### 誰が自動テストを書くのか
- 開発者とテスターの視点は異なる
  - 開発者はユニットテスト、テスターはUIテストに集中しがち
- 協調が大切
  - 役割分担はそこまで気にせず、最終的には __自動テストできる状態が大事__
  - __肩書や役職は必要ない__
    - 肝に銘じます…

## 2章

### ユーザーインターフェイステストを始めよう
- UIテストは直感的
  - __つながり__ をテストするもの
  - スモークテストとして有用
    - ユーザーに最も近い部分なので大事ですね

## 3章

### ステップ2：正しいCSSセレクタを見つける
- idの有無は __テストコードの可読性__ にも影響する
  - フロントコードがidによる有無で可読性が変化するのは当たり前ですが、テストコードもそうですね
  - テストコードの可読性についての言及だったので印象に残った箇所です
- テストコードとUIは疎結合にしておく
  - `Laravel Dusk`を使用していると仮定すると…
    - 書籍内はrubyですがPHPを書き慣れているのでご容赦ください
``` php
public function testHoge()
{
    $this->browse(function (Browser $browser) {
        $browser->visit('/hoge-url')
            ->assertSeeIn('#hoge-id', 'てすと');
    });
}
```
上記の例では `hoge-id` 内に `てすと` があることまで確認していますが、この `てすと` を誰かが書き換えるとそれだけでテストが壊れてしまいます。
そのため下記の方が良いとのことです。
``` php
public function testHoge()
{
    $this->browse(function (Browser $browser) {
        $browser->visit('/hoge-url')
            ->assertPresent('#hoge-id');
    });
}
```

## 4章

### 統合テストを始めよう
- 統合テストは反復型の開発を可能にする
  - TDDに通じる部分ですね
    - 裏を返せばテストがないと反復型開発はできない…
- 統合テストはUIテストの書き直しではない
  - APIレベルのテストという意味では統合テストが重要

## 5章
全体的にCRUDの基礎について書かれている章です。
- テスターやBizサイドの方が読まれると、エンジニアとの話が少しばかりスムーズになるかもしれません
  - 逆にエンジニアには初歩的な内容なので物足りないかも…
  - 初学者にはかなり分かりやすい良い章です

## 6章

### UIテストの課題
- ビルドに時間が掛かる
- どこに問題があるかまでは分からない
  - UIテストで問題があることまでは把握できるが、具体的にどのロジックかまでは把握できない
  - 例：入力フォームでエラーがあるとUIテストで判明、ただしどうしてエラーになるのかは分からない

### ユニットテストの仕組み
 - テストは自信を得るための活動 = 出荷できる状態
   - 「自信を得るため」という表現はかなり肌感として理解しやすかったです
     - コードが壊れていない状態を確認しながらリファクタには臨みたい(というかそうでないと…)
 - 後任の開発者にとって黄金
   - これも実体験することがありますね
 - コードカバレッジを満たすようにテストコードを書くことは後追いの際に有効
   - ただし質の低い100%より質の高い80%を目指すこと

## 7章
- 5章同様JSの基本的な部分に対する言及が多い
- JSを全く触れたことのない人にとっては初級講座として内容がとても良い
  - 経験者にとってはこれも物足りないかも…

## 8章
- 本書籍の中でもかなり重要な箇所になります
- 著者も1章と8章だけ読んでもOKというくらい

### ユニットテストから始める
- 壊れる可能性のあるものはすべてテストする
  - エクストリームプログラミング(XP)の考え方の一つですね
  - 全ては無理、しかし可能な限りテストする

### 統合テストへステップアップする
- HTTPのステータスコード、リダイレクトの確認を行う
  - LaravelではController層でのテスト？認識があっているのか自信がないです…

### UIテストへ到達する
- UIテストはやりすぎない
  - 保守の手間、壊れやすさから

### 逆ピラミッド
- __親指の法則__で語られたピラミッドの形を意識する
  - UIテストが肥大化し、それよりもユニットテストと統合テストが貧弱になっている状態を __逆ピラミッド__ と称する
  - 一時的には問題ない現象だがテスト整備の通過点であることを意識すること

## 9章
- 5章,7章と同様に初歩的な内容
- 唐突なプラグラミング初歩講座が始まるが内容はかなり充実しています
  - 非エンジニアの方が読んでみるのも良さそうです

## 10章

### 分離されたテストの美しさ
- データは使用されているテストの近くに配置する
  - php Unitでいうところの`setUp()`、`tearDown()`へ共通変数を移行するのは必要になったタイミングでOK
- テストは似ているものでまとめる
  - 現職ではメソッド毎の正常系と異常系でまとめていますが、メソッドで分けず単に正常系異常系だけで区分けしてみるのもありかもと感じました

## 11章

### ステップ2：エクスペクテーションの設定
- 緩やかなモックと厳密なモック
  - モックの呼び出し明示をどの程度にすべきか
  - 緩やかな方がおすすめと著者

### モックの泥沼
- モックが多すぎると本来のテスト意図からズレてしまう
  - これを避けるために細かな実装は隠蔽しましょう
  - オブジェクトの表層に注目して`ポート`と`アダプタ`に分離する等の手法があります

## 12章

### この章で学んだこと
- テストファーストはテストと __同じくらい設計に重きを置く__
  - まずは設計の箇所の整理が大事になりますね
- テストファーストは銀の弾丸ではない
- 良いコードを書けるかは自分次第
  - まあ、そりゃそうだよなあと…

# おわりに

## 全体的な感想
- 絵や図が多用されていてとても読みやすいです
  - 非エンジニアの方にもおすすめできる良書
- 本格的なテスト手法の入口という位置付けかなと思います

## 次に読む本
積んでいる本の中に[ドメイン駆動設計をはじめよう](https://www.oreilly.co.jp/books/9784814400737/)があるので、これを読もうかなと思います。

https://www.oreilly.co.jp/books/9784814400737/

その後に今回の本を踏み台として[テスト駆動開発](https://www.amazon.co.jp/%E3%83%86%E3%82%B9%E3%83%88%E9%A7%86%E5%8B%95%E9%96%8B%E7%99%BA-Kent-Beck/dp/4274217884)を読もうかなと。

https://shop.ohmsha.co.jp/shopdetail/000000004967/