この記事を見る前に、テストに関しては上記の記事に目を通してください。
こちらの記事の参考例を、テストコードで書いてみることにしました。
今回は一つの関数が、期待した通りの値を返してくれるかどうかを、TDDで実装していく。
実装の仕様内容
- 学校のテストの点数の結果によって、評価が変わる
- テストは、0〜100点の採点である
- 80点以上は「優」
- 60点以上79点以下は「良」
- 30点以上59点以下は「可」
- 29点以下は「不」
を実装していく。
実装していく
まず最初に、テストファイルを作成する。
StudentEvaluationTests
で作成する。
次に、Student
の構造体を作成して、関数を作成する(形だけ)。
最初はどんな値の引数を設定しても、""
空文字しか返ってこない返り値を実装。
struct Student {
static func evaluationByScore(score: Int) -> String? {
return ""
}
}
そして、この関数を用いて、
- 引数に値を設定して返って来た値(実際の結果)
- 返って来て欲しい値(期待値)
をテストで実装する。
以下のような実装です。
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
)
すると、
このように、すべてのXCTAssertで、テストが失敗する。
ここから、順番にエラーを生じさせないように、関数を実装していく。
struct Student {
static func evaluationByScore(score: Int) -> String? {
if score > 100 {
return nil
}
return ""
}
}
一番上のAssetを成功できるよう実装。
次は、2つ目
struct Student {
static func evaluationByScore(score: Int) -> String? {
if score > 100 {
return nil
} else if score >= 80 {
return "優"
}
return ""
}
}
テスト実行。
このように繰り返して実装していく。
そこであえて、めんどくさくなったので、雑に実装してみる。
間違い探しだと思って記事をよんでください。
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 ""
}
}
テストを実行すると、
エラーが起きています。
境界値をどちらに含めるかを曖昧に実装してしまうと、想定通りの実装ができていません。その確認をするためにも、テストコードを書くことは重要です。
上記の実装を修正します。
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
}
}
}
(余談)
今回はif文だけを用いて実装しましたが、Studentの構造体の中でSCOREとして列挙型で評価を定義しておいたほうが、実装は楽だと思います。一つ一つエラーを潰していくイメージを持ってもらうために、if文で順番に実装しました。
以上が、簡単なTDDとなります。
このような過程で実装すると、print文で確認しながら行うよりも、①漏れなく実装する+②テストコードとして、関数が正しく実行されているかを、残すことができます。他にもメリットはありますが、ここでは割愛させていただきます。ただ、テストコードの最初の実装の時点で、期待値を曖昧に設定してしまうと、元も子もないので、注意した方が良いです。
他にも良い方法があれば、コメントいただけると大変うれしいです。
良かったと思ったら、いいねやTwitterのフォローよろしくお願いいたします!
https://sites.google.com/view/muranakar
個人でアプリを作成しているので、良かったら覗いてみてください!