🧪
【Go】Developer eXperience Day 2021における和田さんのテスト駆動開発の解説をGoで実装してみた
動画リンク
勉強になったので人類見ましょう
Developer eXperience Day 【Stream A】 テストコードのリファクタリングが目指すもの
実装
productionコード
int_closed_range.go
package main
import "strconv"
type IntClosedRange struct {
lower int
upper int
}
func (r IntClosedRange) Lower() int {
return r.lower
}
func (r IntClosedRange) Upper() int {
return r.upper
}
func (r IntClosedRange) Notation() string {
// 文字列と数字の結合はgoでは地道な方法しかなかった
return "[" + strconv.Itoa(r.lower) + "," + strconv.Itoa(r.upper) + "]"
}
func (r IntClosedRange) Includes(i int) bool {
return r.lower <= i && i <= r.upper
}
suiteを使って状況>機能という階層整理で書いた
が、整理がちょっと十分でないなとは感じてます。
int_closed_range_test.go
package main
import (
"github.com/stretchr/testify/suite"
"testing"
)
type intClosedRangeSuite struct {
suite.Suite
icRange IntClosedRange
}
func (suite *intClosedRangeSuite) SetupSuite() {
suite.icRange = IntClosedRange{3, 7}
}
func (suite *intClosedRangeSuite) Test_整数閉区間は下端点3を持つ() {
suite.Equal(3, suite.icRange.Lower())
}
func (suite *intClosedRangeSuite) Test_Upperメソッドは上端点7を持つ() {
suite.Equal(7, suite.icRange.Upper())
}
func (suite *intClosedRangeSuite) Test_Notationメソッドは文字列表記を返せる() {
suite.Equal("[3,7]", suite.icRange.Notation())
}
func (suite *intClosedRangeSuite) Test_Includesメソッドは指定した整数を含むか判定できる() {
tests := map[string]struct {
input int
includes bool
}{
"9は含まれない": {9, false},
"5は含まれる": {5, true},
"1は含まれない": {1, false},
"下端点3は含まれる": {3, true},
"上端点7は含まれる": {7, true},
}
for name, test := range tests {
suite.Run(name, func() {
suite.Equal(test.includes, suite.icRange.Includes(test.input))
})
}
}
func Test_整数閉区間を表す(t *testing.T) {
suite.Run(t, new(intClosedRangeSuite))
}
機能>状況という階層整理で書いた
int_closed_range_test.go
package main
import (
"github.com/stretchr/testify/assert"
"testing"
)
func Test_Lowerメソッドは下端点を返せる(t *testing.T) {
icRange := IntClosedRange{3, 7}
assert.Equal(t, 3, icRange.Lower())
}
func Test_Upperメソッドは上端点を返せる(t *testing.T) {
icRange := IntClosedRange{3, 7}
assert.Equal(t, 7, icRange.Upper())
}
func Test_Notationメソッドは文字列表記を返せる(t *testing.T) {
icRange := IntClosedRange{3, 7}
assert.Equal(t, "[3,7]", icRange.Notation())
}
func Test_Includesメソッドは指定した整数を含むか判定できる(t *testing.T) {
tests := map[string]struct {
input int
includes bool
}{
"9は含まれない": {9, false},
"5は含まれる": {5, true},
"1は含まれない": {1, false},
"下端点3は含まれる": {3, true},
"上端点7は含まれる": {7, true},
}
icRange := IntClosedRange{3, 7}
for name, test := range tests {
t.Run(name, func(t *testing.T) {
assert.Equal(t, test.includes, icRange.Includes(test.input))
})
}
}
勉強になったこと・気付き
- Goも日本語メソッドが使える
- suiteがあることを初めて知った
- が、書き方が普段のテストと違うのでちょっと扱いづらいかも
- Goはtable driven testが推奨されているので、そういう意味でも機能>状況という階層整理が合いそう
Discussion