9
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Swift】TDD(テスト駆動開発)-簡単例で説明-

Last updated at Posted at 2023-05-06

この記事を見る前に、テストに関しては上記の記事に目を通してください。
こちらの記事の参考例を、テストコードで書いてみることにしました。

今回は一つの関数が、期待した通りの値を返してくれるかどうかを、TDDで実装していく。

実装の仕様内容

  • 学校のテストの点数の結果によって、評価が変わる
  • テストは、0〜100点の採点である
  • 80点以上は「優」
  • 60点以上79点以下は「良」
  • 30点以上59点以下は「可」
  • 29点以下は「不」
    を実装していく。

実装していく

まず最初に、テストファイルを作成する。
StudentEvaluationTestsで作成する。
スクリーンショット 2023-05-06 9.22.34.png

次に、Studentの構造体を作成して、関数を作成する(形だけ)。
最初はどんな値の引数を設定しても、"" 空文字しか返ってこない返り値を実装。

Student
struct Student {
    static func evaluationByScore(score: Int) -> String? {
        return ""
    }
}

そして、この関数を用いて、
- 引数に値を設定して返って来た値(実際の結果)
- 返って来て欲しい値(期待値)
をテストで実装する。

以下のような実装です。

StudentEvaluationTests.swift
 func test_Studentの点数に対する評価をテストする() throws {
        XCTAssertEqual(Student.evaluationByScore(score: 110), nil)
        XCTAssertEqual(Student.evaluationByScore(score: 100), "優")
        XCTAssertEqual(Student.evaluationByScore(score: 80), "優")
        XCTAssertEqual(Student.evaluationByScore(score: 79), "良")
        XCTAssertEqual(Student.evaluationByScore(score: 60), "良")
        XCTAssertEqual(Student.evaluationByScore(score: 59), "可")
        XCTAssertEqual(Student.evaluationByScore(score: 30), "可")
        XCTAssertEqual(Student.evaluationByScore(score: 29), "不")
        XCTAssertEqual(Student.evaluationByScore(score: 0), "不")
        XCTAssertEqual(Student.evaluationByScore(score: -1), nil)
    }

そして、テストを実行する。(ショートカットキー:⌘ + U
すると、
スクリーンショット 2023-05-06 14.06.36.png
このように、すべてのXCTAssertで、テストが失敗する。
ここから、順番にエラーを生じさせないように、関数を実装していく。

Student
struct Student {
    static func evaluationByScore(score: Int) -> String? {
        if score > 100 {
            return nil
        }
        return ""
    }
}

一番上のAssetを成功できるよう実装。

テストを実行すると、
スクリーンショット 2023-05-06 14.11.12.png
一番上のAssertが成功している。

次は、2つ目

Student
struct Student {
    static func evaluationByScore(score: Int) -> String? {
        if score > 100 {
            return nil
        } else if score >= 80 {
            return "優"
        }
        return ""
    }
}

テスト実行。

スクリーンショット 2023-05-06 14.17.11.png
2つ目も成功。


このように繰り返して実装していく。
そこであえて、めんどくさくなったので、雑に実装してみる。
間違い探しだと思って記事をよんでください。

Student
struct Student {
    static func evaluationByScore(score: Int) -> String? {
        if score > 100 {
            return nil
        } else if score > 80 {
            return "優"
        } else if score > 60 {
            return "良"
        } else if score > 30 {
            return "可"
        } else if score > 0 {
            return "不"
        } else if score < 0 {
            return nil
        }
        return ""
    }
}

テストを実行すると、
スクリーンショット 2023-05-06 14.26.00.png
エラーが起きています。
境界値をどちらに含めるかを曖昧に実装してしまうと、想定通りの実装ができていません。その確認をするためにも、テストコードを書くことは重要です。

上記の実装を修正します。

Student
struct Student {
    static func evaluationByScore(score: Int) -> String? {
        if score > 100 {
            return nil
        } else if score >= 80 {
            return "優"
        } else if score >= 60 {
            return "良"
        } else if score >= 30 {
            return "可"
        } else if score >= 0 {
            return "不"
        } else {
            return nil
        }
    }
}

テストを実行すると、
スクリーンショット 2023-05-06 14.31.39.png
成功することができました。

(余談)
今回はif文だけを用いて実装しましたが、Studentの構造体の中でSCOREとして列挙型で評価を定義しておいたほうが、実装は楽だと思います。一つ一つエラーを潰していくイメージを持ってもらうために、if文で順番に実装しました。


以上が、簡単なTDDとなります。
このような過程で実装すると、print文で確認しながら行うよりも、①漏れなく実装する+②テストコードとして、関数が正しく実行されているかを、残すことができます。他にもメリットはありますが、ここでは割愛させていただきます。ただ、テストコードの最初の実装の時点で、期待値を曖昧に設定してしまうと、元も子もないので、注意した方が良いです。

他にも良い方法があれば、コメントいただけると大変うれしいです。
良かったと思ったら、いいねやTwitterのフォローよろしくお願いいたします!

https://sites.google.com/view/muranakar
個人でアプリを作成しているので、良かったら覗いてみてください!

9
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?