Loading

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))
        }
    }
}
posted @ 2024-03-03 10:53  brynchen  阅读(22)  评论(0编辑  收藏  举报