【リーダブルコード】初心者エンジニアが読み解く「テスト」で読みやすさを高める技 - 第14章

お疲れ様です。マル太です。

前回は、リーダブルコードの第13章「短いコードを書く」についてまとめました。

今回は、第14章「テストと読みやすさ」について、簡潔にまとめていきます。


※まず初めにテストコードについて解説
テストコードとは、プログラムにバグがないことを確認するプロセスのこと。
開発者は、作成したプログラムが意図した通りに動作するかを確認するために、様々なテストを行います。
しかし、人の手によるテストだと限界があり、すべてのケースを網羅することは難しいです。
また、ヒューマンエラーによる見落としや、テストの度に時間と労力を要するという問題も発生してしまいます。
そこで、テストコードを活用することで、テストコードが自動でプログラムの動作を検証してくれます。

<br>

# なぜテストコードは読みやすくなければいけないのか？
テストコードは、プログラムが正しく動作することを確認するためのコードです。

開発者だけでなく、他のエンジニアやQA担当者も読む可能性があり、その可読性は非常に重要です。

読みづらいテストコードは、以下のような問題を引き起こします。

**1.バグの発見の遅延**
テストコードの意図が理解しづらく、バグの発見が遅れる可能性があります。

**2.修正の困難さ**
テストコードの構造が複雑で、修正が困難になる可能性があります。

**3.共同作業の阻害**
他のエンジニアがテストコードを理解できず、共同作業がスムーズに進まない可能性があります。
<br>

# 読みやすいテストコードを書くためのヒント

**1.テストの目的を明確にする**
テストコードの意図が明確に伝わるように、コメントや命名規則などを工夫しましょう。
例：
```ruby:Python
def test_add_two_numbers():
  """
  2つの数字を足し算する関数が正しく動作することを確認するテスト
  """
  result = add(2, 3)  # 2 + 3 を計算
  assert result == 5   # 結果が 5 になることを確認
```
<br>

**2.テストコードを整理する**
テストコードを整理された構造にすることで、可読性が向上します。
例：足し算、引き算、掛け算など、機能ごとにテスト関数を分ける。
<br>


**3.テストコードを簡潔にする**
冗長な記述や不要なコードを避け、簡潔なテストコードを心がけましょう。
例：
```ruby:Python
# 悪い例
a = 2
b = 3
result = add(a, b)
assert result == 5

# 良い例
result = add(2, 3)
assert result == 5
```
<br>

**4.テストしやすいコードを書く**
テストしやすいコード設計を行うことで、テストコードも自然と読みやすくなります。
例：関数を小さく保ち、1つの関数で1つの処理のみを行うようにする。
<br>

**5.エラーメッセージを読みやすくする**
テスト失敗時の原因を特定しやすいように、具体的で分かりやすいエラーメッセージを記述しましょう。
例：
```ruby:Python
# 悪い例
assert actual == expected

# 良い例
assert actual == expected, f"期待値: {expected}, 実際値: {actual}" 
```
<br>

**6.独自の「ミニ言語」を作る**
繰り返し登場する処理を関数やマクロにまとめることで、テストコードの可読性を高めることができます。
例：
```ruby:Python
def check_apple_count(actual_count, expected_count):
  """
  りんごの数が期待通りか確認する
  """
  if actual_count == expected_count:
    print("OK！りんごの数は合っています")
  else:
    print(f"NG... りんごの数が違います。期待値: {expected_count}個、実際値: {actual_count}個")

# テストケース
actual_apples = 3  # 実際にあるりんごの数
expected_apples = 3  # 期待するりんごの数
check_apple_count(actual_apples, expected_apples)  # 確認を実行
```
<br>

**7.assert文を効果的に使おう**
標準の `assert()` 文に加えて、`unittest`モジュールで提供されている `assertEqual()`, `assertTrue()`, `assertFalse()` などのアサーションメソッドも活用することで、より分かりやすく、詳細なテストを書くことができます。

例：
```ruby:Python
import unittest

class TestMyFunction(unittest.TestCase):

  def test_my_function(self):
    # 期待値と実際値が等しいことを確認
    self.assertEqual(my_function(2, 3), 5)  

    # 値がTrueであることを確認
    self.assertTrue(my_function(10))  

    # 値がFalseであることを確認
    self.assertFalse(my_function(0)) 
```

このように、`assert()` 文を直接使うだけでなく、`assertEqual()` などのアサーションメソッドを適切に使うことで、テストコードの可読性と表現力を高めることができます。
<br>

※assert文って？
assert文は、「もしも〇〇が正しくなかったら、プログラムを止めて教えて！」という命令を埋め込むことができるコードのことです。
例えば…
「もしも変数 `age` がマイナスだったら、おかしいからプログラムを止めて」
「もしもファイルが開けなかったら、エラーメッセージを出してプログラムを止めて」
…といった具合に、assert文でチェックポイントを作っておくことで、プログラムが想定外の動きをするのを防ぐことができます。
<br>

assert文の使用例：
```ruby:Python
def divide(x, y):
  """
  xをyで割った結果を返す関数
  """
  assert y != 0, "0で割ることはできません"
  return x / y
```

<br>

**8.テストケースをシンプルにする**
テストケースは、できるだけ単純な入力値を用いることで、理解しやすくなります。
例：`add()`関数のテストでは、`2 + 3 = 5` のような単純なケースから始める。

<br>

**9.様々なパターンをテストする**
正常系だけでなく、異常系や境界値など、様々なパターンをテストすることで、コードの信頼性を高めることができます。
例：`divide()`関数のテストでは、0で割るケースもテストする。
<br>

**10.テストの機能に適切な名前をつける**
テスト関数の名前は、テストの目的を明確に示すようにしましょう。
例：`test_add_positive_numbers`
<br>

**11.テストコードを定期的に見直す**
定期的にテストコードを見直し、改善を続けることで、より質の高いテストコードを維持することができます。
<br>

**12.テストに優しい開発**
テストしやすいコード設計を心がけることで、テストコードもシンプルになり、可読性が向上します。
<br>

**13.テストのやりすぎに注意する**
完璧なテストを目指すあまり、テストコードが複雑になりすぎないように注意しましょう。
<br>

# まとめ
読みやすいテストコードは、ソフトウェアの品質向上に大きく貢献します。

今回紹介したヒントを参考に、読みやすいテストコードを記述し、より質の高いソフトウェア開発を目指しましょう。

次回は、第15章「『分/時間カウンタ』を設計・実装する」についてまとめます。