Testing 如何修复Go测试输出中的行号? 让我们考虑一下这个简单的测试代码。

Testing 如何修复Go测试输出中的行号? 让我们考虑一下这个简单的测试代码。,testing,go,Testing,Go,(注意:assertSomething在这里非常简单,但通常我会为手头的任务编写一个更专业的助手,它可以查看多个内容,并报告多种类型的错误。) 当我运行go test时,我得到以下信息: --- FAIL: TestFoo (0.00s) hello.go:12: Something's not right FAIL exit status 1 FAIL kos/hello 0.008s 我有两个问题: 1) 错误指向第12行-为什么?t.Error如何找出它是从哪一行调用的

(注意:
assertSomething
在这里非常简单,但通常我会为手头的任务编写一个更专业的助手,它可以查看多个内容,并报告多种类型的错误。)

当我运行
go test
时,我得到以下信息:

--- FAIL: TestFoo (0.00s)
    hello.go:12: Something's not right
FAIL
exit status 1
FAIL    kos/hello   0.008s
我有两个问题:

1) 错误指向第12行-为什么?
t.Error
如何找出它是从哪一行调用的

2) 在helper中,我想指定
t.Error
应该看起来堆栈级别更高,以确定要打印的行号,这样我将得到如下消息:

--- FAIL: TestFoo (0.00s)
    hello.go:7: Something's not right
Python允许我这样做,例如,在-我如何在这里实现等价物?

您可以按照自己的要求执行,您可以通过了解
t.Error
的工作原理。我想这个函数就是你想要的

但是,如果您有大量的检查代码,并且由于某种原因它在您的测试中被复制,那么最好将其提取为返回错误的函数,而不是传递testing.T并使其成为“断言”。事实上,该语言明确禁止编写断言函数

但我认为惯用测试代码应该是这样的。它是表驱动的,案例包括输入和预期输出,当测试失败时,会产生非常清晰的错误消息

package hello

import "testing"

func TestFoo(t *testing.T) {
    cases := []struct {
        a, b, want int
    }{
        {2, 2, 4},
        {2, 3, 6},
    }
    for _, c := range cases {
        if got := operation(c.a, c.b); got != c.want {
            t.Errorf("operation(%d, %d) = %d, want %d", c.a, c.b, got, c.want)
        }
    }
}

func operation(a, b int) int {
    return a + b
}
从那以后,情况就变了1.9

Helper()
方法已添加到
testing.T
testing.B
。它旨在从测试帮助程序(如
assertSomething
)中调用,以指示函数是帮助程序,我们对来自它的行号不感兴趣

package main

import "testing"

func TestFoo(t *testing.T) {
    assertSomething(t, 2+2 == 4) // line 6
    assertSomething(t, 2+3 == 6) // line 7
}

func assertSomething(t *testing.T, expected bool) {
    if !expected {
        t.Helper()
        t.Error("Something's not right") // line 12
    }
}
输出包含正确的行号:

=== RUN   TestFoo
--- FAIL: TestFoo (0.00s)
    main.go:7: Something's not right
FAIL

您也可以在运动场上玩。

就1而言,它可能用于此目的。为
skip
提供一个不同的数字,以提升某些级别。我不确定您是否可以告诉
test.XXX
在不更改测试包代码的情况下执行此操作。哇,谢谢。对于测试有状态异步代码,有没有比“在一个通道中放入某些内容,在另一个通道中断言某些内容,然后重复”更惯用的方法?有什么我可以参考的例子吗?我不认为我可以编写表驱动的。唉,更复杂的测试助手(不是断言)是有用的,需要根据FAQ条目中记录的原因调整调用级别-如果他们执行多个检查,他们应该能够添加多个失败。不幸的是,添加调用站点的魔力隐藏在一个未报告的助手(装饰方法)中,因此添加此功能需要相当多的复制或替代测试库。例如,您可能希望在几个实现InterfaceEvery的对象上重复相同的一系列测试!谢谢你的信息。从围棋的角度来看,设计也不错:P
package main

import "testing"

func TestFoo(t *testing.T) {
    assertSomething(t, 2+2 == 4) // line 6
    assertSomething(t, 2+3 == 6) // line 7
}

func assertSomething(t *testing.T, expected bool) {
    if !expected {
        t.Helper()
        t.Error("Something's not right") // line 12
    }
}
=== RUN   TestFoo
--- FAIL: TestFoo (0.00s)
    main.go:7: Something's not right
FAIL