1. TDDの理解
TDDの定義
TDDは、タイトルのテスト駆動開発(Test-Driven Development)であり、アジャイル開発の中核となる技術であり、設計方法論でもあります。TDDの原則は、機能コードを開発する前に単体テストケースコードを書くことであり、テストコードは、どの製品コードを書く必要があるかを決定します。TDDはアジャイルメソッドのコアプラクティスですが、XP(Extreme Programming)に適用できるだけでなく、他の開発メソッドやプロセスにも適用できます。
TDDの基本的な考え方は、テストを通じて開発全体を促進することですが、テスト駆動型の開発は、単なるテスト作業ではなく、要件分析、設計、および品質管理を定量化するプロセスです。基本的なフローチャートは次のとおりです。
TDDサイクルに基づくチュートリアルの「反復」の章を完了する
1.テスト
の作成テストでは、Repeat関数をテストし、Repeat関数を介して、5つの入力文字パラメーターを含む文字列を返します。
次のように、イテレーション/repeat_test.goファイルにテストコードを記述します。
package iteration
import "testing"
func TestRepeat(t *testing.T) {
repeated := Repeat("a")
expected := "aaaaa"
if repeated != expected {
t.Errorf("expected '%q' but got '%q'", expected, repeated)
}
}
2.テストを実行して失敗の結果を取得します
。Repeat関数が定義されていないため、テストの実行時にエラーが報告されます。実行テストの結果は次のとおりです
。3.コンパイル可能な実装を記述し
、TDDメソッドの手順と原則に厳密に従います。コードをコンパイル可能にします。したがって、テストケースに合格できるかどうかを確認できます。
次のように、コードをiteration / repeat.goファイルに記述します。
package iteration
func Repeat(character string) string {
return ""
}
4.テストを実行して、失敗した結果を取得し
ます。ここでは、Repeat関数が定義されており、テストコードの特定の内容をさらに実行できますが、実行中のテストの結果も間違っています。これは、Repeat関数の定義に問題があるためです。実行中のテスト結果は次のとおりです
。5.テストに合格できる実現を記述します。
前のステップの実行中のテスト結果とテストコードの要件に従って、テスト要件を満たすRepeat関数を書き直します。テストコードの特定の内容はすでにわかっているため、要件はこのステップで渡すことができます。 Repeat関数を書き出します。
反復/repeat.goファイルのコードを次のように書き換えます。
package iteration
func Repeat(character string) string {
var repeated string
for i := 0; i < 5; i++ {
repeated = repeated + character
}
return repeated
}
6.テストを実行して成功する結果を取得する
Repeat関数の書き換えはテストコードのニーズを満たしているため、テストを実行すると成功する結果が得られます。実行中のテスト結果は次のとおりです
。7.リファクタリング
コードのrepeat.goファイル内のコードはテストに合格しましたが、コードの標準化と簡潔性にはまだ多くの問題があるため、コードをリファクタリングし、コード要件をリファクタリングする必要があります。コードのロジックと機能を変更せずに、コードをできるだけ簡略化します。簡略化の目的は、コードの読みやすさの向上、コードの実行速度の向上などです。一般的な簡略化方法は、コードを再利用することです(頻繁に使用する変数、定数、関数を個別に定義して、これらの変数、定数、関数をさまざまな場所で呼び出すことができます)。次のようにrepeat.goをリファクタリングします。
package iteration
const repeatCount = 5
func Repeat(character string) string {
var repeated string
for i := 0; i < repeatCount; i++ {
repeated += character
}
return repeated
}
ベンチマーク(benchmarks)
TDDサイクルに基づく「反復」の章の例を完了した後、これに基づいてベンチマークテストを作成することもできます。Goでベンチマークを作成することは、言語のもう1つのレベルの機能であり、TDDでテストを作成することと非常によく似ています。
iteration / reoeat_test.goに基づいて、次のベンチマークコードを追加します。
func BenchmarkRepeat(b *testing.B) {
for i := 0; i < b.N; i++ {
Repeat("a")
}
}
Testing.Bは、不可解な名前のbNへのアクセスを提供します。ベンチマークの実行中、コードはbN回実行され、その所要時間を測定します。コード実行の数はあなたに影響を与えません、テストフレームワークはあなたがより合理的な結果を得ることができるようにそれが考える最高の値を選択します。
go test -bench =。を使用して、ベンチマークテストを実行します。(Windows Powershell環境でgo test -bench = "。"を使用する場合)。テスト結果は次のとおりです。
2.このチュートリアルの「反復」の章の演習を完了する
呼び出し元が文字の繰り返し数を指定できるようにテストコードを変更し、コードを修正します。
ここでは、Repeat関数がパラメータを渡して文字の繰り返し数を指定する必要があります。テストコードを次のように変更します。
package iteration
import "testing"
func TestRepeat(t *testing.T) {
repeated := Repeat("a", 6)
expected := "aaaaaa"
if repeated != expected {
t.Errorf("expected %q but got %q", expected, repeated)
}
}
Repeat関数のパラメーターが変更されたため、テストを実行すると失敗した結果が返されます。テスト結果は次のとおりです。
メインコードを変更してテストに合格すると、コードが次のように変更されます。
package iteration
//Repeat a string with
func Repeat(character string, Readcount int) string {
var repeated string
for i := 0; i < Readcount; i++ {
repeated += character
}
return repeated
}
この時点でテストを実行すると、正常な結果が得られます。次のようにテストを実行します。
関数のドキュメントを改善するために、ExampleRepeatを記述します。
関数のドキュメントを改善するために、サンプルテストも作成する必要があります。サンプルテスト関数ExampleRepeatをrepeat_test.goファイルに追加します。関数コードは次のとおりです。
func ExampleRepeat() {
str := Repeat("b", 10)
fmt.Println(str)
//Output: bbbbbbbbbb
}
実行中のテストの結果は次のとおりです。
これは、テスト関数とサンプルテスト関数が正常に実行されたことを示しています。この時点で関数のドキュメントを確認し、関数のドキュメントにサンプルテストパーツが既に含まれていることを確認します。
stringsパッケージをご覧ください。役立つと思われる関数を見つけ、それらのテストをいくつか作成します
文字列パッケージのドキュメントを確認してください。一部の関数は次のとおりです。
Compare関数とToLower関数を記述してテストするテストコードは、次のように簡単に記述できます。
package main
import (
"fmt"
"strings"
)
func main() {
fmt.Println("compare:", strings.Compare("a", "b")) //Output: -1
fmt.Println("tolower:", strings.ToLower("ABC")) // Output: abc
}
テストコードを実行した結果は次のとおりです。
3、TDDアプリケーション:言語を使用してバブルソートアルゴリズムを実現する
TDDサイクル完了に基づくバブルソートアルゴリズム
1.
テストを記述しますBubbleSort / BubbleSort_test.goファイルにテストコードを次のように記述します。
package BubbleSort
import (
"testing"
)
func TestBubbleSort(t *testing.T) {
arr := [10]int{
7, 6, 3, 9, 5, 0, 1, 4, 2, 8}
sorted := BubbleSort(arr)
expected := [10]int{
0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
for i := 0; i < 10; i++ {
if sorted[i] != expected[i] {
t.Errorf("expected %v but got %v", expected, sorted)
}
}
}
2.テストを実行して失敗した結果を取得します
。BubbleSortt関数が定義されていないため、この時点でテストを実行するとエラーが報告されます。実行テストの結果は次のとおりです。
3.コンパイル可能な実装を記述
します。TDDメソッドの手順と原則に厳密に従ってください。コードをコンパイル可能にするだけで、テストケースに合格するかどうかを確認できます。
次のように、BubbleSort / BubbleSort.goファイルにコードを記述します。
package BubbleSort
func BubbleSort(arr [10]int) [10]int {
return arr
}
4.テストを実行して失敗した結果を取得し
ます。ここでBubbleSort関数が定義されているため、テストコードの特定のコンテンツをさらに実行できますが、実行中のテストの結果は正しくありません。これは、BubbleSort関数の定義に問題があるためです。テスト結果は次のとおりです。
5.テストに合格できる実現を記述します。
前のステップの実行中のテスト結果とテストコードの要件に従って、テスト要件を満たすBubbleSort関数を書き直します。テストコードの具体的な内容はすでにわかっているので、このステップの要件に従ってBubbleSort関数を記述できます。
BubbleSort / BubbleSort.goファイルのコードを次のように書き換えます。
package BubbleSort
//BubbleSort sort a array
func BubbleSort(arr [10]int) [10]int {
for i := 0; i < 9; i++ {
for j := 0; j < 9-i; j++ {
if arr[j] > arr[j+1] {
temp := arr[j]
arr[j] = arr[j+1]
arr[j+1] = temp
}
}
}
return arr
}
6.テストを実行して正常な結果を得る
BubbleSort関数を書き換えると、テストコードのニーズを満たすため、テストを実行すると正常な結果が得られます。実行中のテストの結果は次のとおりです
。7.リファクタリング
上記の方法によると、BubbleSort.goのリファクタリングは次のようになります。
package BubbleSort
const count = 10
//BubbleSort sort a array
func BubbleSort(arr [10]int) [10]int {
for i := 0; i < count-1; i++ {
for j := 0; j < count-1-i; j++ {
if arr[j] > arr[j+1] {
temp := arr[j]
arr[j] = arr[j+1]
arr[j+1] = temp
}
}
}
return arr
}
ベンチマーク(benchmarks)
BubbleSort / BubbleSort.goに基づいて、次のベンチマークコードを追加します。
func BenchmarkBubbleSort(b *testing.B) {
for i := 0; i < b.N; i++ {
arr := [10]int{
7, 6, 3, 9, 5, 0, 1, 4, 2, 8}
BubbleSort(arr)
}
}
go test -bench =。を使用して、ベンチマークテストを実行します。(Windows Powershell環境でgo test -bench = "。"を使用する場合)。テスト結果は次のとおりです。