計算機科学のブログ

テスト駆動開発のパターン(Patterns for Test-Driven Development) TDDを身につける(Mastering TDD) 三角形と辺、正三角形、二等辺三角形、不等辺三角形

テスト駆動開発 (Kent Beck(著)、和田 卓人(翻訳)、オーム社)の第Ⅲ部(テスト駆動開発のパターン(Patterns for Tejst-Driven Development))、第32章(TDDを身につける(Mastering TDD))、どのくらいフィードバックが必要かをSmalltalk、Java、PythonではなくGo言語で取り組んでみる。

コード

triangle_test.go

package triangle

import (
	"errors"
	"fmt"
	"testing"
)

func TestEvaluate(t *testing.T) {
	tests := []struct {
		desc       string
		a, b, c, n int
		err        error
	}{
		{
			"Equilateral",
			2, 2, 2, 1,
			nil,
		},
		{
			"Isosceles",
			1, 2, 2, 2,
			nil,
		},
		{
			"Scalene",
			2, 3, 4, 3,
			nil,
		},
		{
			"Irrational",
			1, 2, 3, 0,
			errors.New("Irrational"),
		},
		{
			"Negative",
			-1, 2, 2, 0,
			errors.New("Negative"),
		},
	}
	for _, test := range tests {
		n, err := evaluate(test.a, test.b, test.c)
		if test.err != nil {
			if fmt.Sprint(err) != fmt.Sprint(test.err) {
				t.Errorf("%v: evaluate(%v, %v, %v) got (_, %v), want (_, %v)",
					test.desc, test.a, test.b, test.c, err, test.err)
			}
		} else if n != test.n {
			t.Errorf("%v: evaluate(%v, %v, %v) got (%v, _), want (%v, _)",
				test.desc, test.a, test.b, test.c, n, test.n)
		}
	}
}

triangle.go

package triangle

import (
	"errors"
)

func evaluate(a, b, c int) (int, error) {
	if a < 0 || b < 0 || c < 0 {
		return 0, errors.New("Negative")
	}
	if a+b == c || b+c == a || c+a == b {
		return 0, errors.New("Irrational")
	}
	if a == b && b == c {
		return 1, nil
	}
	if a == b || a == c || b == c {
		return 2, nil
	}
	if a+b > c || b+c > a || c+a > b {
		return 3, nil
	}
	return 0, errors.New("Invalid")
}

入出力結果(Terminal, Zsh)

% go test
PASS
ok  	_/.../triangle	0.324s
% go test
PASS
ok  	_/.../triangle	0.222s
% go test
# _/.../triangle
triangle_test.go:20:4: missing ',' before newline in composite literal
FAIL	_/.../triangle [setup failed]
% go test
PASS
ok  	_/.../triangle	0.355s
% go test
--- FAIL: TestEvaluate (0.00s)
    triangle_test.go:25: Isosceles: evaluate(1, 2, 2) got (0, <nil>), want (2, <nil>)
FAIL
exit status 1
FAIL	_/.../triangle	0.232s
% go test
PASS
ok  	_/.../triangle	0.226s
% go test
--- FAIL: TestEvaluate (0.00s)
    triangle_test.go:30: Scalene: evaluate(2, 3, 4) got (0, <nil>), want (3, <nil>)
FAIL
exit status 1
FAIL	_/.../triangle	0.073s
% go test
PASS
ok  	_/.../triangle	0.254s
% go test
--- FAIL: TestEvaluate (0.00s)
    triangle_test.go:38: Irrational: evaluate(1, 2, 3) got (3, <nil>), want (0, Irrational)
FAIL
exit status 1
FAIL	_/.../triangle	0.284s
% go test
--- FAIL: TestEvaluate (0.00s)
    triangle_test.go:38: Irrational: evaluate(1, 2, 3) got (3, <nil>), want (0, Irrational)
FAIL
exit status 1
FAIL	_/.../triangle	0.305s
% go test
# _/.../triangle [_/.../triangle.test]
./triangle.go:7:13: undefined: erros
FAIL	_/.../triangle [build failed]
% go test
--- FAIL: TestEvaluate (0.00s)
    triangle_test.go:38: Irrational: evaluate(1, 2, 3) got (0, Irrational), want (0, Irrational)
FAIL
exit status 1
FAIL	_/.../triangle	0.284s
% go test
false
--- FAIL: TestEvaluate (0.00s)
    triangle_test.go:38: Irrational: evaluate(1, 2, 3) got (0, Irrational), want (0, Irrational)
FAIL
exit status 1
FAIL	_/.../triangle	0.248s
% go test
PASS
ok  	_/.../triangle	0.296s
% go test
--- FAIL: TestEvaluate (0.00s)
    triangle_test.go:45: Negative: evaluate(-1, 2, 2) got (_, <nil>), want (_, Negative)
FAIL
exit status 1
FAIL	_/.../triangle	0.226s
% go test
PASS
ok  	_/.../triangle	0.253s
% go test
PASS
ok  	_/.../triangle	0.220s
%