cmd/go: go test -fuzz='^FuzzName$' uses default value of -run flag and runs all regular tests as well

e4yzc0pl  于 5个月前  发布在  Go
关注(0)|答案(6)|浏览(53)

你正在使用哪个版本的Go( gotip version )?

$ gotip version
go version devel go1.18-95b240b2 Mon Jan 3 23:45:12 2022 +0000 darwin/amd64

这个问题在最新版本中是否重现?

是的,这个问题在最新提示( 95b240b )中重现了,而且在我之前安装的gotip版本(从9月22日开始)( 09d3df0 )中也看到了。

你正在使用什么操作系统和处理器架构( go env )?

go env 输出

darwin/amd64

你做了什么?

  • 编写了一个简单的fuzz_test.go文件,并尝试按照文档运行它,但发现它运行时间很长,感到惊讶
  • 添加了 -v 以查看输出,并注意到我的其他所有测试也在运行

你期望看到什么?

我期望 -fuzz=^FuzzName$ 能与文档和规范相匹配,表现得像 -run=^TestName$ :
为了使用变异引擎运行模糊测试,-fuzz将接受一个正则表达式,该表达式必须仅匹配一个模糊测试。在这种情况下,只有模糊测试会运行(忽略所有其他测试)

你看到了什么?

gotip test 继续执行我指定的所有常规测试,以及我指定的单个模糊测试。解决方法是将命令更改为 gotip test -fuzz='^FuzzName$' -run='^FuzzName$' ,然后它按预期运行,只运行一个模糊测试,不运行其他任何内容。

gajydyqb

gajydyqb1#

有趣的是,我们有一个专门锁定这种行为的测试:
go/src/cmd/go/testdata/script/test_fuzz_chatty.txt
第35行到第42行 95b240b
| | # 包含单独单元测试的成功的喧闹模糊测试目标。 |
| | go test -v chatty_with_test_fuzz_test.go -fuzz=Fuzz -fuzztime=1x |
| | stdout ok |
| | stdout PASS |
| | ! stdout FAIL |
| | stdout -count=1 'all good here' |
| | # 验证单元测试只运行一次。 |
| | stdout -count=1 'logged foo' |
它似乎是在 b894834 由 @katiehockman 添加的。听起来是一个相对简单的修复,无论是修改文档,还是更新代码以遵循文档。从代码的Angular 来看,最简单的修复可能是让 -run-fuzz 设置但 -run 未设置时默认为 -fuzz 的值。

ws51t4hk

ws51t4hk2#

感谢你提交这个。你能澄清你在哪里看到的这些文档吗?如果它只在设计草案中,那么这个文档已经过时了(请参见文档顶部的增编),所以不需要更新。

这是有意的行为。参见 $x_{1}e^{0f_1^x}$

bksxznpy

bksxznpy3#

在文档方面,可能只有草案提案让我觉得行为与设计不匹配,或者是我在旧的go help fuzz输出中看到的某些东西。重新阅读gotip help testflag后,我可以看到当前的行为是在那里指定的:

-fuzz regexp
	    Run the fuzz test matching the regular expression. When specified,
	    the command line argument must match exactly one package within the
	    main module, and regexp must match exactly one fuzz test within
	    that package. Fuzzing will occur after tests, benchmarks, seed corpora
	    of other fuzz tests, and examples have completed. See the Fuzzing
	    section of the testing package documentation for details.

但如果我们能在https://go.dev/doc/fuzz/上覆盖它,并突出显示仅使用种子语料库的gotip test运行与通过突变生成模糊测试数据集的-fuzz=FuzzXYZ运行之间的差异,那就太好了。

编辑:我现在也阅读了最新的https://pkg.go.dev/testing@master#hdr-Fuzzing,这可能是我的起点,而不是https://go.dev/doc/fuzz/,因为它确实解释了甚至有“-fuzz和-run标志都可以设置,以便对目标进行模糊测试,但跳过所有其他测试的执行”。
我想当前行为的一个意外部分是,即使我已经通过gotip test .亲自运行了所有测试,当我随后直接运行gotip test -fuzz=FuzzTest .时,测试缓存会失效,因此它将从重新运行所有测试开始,尽管我已经运行了它们并且没有更改任何文件。所以如果我想要为我的所有模糊测试(gotip test -list . | grep '^Fuzz' | parallel -j1 'gotip test -v -run=^{}$ -fuzz=^{}$ -fuzztime=10m')执行一些模糊时间,那么常规测试、示例和基准测试将为每个测试重新运行。
遗憾的是,我们无法忽略-fuzz=参数来保留测试缓存。

wixjitnu

wixjitnu4#

这是一个有趣的想法。我明白你的观点,即使用 -fuzz 运行 go test 可能利用了之前运行 go test 时缓存的测试数据。@bcmills 你对这个可行性有什么看法?我需要再多考虑一下。
一个可能的问题是二进制文件并不完全相同,因为运行 go test -fuzz 以一种与通常运行 go test 不同的方式对测试二进制进行插桩。这种插桩对于单元测试应该是无关紧要的,但它仍然存在。
/cc @golang/fuzzing

92vpleto

92vpleto5#

Bump。我们能解决这个糟糕的UX问题吗?输入-fuzz仍然正常运行测试(而且你必须重复harness名称,如go test -v -fuzz='^FuzzMyFunc$' -run='^FuzzMyFunc$'),更不用说go test没有-v不列出它执行的所有测试(它会执行测试,但输出只会显示失败),但好吧。

dldeef67

dldeef676#

我还想提出一些关于模糊测试用户体验的建议:

  1. go test -fuzz 移动到 go fuzz 可能会更好,以便在两者之间进行区分,避免运行测试和模糊测试之间的混淆,但这并不是什么大问题。
  2. 应该有一个命令来列出所有harnesses 在所有包中递归地 。现在,我们似乎可以通过 go test -list . 在当前包中列出测试。但它有两个很大的缺点:
  • 首先,它打印的最后一行将是类似 "ok 0.023s" 的东西 - 我们不需要那个!
  • 其次,我希望 go test -list ./... 能够像 go test ./... 一样递归地列出测试,即在子目录中执行测试。然而,-list 只会告诉 "no go files in <path>" 。为什么?
  1. 当用户完成运行时,通知他们语料库文件保存在哪里会很好,一个简单的消息 All corpus files can be found in /home/user/.cache/go-build/fuzz/<...> 。我的意思是,我们应该让用户意识到这个存在,他们可以将其存储起来以便继续使用它进行模糊测试,或者将其发送给某人。
  2. 我们应该考虑将语料库和崩溃一起保留。我的意思是,拥有一个与给定harness相关的所有内容的单个目录比将其拆分到不同的路径($GOCACHE/... 用于语料库和 testdata/... 用于崩溃)更有用。
  3. 对于2),应该有一些命令使用 -cover 重新运行项目中的所有harnesses并生成覆盖率报告。应该有每个harness的报告,然后是一个合并覆盖率的单一报告。
    我知道这个问题可能不是讨论这些问题的最佳地方。如果有更好的地方讨论它们,请告诉我/将此帖子移动到其他地方。另外,对于那些是否已经被讨论或计划过的问题,如果没有进行详尽的研究,我也表示歉意。

相关问题