Go-知识测试-示例测试

2024-07-17 1356阅读

Go-知识测试-示例测试

  • 1. 定义
  • 2. 例子
  • 3. 数据结构
  • 4. 编译过程
  • 5. 执行过程

    建议先看:https://blog.csdn.net/a18792721831/article/details/140062769

    Go-知识测试-工作机制

    1. 定义

    示例测试要保证测试文件以_test.go结尾。

    测试方法必须以ExampleXxx开头。

    测试文件可以与源码处于同一目录,也可以处于单独的目录。

    检测单行输出格式为 // Output:

    检测多行输出格式为 // Output: \n \n \n,每个期望字符串占一行

    检测无序输出格式为 // Unordered output: \n \n \n ,每个期望字符串占一行

    测试字符串会自动忽略字符串前后的空白字符

    如果测试函数中没有Output表示,则测试函数不会被执行

    2. 例子

    在字符串输出中,可能是一行,可能是多行,也有可能是乱序

    函数如下:

    func Hello() {
    	fmt.Println("Hello")
    }
    func HelloTwo() {
    	fmt.Println("Hello")
    	fmt.Println("hi")
    }
    func HelloMore() {
    	m := make(map[string]string)
    	m["hello"] = "Hello"
    	m["hi"] = "hi"
    	m["你好"] = "你好"
    	for _, v := range m {
    		fmt.Println(v)
    	}
    }
    

    接着使用示例测试

    func ExampleHello() {
    	Hello()
    	// Output: Hello
    }
    func ExampleHelloTwo() {
    	HelloTwo()
    	// Output:
    	// Hello
    	// hi
    }
    func ExampleHelloMore() {
    	HelloMore()
    	// Unordered output:
    	// Hello
    	// hi
    	// 你好
    }
    

    使用go test -v 执行示例测试,-v 表示控制台输出结果

    Go-知识测试-示例测试

    3. 数据结构

    每个测试经过编译后都有一个数据结构来承载,对于示例测试就是InternalExample:

    type InternalExample struct {
    	Name      string // 测试名称
    	F         func() // 测试函数
    	Output    string // 期望字符串
    	Unordered bool // 输出是否无序
    }
    

    比如如下case:

    func ExampleHelloMore() {
    	HelloMore()
    	// Unordered output:
    	// Hello
    	// hi
    	// 你好
    }
    

    编译后,数据结构成员

    InternalExample.Name = "ExampleHelloMore"
    InternalExample.F = ExampleHelloMore()
    InternalExample.Output = "hello\nhi\n你好\n"
    InternalExample.Unordered = true
    

    4. 编译过程

    在文章: Go-知识测试-工作机制

    Go-知识测试-工作机制

    中,我们知道编译的时候,会调用src/cmd/go/internal/load/test.go:528

    Go-知识测试-示例测试

    在 load 里面会对四种测试进行分别处理:单元测试,性能测试,Main测试和示例测试

    Go-知识测试-示例测试

    在对测试文件进行处理时,会查看注释中是否包含 output

    Go-知识测试-示例测试

    并且封装好元数据

    Go-知识测试-示例测试

    封装好元数据后,会使用元数据渲染模板,生成Main入口,并同时渲染InternalExample切片

    Go-知识测试-示例测试

    5. 执行过程

    在执行的时候,会执行testing.M.Run,在Run里面会执行runExamples

    Go-知识测试-示例测试

    func runExamples(matchString func(pat, str string) (bool, error), examples []InternalExample) (ran, ok bool) {
    	ok = true
    	var eg InternalExample
    	// 对每个实例测试进行执行
    	for _, eg = range examples {
    	    // 是否匹配
    		matched, err := matchString(*match, eg.Name)
    		if err != nil {
    			fmt.Fprintf(os.Stderr, "testing: invalid regexp for -test.run: %s\n", err)
    			os.Exit(1)
    		}
    		if !matched {
    			continue
    		}
    		ran = true
    		// 执行
    		if !runExample(eg) {
    			ok = false
    		}
    	}
    	return ran, ok
    }
    
    func runExample(eg InternalExample) (ok bool) {
        // 附加输出
    	if *chatty {
    		fmt.Printf("=== RUN   %s\n", eg.Name)
    	}
    	// 获取标准输出
    	stdout := os.Stdout
    	// 新建管道,将标准输出拷贝一份
    	r, w, err := os.Pipe()
    	if err != nil {
    		fmt.Fprintln(os.Stderr, err)
    		os.Exit(1)
    	}
    	os.Stdout = w
    	// 创建一个管道,用于接收标准输出返回的字符串
    	outC := make(chan string)
    	// 在一个单独的 goroutine 中处理拷贝的输出
    	go func() {
    		var buf strings.Builder
    		_, err := io.Copy(&buf, r)
    		r.Close()
    		if err != nil {
    			fmt.Fprintf(os.Stderr, "testing: copying pipe: %v\n", err)
    			os.Exit(1)
    		}
    		outC 
VPS购买请点击我

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

目录[+]