Go语言精进之路读书笔记第43条——使用testdata管理测试依赖的外部数据文件
43.1 testdata目录
Go语言规定:Go工具链将忽略名为testdata的目录。
- 开发者可以在名为testdata的目录下存放和管理测试代码依赖的数据文件,数据文件可作为输入也可作为输出
- go test命令在执行时会将被测试程序包源码所在目录设置为其工作目录,可以这样使用
f, err := os.Open("testdata/data-001.txt")
- 不同操作系统对路径分隔符定义有差别,这样使用增加测试代码的可移植性
f, err := os.Open(filepath.Join("testdata", "data-001.txt"))
43.2 golden文件惯用法
golden文件模式:将预期数据采集到文件的过程与测试代码融合到一起
- 测试代码会先将最新的预期结果写入testdata目录下的golden文件中,然后将该结果与从golden文件中读出的结果作比较
func TestAttendeeMarshal(t *testing.T) {
tests := []struct {
fileName string
a Attendee
}{
{
fileName: "attendee1.xml",
a: Attendee{
Name: "robpike",
Age: 60,
Phone: "13912345678",
},
},
}
for _, tt := range tests {
got, err := xml.MarshalIndent(&tt.a, "", " ")
if err != nil {
t.Fatalf("want nil, got %v", err)
}
want, err := ioutil.ReadFile(filepath.Join("testdata", tt.fileName))
if err != nil {
t.Fatalf("open file %s failed: %v", tt.fileName, err)
}
if !bytes.Equal(got, want) {
t.Errorf("want %s, got %s", string(want), string(got))
}
}
}
改造后
var update = flag.Bool("update", false, "update .golden files")
func TestAttendeeMarshal(t *testing.T) {
tests := []struct {
fileName string
a Attendee
}{
{
fileName: "attendee1.golden",
a: Attendee{
Name: "robpike",
Age: 60,
Phone: "13912345678",
},
},
}
for _, tt := range tests {
got, err := xml.MarshalIndent(&tt.a, "", " ")
if err != nil {
t.Fatalf("want nil, got %v", err)
}
golden := filepath.Join("testdata", tt.fileName)
if *update {
ioutil.WriteFile(golden, got, 0644)
}
want, err := ioutil.ReadFile(golden)
if err != nil {
t.Fatalf("open file %s failed: %v", tt.fileName, err)
}
if !bytes.Equal(got, want) {
t.Errorf("want %s, got %s", string(want), string(got))
}
}
}