• Go的简单入门:开始使用模糊测试


    开始使用模糊测试

    一、介绍

    这篇指导介绍Go中基础的模糊测试。通过模糊测试,随机数据会针对您的测试运行,以尝试找出漏洞或导致崩溃的输入。例如,通过模糊测试能够发现SQL注入的漏洞,缓冲区溢出,拒绝服务或者跨域攻击。

    在这篇指导中,你将为一个简单的函数写一个模糊测试,运行Go命令行,调试并修复代码中的问题。

    你将通过下面的部分:

    1. 为你的代码创建一个目录;
    2. 添加代码用于测试;
    3. 添加单元测试;
    4. 添加模糊测试;
    5. 修复两个bug;
    6. 探索更多的资源;

    二、准备

    • 安装Go1.18 或以上版本;
    • 一个用于编写代码的工具;
    • 命令行工具;
    • 一个支持模糊测试的环境。目前仅在 AMD64 和 ARM64 架构上使用覆盖检测进行模糊测试。

    三、实践

    3.1 为你的代码创建一个目录

    1. 打开命令行,进入到工作目录

      从为你将要写的代码创建目录开始。

      $ cd 
      $
      
      • 1
      • 2
    2. 通过命令行,创建一个名称为fuzz的目录

      $ mkdir fuzz
      $ cd fuzz/
      $
      
      • 1
      • 2
      • 3
    3. 为你的代码创建一个模块

      运行go mod init命令,并给它一个新的代码模块路径

      $ go mod init example/fuzz
      go: creating new go.mod: module example/fuzz
      $
      
      • 1
      • 2
      • 3

    接下来,你将添加一些简单代码去反转字符串,它将用于模糊。

    3.2 添加代码用于测试

    在这一步,将添加函数用于反转字符串。

    写代码
    1. 使用文本编辑器,在fuzz目录中,创建一个叫main.go的文件。

    2. 进入main.go文件,在文件的顶部,粘贴下面的代码声明。

      package main
      
      • 1

      一个独立的程序(和标准库相反),总是在main包中。

    3. 在包声明的下面,粘贴下面的函数声明

      func Reverse(s string) string {
        b := []byte(s)
        for i,j := 0, len(b)-1; i < len(b)/2; i, j = i+1, j-1{
          b[i], b[j] = b[j], b[i]
        }
        return string(b)
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7

      函数接受一个字符串,同时循环byte,最后返回反转的字符串。

      注意:这个代码基于golang.org/x/examplestringUtils.Reverse函数。

    4. main.go文件的顶部,在包声明的下面,粘贴下面的main函数去初始化一个字符串,反转它,打印输出,并重复这样做

    func main() {
      input := "The quick brown fox jumped over the lazy dog"
      rev := Reverse(input)
      doubleRev := Reverse(rev)
      fmt.Printf("original: %q\n", input)
      fmt.Printf("reversed: %q\n", rev)
      fmt.Printf("reversed agained: %q\n", doubleRev)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    这个函数将运行Reverse 操作,然后打印命令行的输出。这个是有用的,在实践中查看代码,也是有用的对于发现潜在的debug。

    1. main 函数使用了fmt包,因此,你将需要导入它。

      第一行代码看起来像这样:

      package main
      import "fmt"
      
      • 1
      • 2
    运行代码

    在包含main.go文件目录的命令行下,运行代码:

    $ go run .
    original: "The quick brown fox jumped over the lazy dog"
    reversed: "god yzal eht revo depmuj xof nworb kciuq ehT"
    reversed agained: "The quick brown fox jumped over the lazy dog"
    $ 
    
    • 1
    • 2
    • 3
    • 4
    • 5

    你能看到原始数据,反转的结果数据,然后对结果再次旋转。它和原始数据相等。

    现在代码正在运行,是时间去测试它了。

    3.3 添加单元测试

    在这一步,你将为Reverse函数写基础的单元测试。

    写代码
    1. 使用你的文本编辑器,在fuzz目录中,创建一个文件叫做reverse_test.go

    2. 粘贴下面的代码到reverse_test.go

      package main
      
      import (
        "testing"
      )
      
      func TestReverse(t *testing.T) {
        testcases := []struct {
          in, want string
        }{
          {"Hello, world", "dlrow ,olleH"},
          {" ", " "},
          {"!12345", "54321!"},
        }
        for _, tc := range testcases {
          rev := Reverse(tc.in)
          if rev != tc.want {
            t.Errorf("Reverse: %q, want %q", rev, tc.want)
          }
        }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21

      这个简单的函数将断言,那一列输入的字符串将被正确的反转。

    运行代码

    使用go test 运行单元测试。

    $ go test
    PASS
    ok  	example/fuzz	0.325s
    $ go test -v
    === RUN   TestReverse
    --- PASS: TestReverse (0.00s)
    PASS
    ok  	example/fuzz	0.253s
    $
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    接下来,你将改变单元测试变成模糊测试。

    3.4 添加模糊测试

    单元测试拥有局限性,即每次输入必须被开发者添加到测试。一个模糊测试的好处是它能为你的代码创建输入,并且能确认边缘化的用例,那些你没有想象出来的用例。

    在这一部分你将转换单元测试变成模糊测试,以便于你能通过少量的工作产生更多输入。

    注意,你将保留单元测试、基准测试和模糊测试在相同的*_test.go文件下面。但是对于这个案例,你将转换单元测试成为模糊测试。

    写代码

    在你的文本编译器中,使用下面的模糊测试替换单元测试。

    func FuzzReverse(f *testing.F) {
    	testcase := []string{"Hello World", " ", "!12345"}
    	for _, tc := range testcase {
    		f.Add(tc)
    	}
    	f.Fuzz(func(t *testing.T, orig string) {
    		rev := Reverse(orig)
    		doubleRev := Reverse(rev)
    		if orig != doubleRev {
    			t.Errorf("Before: %q, after: %q", orig, doubleRev)
    		}
    		if utf8.ValidString(orig) && !utf8.ValidString(rev) {
    			t.Errorf("Reverse produced invalid UTF-8 string %q", rev)
    		}
    	})
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    Fuzzing也有一些局限性。在你的单元测试中,你能预测Reverse函数期待的输出,并且验证实际的输出满足预期。

    例如,在测试用例Reverse("Hello, world")单元测试明确返回dlrow ,olleH

    使用模糊查询,你不能预测期待的输出,因为你不能控制输入。

    可是,这里有一些Reverse函数的属性,你能在fuzz测试中进行验证。其中两个能在模糊测试中验证的是:

    1. 反转字符串两次,保留原始值;
    2. 反转的字符串将其状态保留在UTF-8;

    注意在单元测试和模糊测试中的语法不同。

    • 函数以FuzzXxx开头代替TestXxx,并且获取*testing.F代替*testing.T
    • 在你期待看到t.Run执行的地方,你替换成f.Fuzz,在那儿你获取一个模糊测试的函数,它的参数是*testing.T和一个用于模糊执行的类型。单元测试的输入使用 f.Add 作为种子语料库输入提供。

    确保新的包unicode/utf8是被导入。

    package main
    
    import (
      "testing"
      "unicode/utf8"
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    使用模糊测试覆盖单元测试,同时,再次运行测试。

    运行代码
    1. 运行模糊测试,不带模糊属性,确保种子输入能够通过

      $ go test
      PASS
      ok  	example/fuzz	1.089s
      $
      
      • 1
      • 2
      • 3
      • 4
    2. 带上模糊,运行FuzzReverse,去看是否任意的随机产生的字符串输入将产生错误。这次执行使用go test带上一个新的标识,-fuzz

      $ go test -fuzz=Fuzz
      fuzz: elapsed: 0s, gathering baseline coverage: 0/3 completed
      fuzz: elapsed: 0s, gathering baseline coverage: 3/3 completed, now fuzzing with 8 workers
      fuzz: elapsed: 0s, execs: 780 (19533/sec), new interesting: 5 (total: 8)
      --- FAIL: FuzzReverse (0.04s)
          --- FAIL: FuzzReverse (0.00s)
              reverse_test.go:20: Reverse produced invalid UTF-8 string "0\x86\xcb"
      
          Failing input written to testdata/fuzz/FuzzReverse/51fd8412ffb50aa7caa0c705c8d9b9f44bd34af7973d0f5940d60a7b24e6ff34
          To re-run:
          go test -run=FuzzReverse/51fd8412ffb50aa7caa0c705c8d9b9f44bd34af7973d0f5940d60a7b24e6ff34
      FAIL
      exit status 1
      FAIL	example/fuzz	1.106s
      $
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15

      使用模糊测试的时候一个错误产生了,并且引起问题的输入是被写到了一个种子语料库文件。它将在下次go test被调用的时候运行,即便不带-fuzz标识。为了展示引起错误的输入,在编译器中打开被写到testdata/fuzz/FuzzReverse 目录下的语料库文件。你的语料库文件可能包含不同的字符串,但是格式是相同的。

      $ cat testdata/fuzz/FuzzReverse/51fd8412ffb50aa7caa0c705c8d9b9f44bd34af7973d0f5940d60a7b24e6ff34
      go test fuzz v1
      string("ˆ0")
      $
      
      • 1
      • 2
      • 3
      • 4

      语料库文件第一行包含了编码版本。以下每一行代表构成语料库条目的每种类型的值。因为模糊测试的目标仅获取一个值,在版本后面仅仅有一个值。

    3. 再次不带-fuzz运行go test,将使用新的失败种子语料库条目。

      $ go test
      --- FAIL: FuzzReverse (0.00s)
          --- FAIL: FuzzReverse/51fd8412ffb50aa7caa0c705c8d9b9f44bd34af7973d0f5940d60a7b24e6ff34 (0.00s)
              reverse_test.go:20: Reverse produced invalid UTF-8 string "0\x86\xcb"
      FAIL
      exit status 1
      FAIL	example/fuzz	1.076s
      $
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8

    因为我们的测试失败了,是时候进行调试了。

    3.5 修复无效的字符串错误

    在这一部分,你将调试错误,并修复错误。

    在继续之前,请随意花一些时间思考这个问题并尝试自己解决问题。

    诊断错误

    这儿有一些不同的方法用来调试错误。如果你使用VS Code作为你的编译器,你能设置断点进行调试。

    在这个教程中,你将打印有用的调试信息到你的控制台。

    首先,思考对于utf8.ValidString的文档。

    ValidString 报告 s 是否完全由有效的 UTF-8 编码符文组成。

    当前的Reverse函数,一个字节一个字节的反转字符串,这就是我们的问题。为了保留原始字符串的 UTF-8 编码符文,我们必须逐个符文反转字符串。

    为了检查当反转的时候为什么那个输入(在这种情况下,字符串ˆ0)造成了Reverse 产生了一个无效的字符串,你能检查反转字符串符文的数量。

    写代码

    在文本编译器中,使用下面的代码替换FuzzReverse下的模糊目标。

    f.Fuzz(func(t *testing.T, orig string){
      rev := Reverse(orig)
      doubleRev := Reverse(rev)
      t.Logf("Number of runes: orig=%d, rev=%d, doubleRev=%d", utf8.RuneCountInString(orig), utf8.RuneCountInString(rev), utf8.RuneCountInString(doubleRev))
      if orig != doubleRev {
    		t.Errorf("Before: %q, after: %q", orig, doubleRev)
    	}
    	if utf8.ValidString(orig) && !utf8.ValidString(rev) {
    		t.Errorf("Reverse produced invalid UTF-8 string %q", rev)
    	}
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    这个t.Logf行将打印到命令行,如果一个错误发生。获取如果执行测试带上-v,它能帮助你调试特定的议题。

    运行代码

    使用go test运行测试

    $ go test
    --- FAIL: FuzzReverse (0.00s)
        --- FAIL: FuzzReverse/51fd8412ffb50aa7caa0c705c8d9b9f44bd34af7973d0f5940d60a7b24e6ff34 (0.00s)
            reverse_test.go:16: Number of runes: orig=2, rev=3, doubleRev=2
            reverse_test.go:21: Reverse produced invalid UTF-8 string "0\x86\xcb"
    FAIL
    exit status 1
    FAIL	example/fuzz	1.098s
    $
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    整个种子语料库使用字符串,其中每个字符都是一个字节。可是,字符像^需要若干个字节。因此,一个字节一个字节的反转字符串是无效的对于多字节字符。

    注意,如果你好奇关于Go处理字符串,阅读博客Strings, bytes, runes and characters in Go进行更深度的理解。

    为了更好的理解错误,更正反向功能的错误。

    修复错误

    为了修复Reverse函数,让我们按照符文遍历字符,代替通过字节。

    写代码

    在文本编译器中,使用下面的代码替换存在的Reverse()函数。

    func Reverse(s string) string {
      r := []rune(s)
      for i, j := 0, len(r)-1; i<len(r)/2; i, j = i+1, j-1 {
        r[i], r[j] = r[j], r[i]
      }
      return string(r)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    关键的不同是,Reverse现在是遍历字符串中的每个符文,而不是每一个字符。

    运行代码
    1. 使用go test运行测试

      $ go test
      PASS
      ok  	example/fuzz	1.207s
      $
      
      • 1
      • 2
      • 3
      • 4
    2. 再次使用go test -fuzz=Fuzz进行模糊测试,去看现在是否有新的问题。

      $ go test -fuzz=Fuzz
      fuzz: elapsed: 0s, gathering baseline coverage: 0/9 completed
      fuzz: minimizing 31-byte failing input file
      fuzz: elapsed: 0s, gathering baseline coverage: 4/9 completed
      --- FAIL: FuzzReverse (0.03s)
          --- FAIL: FuzzReverse (0.00s)
              reverse_test.go:16: Number of runes: orig=1, rev=1, doubleRev=1
              reverse_test.go:18: Before: "\xa0", after: "�"
      
          Failing input written to testdata/fuzz/FuzzReverse/1d81da97512e2e81bf08cdb8b161334d7d9639f5c5b18255c920ad25370ff2aa
          To re-run:
          go test -run=FuzzReverse/1d81da97512e2e81bf08cdb8b161334d7d9639f5c5b18255c920ad25370ff2aa
      FAIL
      exit status 1
      FAIL	example/fuzz	1.081s
      $
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16

      我们能够看到,经过两次反转的结果是不同于原始结果。这次输入是一个无效的字符串。如果我们使用字符串进行模糊测试,这怎么可能?

      让我们再次调试。

    3.6 修复两次反转的错误

    在这一部分,我们将调试两次反转的错误,并修复这个错误。

    在继续之前,自由的好一些时间去思考这个问题,并修复这个问题。

    诊断错误

    就像之前,有若干个方法调试错误,在这种场景下,使用断点是一个好的方法。

    在这个教程中,我们将在Reverse函数中打印有用的调试信息。

    仔细查看反转的字符串以发现错误。在Go中,一个字符串实际上是一个字符切片。并且能够包含非有效的UTF-8字节。原始字符串是一个字节切片,有一个字节,‘\x91’。 当输入字符串设置为 []rune 时,Go 将字节切片编码为 UTF-8,并将字节替换为 UTF-8 字符 �。 当我们将替换的 UTF-8 字符与输入字节切片进行比较时,它们显然不相等。

    写代码
    1. 在文本编辑器中,使用下面的代码替换Reverse函数

      func Reverse(s string) string {
        fmt.Printf("input: %q\n", s)
        r := []rune(s)
        fmt.Printf("runes: %q\n", r)
        for i, j := 0, len(r)-1; i<len(r)-1; i, j = i+1, j-1 {
          r[i], r[j] = r[j], r[i]
        }
        return string(r)
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9

      这将帮助我们理解发生了什么错误,当字符串转化成符文切片。

    运行代码

    这个时候,我们仅仅想运行失败的测试为了检查日志。为了做这个,我们将使用go test -run

    $ go test -run FuzzReverse/1d81da97512e2e81bf08cdb8b161334d7d9639f5c5b18255c920ad25370ff2aa
    input: "\xa0"
    runes: ['�']
    input: "�"
    runes: ['�']
    --- FAIL: FuzzReverse (0.00s)
        --- FAIL: FuzzReverse/1d81da97512e2e81bf08cdb8b161334d7d9639f5c5b18255c920ad25370ff2aa (0.00s)
            reverse_test.go:16: Number of runes: orig=1, rev=1, doubleRev=1
            reverse_test.go:18: Before: "\xa0", after: "�"
    FAIL
    exit status 1
    FAIL	example/fuzz	0.435s
    $
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    为了运行包含在FuzzXxx/testdata中特定语料库,你能提供{FuzzTestName}/filename-run。这是有用的在调试的时候。

    知道了输入是无效的unicode,让我们修复在Reverse函数的错误。

    修复错误

    为了修复这个问题,如果Reverse输入不是一个有效的的UTF-8,让我们返回一个错误。

    写代码
    1. 在你的编译器中,使用下面的函数替换存在的Reverse函数

      func Reverse(s string) (string, error) {
      	if !utf8.ValidString(s) {
      		return s, errors.New("输入是一个无效的UTF-8")
      	}
      	fmt.Printf("input: %q\n", s)
      	r := []rune(s)
      	fmt.Printf("runes: %q\n", r)
      	for i, j := 0, len(r)-1; i < len(r)-1; i, j = i+1, j-1 {
      		r[i], r[j] = r[j], r[i]
      	}
      	return string(r), nil
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12

      这次改变,当输入的字符串是一个无效的UTF-8时,将返回一个错误。

    2. 因为Reverse 函数现在返回了一个错误,修复main函数去丢弃额外的错误值。使用下面的代码替换已经存在的main函数。

      func main() {
      	input := "The quick brown fox jumped over the lazy dog"
      	rev, revErr := Reverse(input)
      	doubleRev, doubleErr := Reverse(rev)
      	fmt.Printf("original: %q\n", input)
        fmt.Printf("reversed: %q, err: %v\n", rev, revErr)
        fmt.Printf("reversed agained: %q, err: %v\n", doubleRev, doubleErr)
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8

      这些调用将会返回一个nil 错误,因为输入是有效的UTF-8。

    3. 你需要导入errorsunicode/utf8包。在main.go 中的导入语句看起来像这样:

      import (
        "errors"
        "fmt"
        "unicode/utf8"
      )
      
      • 1
      • 2
      • 3
      • 4
      • 5
    4. 修改reverse_test.go 文件,检查错误并跳过测试,如果错误是被返回值产生。

      func FuzzReverse(f *testing.F) {
      	testcase := []string{"Hello World", " ", "!12345"}
      	for _, tc := range testcase {
      		f.Add(tc) // 使用 f.Add 提供种子语料库
      	}
      	f.Fuzz(func(t *testing.T, orig string) {
      		rev, err1 := Reverse(orig)
          if err1 != nil {
            return
          }
      		doubleRev, err2 := Reverse(rev)
          if err2 != nil {
            return
          }
      		if orig != doubleRev {
      			t.Errorf("Before: %q, after: %q", orig, doubleRev)
      		}
      		if utf8.ValidString(orig) && !utf8.ValidString(rev) {
      			t.Errorf("Reverse produced invalid UTF-8 string %q", rev)
      		}
      	})
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22

      除了返回,您还可以调用 t.Skip() 来停止执行该模糊输入。

    运行代码
    1. 使用 go test 运行测试

      $ go test
      PASS
      ok  	example/fuzz	0.491s
      $
      
      • 1
      • 2
      • 3
      • 4
    2. 使用带有go test -fuzz=Fuzz进行模糊化,然后若干秒后通过,使用ctrl-C停止模糊测试

      $ go test -fuzz=Fuzz
      fuzz: elapsed: 0s, gathering baseline coverage: 0/9 completed
      fuzz: elapsed: 0s, gathering baseline coverage: 9/9 completed, now fuzzing with 8 workers
      fuzz: elapsed: 3s, execs: 306930 (102280/sec), new interesting: 32 (total: 41)
      fuzz: elapsed: 6s, execs: 870767 (187915/sec), new interesting: 33 (total: 42)
      fuzz: elapsed: 9s, execs: 1293839 (141029/sec), new interesting: 34 (total: 43)
      ......
      fuzz: elapsed: 1m18s, execs: 10520829 (142569/sec), new interesting: 36 (total: 45)
      fuzz: elapsed: 1m21s, execs: 10909615 (129590/sec), new interesting: 37 (total: 46)
      fuzz: elapsed: 1m24s, execs: 11289776 (126692/sec), new interesting: 37 (total: 46)
      fuzz: elapsed: 1m27s, execs: 11689172 (133198/sec), new interesting: 37 (total: 46)
      fuzz: elapsed: 1m30s, execs: 12068776 (126454/sec), new interesting: 37 (total: 46)
      fuzz: elapsed: 1m33s, execs: 12461830 (131088/sec), new interesting: 37 (total: 46)
      fuzz: elapsed: 1m36s, execs: 12843006 (127040/sec), new interesting: 37 (total: 46)
      ^Cfuzz: elapsed: 1m38s, execs: 13067321 (134596/sec), new interesting: 37 (total: 46)
      PASS
      ok  	example/fuzz	98.729s
      lifeideMacBook-Pro:fuzz lifei$
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18

      除非您通过 -fuzztime 标志,否则模糊测试将一直运行,直到遇到失败的输入。如果没有发生故障,默认是永远运行,并且可以使用 ctrl-C 中断该过程。

    3. 使用go test -fuzz=Fuzz -fuzztime 30s进行模糊化,如果没有发现失败,它将在退出之前模糊 30 秒。

      $ go test -fuzz=Fuzz -fuzztime 30s
      fuzz: elapsed: 0s, gathering baseline coverage: 0/46 completed
      fuzz: elapsed: 0s, gathering baseline coverage: 46/46 completed, now fuzzing with 8 workers
      fuzz: elapsed: 3s, execs: 432881 (144195/sec), new interesting: 3 (total: 49)
      fuzz: elapsed: 6s, execs: 881372 (149498/sec), new interesting: 3 (total: 49)
      fuzz: elapsed: 9s, execs: 1320812 (146554/sec), new interesting: 3 (total: 49)
      fuzz: elapsed: 12s, execs: 1735749 (138323/sec), new interesting: 3 (total: 49)
      fuzz: elapsed: 15s, execs: 2140404 (134860/sec), new interesting: 3 (total: 49)
      fuzz: elapsed: 18s, execs: 2553033 (137558/sec), new interesting: 3 (total: 49)
      fuzz: elapsed: 21s, execs: 2934209 (127072/sec), new interesting: 3 (total: 49)
      fuzz: elapsed: 24s, execs: 3289376 (118391/sec), new interesting: 3 (total: 49)
      fuzz: elapsed: 27s, execs: 3670350 (126988/sec), new interesting: 4 (total: 50)
      fuzz: elapsed: 30s, execs: 4071006 (133510/sec), new interesting: 4 (total: 50)
      fuzz: elapsed: 30s, execs: 4071006 (0/sec), new interesting: 4 (total: 50)
      PASS
      ok  	example/fuzz	30.994s
      $
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17

      模糊化测试通过。

    除了添加-fuzz标识,若干个新的标识能够添加到go test上,在文档中能够看到:custom-settings

    点击文档,go.dev/doc/fuzz 进一步阅读。

  • 相关阅读:
    面试必知的9个性能测试指标,你完全了解吗?
    [深度学习] 计算机视觉低代码工具Supervision库使用指北
    实现无公网IP的公网环境下Windows远程桌面Ubuntu 18.04连接,高效远程办公!
    大气污染扩散模型Calpuff实践
    Vue之transition组件
    JS中字符串常用方法(总结)
    Linux下C语言实现HTTP文件服务器和TCP协议实现网络数据传输
    Vue2 08 了解Vue-cli和Webpack
    硬件设计——串联直流稳压电源
    .net 温故知新【15】:Asp.Net Core WebAPI 配置
  • 原文地址:https://blog.csdn.net/hefrankeleyn/article/details/126691584