zoukankan      html  css  js  c++  java
  • 1.go test之测试函数

    在包目录内,所有以_test.go为后缀名的源文件在执行go build时不会被构建成包的一部分,它们是go test测试的一部分。

    *_test.go文件中,有三种类型的函数:测试函数、基准测试(benchmark)函数、示例函数一个测试函数是以Test为函数名前缀的函数,用于测试程序的一些逻辑行为是否正确;go test命令会调用这些测试函数并报告测试结果是PASS或FAIL。基准测试函数是以Benchmark为函数名前缀的函数,它们用于衡量一些函数的性能;go test命令会多次运行基准函数以计算一个平均的执行时间。示例函数是以Example为函数名前缀的函数,提供一个由编译器保证正确性的示例文档。

    本节主要简单介绍一下测试函数,以及go test的一些常用命令。

    现在的目录结构如下:在word包下,含有两个文件,一个是word.go,该文件内有一个判断字符串是否是回文串的函数。另一个是测试文件word_test.go。

    D:workspaceGoRepogoplch11word>ls
    word.go word_test.go

    word.go文件

    package word
    
    import "unicode"
    
    func IsPalindrome(s string) bool {
        // 处理非ASCII字符,比如中文
        var letters []rune
        for _, r := range s {
            if unicode.IsLetter(r) {
                letters = append(letters, unicode.ToLower(r))
            }
        }
    
        length := len(letters)
        for i := 0; i < length/2; i++ {
            if letters[i] != letters[length-i-1] {
                return false
            }
        }
        return true
    }

    一个简单的测试函数可以写成如下,每个测试函数必须导入testing包。测试函数有如下的签名:

    func TestName(t *testing.T) {
        // ...
    }

    特别注意,测试函数的名字必须以Test开头,可选的后缀名必须以大写字母开头,比如

    func TestFoo(t *testing.T) { // 正确
      // ... 
    }
    
    func Testfoo(t *testing.T) { // 错误
      // ... 
    }

    一个简单的测试文件可以写成这样:

    package word
    
    import "testing"
    
    func TestIsPalindrome(t *testing.T) {
        if !IsPalindrome("detartrated") {
            t.Error(`IsPalindrome("detartrated") = false`)
        }
        if !IsPalindrome("kayak") {
            t.Error(`IsPalindrome("kayak") = false`)
        }
    }
    
    func TestNonPalindrome(t *testing.T)  {
       if IsPalindrome("abcd") {
          t.Error(`IsPalindrome("abcd") = true`)
       }
    }

    go test 命令如果没有参数指定具体哪个包,那么将默认采用当前目录对应的包(和go build命令一样)。我们可以用下面的命令构建和运行测试。

    D:workspaceGoRepogoplch11word1>go test
    PASS
    ok      _/D_/workspace/GoRepo/gopl/ch11/word1   0.955s

    如果显示PASS,说明所有测试用例均已经通过。

    参数-v可用于打印每个测试函数的名字和运行时间:

    D:workspaceGoRepogoplch11word1>go test -v
    === RUN   TestIsPalindrome
    --- PASS: TestIsPalindrome (0.00s)
    === RUN   TestNonPalindrome
    --- PASS: TestNonPalindrome (0.00s)
    PASS
    ok      _/D_/workspace/GoRepo/gopl/ch11/word1   1.963s

    参数-run对应一个正则表达式,只有测试函数名被它正确匹配的测试函数才会被go test测试命令运行:

    D:workspaceGoRepogoplch11word1>go test -v -run="Non"
    === RUN   TestNonPalindrome
    --- PASS: TestNonPalindrome (0.00s)
    PASS
    ok      _/D_/workspace/GoRepo/gopl/ch11/word1   0.870s

    此外,还有-race参数也比较常用,用于检测是否存在数据竞争非常有用,这个点在用到的时候再讲。

    最后,在写测试文件的时候,推荐将所有测试数据合并到一个测试的表格中。比如,写成下面这样子。这种表格驱动的测试在Go语言中很常见。我们可以很容易地向表格添加新的测试数据,并且后面的测试逻辑也没有冗余,这样我们可以有更多的精力去完善错误信息。

    func TestAllCases(t *testing.T) {
        // 把所有测试用例装在一个结构体数组中
        var tests = []struct {
            input string
            want bool
        } {
            {"",true},
            {"a",true},
            {"aa",true},
            {"abba",true},
            {"ab",false},
            {"A man, a plan, a canal: Panama",true},
            {"哈哈哈",true},
        }
    
        for _, test := range tests {
            // 如果返回结果不和预期的一致,则测试不通过
            if res := IsPalindrome(test.input); res != test.want {
                t.Errorf("IsPalindrome(%q) = %v", test.input, res)
            }
        }
    }
  • 相关阅读:
    C#方法笔记二:四种类型的参数
    C#+AE 判断点是否在面内的方法
    C#:ref和out的联系及区别。
    C#+AE 调整TOCControl控件中图层的显示顺序
    C# 笔记2:面向对象
    AE10.0 Runtime绑定,如何实现
    C#+AE 用MapControl加载栅格格式文件
    Oracle 10g安装之后解锁Scott的方法
    (转载一篇)Windows7与ArcGIS Desktop9.3冲突问题解决(由QQ安装问题引出)(经本人验证已解决)
    C#方法笔记一:C#4.0新特性:命名参数和可选参数
  • 原文地址:https://www.cnblogs.com/kkbill/p/12461468.html
Copyright © 2011-2022 走看看