6歳娘「ねぇ、パパ！このテストコード、Given-When-Then構文で可読性、高めてみない？」

# とある休日

娘「ねぇ、パパ！」

ワイ「なんや、娘ちゃん」

娘「さっきね」
娘「ちょっとだけ伸びしろのあるテストコードを拾ったの」

ワイ「おお、そうなんか」
ワイ「ちょっとみせてみ」

娘「うん！」

```python:test_task.py
class TestNextStatus(TestCase):

    def test_ステータスがResolveの状態でステータスを進めるとCloseになる(self) -> None:
        task = Task.create("Qiitaに記事を投稿する")

        task.next_status()
        task.next_status()
        task.next_status()
        task.next_status()

        self.assertEqual(Status.Close, task.status)
```

娘「↑これがそのテストコードだよ」

ワイ「ん？娘ちゃん」
ワイ「とくに問題があるようには見えんのやけど？」

娘「うん、だから」
娘「**ちょっとだけ伸びしろのある**テストコードなの」

ワイ「あ、なるほどね」
ワイ「(てかこれ、ワイが書いたテストコードやん・・・)」
ワイ「そんで、どのへんに伸びしろみを感じたん？」

娘「えっとね」
娘「このテストコードって・・・」

① ステータスを**Resolve**な状態にして
② ステータスを進めると
③ ステータスが**Close**になる

娘「↑ってことが書かれてるでしょ」

ワイ「せやな」

娘「でも、このコードのどこに①②③が書いてあるのかって」
娘「ひと目じゃわかりずらいと思わない？」

ワイ「んー、たしかにそうかもしれんなぁ」

娘「でしょ！だからね」
娘「**Given-When-Then構文**で可読性、高めたいなって思ったの！」

ワイ「Given・・・When・・・？」
ワイ「なんて？」


娘「えっとね」

# Given-When-Then構文とは

娘「**Given-When-Then構文**っていうのはね」
娘「テストコードを」

① Given (前提条件) → 「こんな状態にして」
② When (操作) → 「こんな操作をすると」
③ Then (結果) → 「こんな結果になるよね」

娘「↑の3つのブロックに分けて書く記法だよ」

ワイ「ふむふむ」
ワイ「つまり、さっきのテストコードを・・・」

① Given (前提条件) → 「ステータスを**Resolve**な状態にして」
② When (操作) → 「ステータスを進めると」
③ Then (結果) → 「ステータスが**Close**になるよね」

ワイ「↑こんな感じに分けて書くってこと？」

娘「そうそう」
娘「各ブロックに何が書いてあるのか、ひと目でわかって可読性が高まるんだよ！」

ワイ「へぇ～そうなんや」

娘「じゃあ、パパ」
娘「さっそく、やってみよう！」

ワイ「おお、ええで！」


# Given-When-Then構文で書いてみる

ワイ「ほな、**Given-When-Then構文**で書いていくで」
ワイ「そしたら、まずは」

> **① Given (前提条件) → 「ステータスをResolveな状態にして」**
> ② When (操作) → 「ステータスを進めると」
> ③ Then (結果) → 「ステータスがCloseになるよね」

ワイ「↑の①の部分を書くわけやから・・・」

```diff_python:test_task.py
class TestNextStatus(TestCase):

    def test_ステータスがResolveの状態でステータスを進めるとCloseになる(self) -> None:
+        # given:
+        # タスクを新規作成してステータスをResolveまで進める
+        task = Task.create("Qiitaに記事を投稿する")
+        task.next_status()
+        task.next_status()
+        task.next_status()
```

ワイ「↑こうや」
ワイ「そんで、次に」

> ① Given (前提条件) → 「ステータスをResolveな状態にして」
> **② When (操作) → 「ステータスを進めると」**
> ③ Then (結果) → 「ステータスがCloseになるよね」

ワイ「↑の②の部分を書く・・・」

```diff_python:test_task.py
class TestNextStatus(TestCase):

    def test_ステータスがResolveの状態でステータスを進めるとCloseになる(self) -> None:
        # given:
        # タスクを新規作成してステータスをResolveまで進める
        task = Task.create("Qiitaに記事を投稿する")
        task.next_status()
        task.next_status()
        task.next_status()

+        # when:
+        task.next_status()
```

ワイ「↑こうや！」
ワイ「ほんで、最後に」

> ① Given (前提条件) → 「ステータスをResolveな状態にして」
> ② When (操作) → 「ステータスを進めると」
> **③ Then (結果) → 「ステータスがCloseになるよね」**

ワイ「↑の③の部分を書いて・・・」

```diff_python:test_task.py
class TestNextStatus(TestCase):

    def test_ステータスがResolveの状態でステータスを進めるとCloseになる(self) -> None:
        # given:
        # タスクを新規作成してステータスをResolveまで進める
        task = Task.create("Qiitaに記事を投稿する")
        task.next_status()
        task.next_status()
        task.next_status()

        # when:
        task.next_status()

+        # then:
+        self.assertEqual(Status.Close, task.status)
```

ワイ「↑完成や！」
ワイ「おぉー！たしかに」

```python:test_task.py
class TestNextStatus(TestCase):

    def test_ステータスがResolveの状態でステータスを進めるとCloseになる(self) -> None:
        # given:
        # タスクを新規作成してステータスをResolveまで進める
        task = Task.create("Qiitaに記事を投稿する")
        task.next_status()
        task.next_status()
        task.next_status()

        # when:
        task.next_status()

        # then:
        self.assertEqual(Status.Close, task.status)
```

ワイ「↑各ブロックに分けたことで」
ワイ「どこに何が書いてあるのか、ひと目でわかりやすくなったで！」

娘「でしょでしょ！」

ワイ「これなら」

> 現場ワイ「んー、このテストコード・・・」
> 現場ワイ「なんか、ゴニョゴニョやっててようわからんけど」
> 現場ワイ「テスト通ってるから、ヨシッ！」

ワイ「↑ってなることもなさそうやわ！」
ワイ「ありがとうやで、娘ちゃん！」

# まとめ

テストコードは

① Given (前提条件) → 「こんな状態にして」
② When (操作) → 「こんな操作をすると」
③ Then (結果) → 「こんな結果になるよね」

↑な3つのブロックに分けて書くと
どこに何が書いてあるのか、ひと目でわかって可読性が高まる

ワイ「↑こういうことやな」

娘「そうだね！」

**～おしまい～**

# おまけ

今回、記事で使ったコードは以下にありますやでー
https://github.com/wako-p/qiita-given-when-then