Golang测试相关问题的求助与讨论

Golang测试相关问题的求助与讨论 我编写了以下简单的代码,以尝试在Go中使用test

package main

// Init 是输入数字,为了简化,将其作为结构体使用,而不是直接调用函数
type Init struct {
	Number int
}

func main() {
	d := Init{Number: 3}
	d.Double()
	println(d.Number, "(which is 3 by 2)")
}

// Double 函数返回输入值乘以2的结果
func (d *Init) Double() {
	d.Number = d.Number * 2
}

func ExampleDouble() {
	// 为图像创建新的缓冲区
	d := Init{Number: 3}
	d.Double()
	println(d.Number, "(which is 3 by 2)")
	// Output:
	// 6 (which is 3 by 2)
}

double_test.go文件的内容是:

package main

import "testing"

func TestDouble(t *testing.T) {
	d := Init{Number: 3}
	d.Double()
	want := 6
	if got := d.Number; got != want {
		println("test failed")
	} else {
		println("test passed")
	}
}

运行时:

go test -v double_test.go

我得到了以下错误:

# command-line-arguments [command-line-arguments.test]
.\double_test.go:6:7: undefined: Init
FAIL    command-line-arguments [build failed]
FAIL

这里有什么问题?测试文件不应该能读取大写的Init类型吗?


更多关于Golang测试相关问题的求助与讨论的实战教程也可以访问 https://www.itying.com/category-94-b0.html

4 回复

你好, 我是一个非常新的初学者,所以如果信息有误请见谅,但如果你像这样运行go命令,只有目标文件会运行,因此现在double.go文件的内容在编译过程中将不可见。尝试不指定目标文件,所以我认为go test -v会起作用。

更多关于Golang测试相关问题的求助与讨论的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


main 包是不可导入的,它也不会自动与同一文件夹中的其他文件合并。请为包使用一个不同于 main 的名称。

avu12:

go test -v

非常感谢,这个方法非常有效,祝你在Go语言的旅程中一切顺利,我也是个新手。

测试文件无法访问Init类型是因为测试文件没有包含被测试的源文件。在Go中,测试文件需要与被测试的代码在同一个包中,并且需要显式包含被测试的文件。以下是解决方案:

问题分析

  1. 测试文件独立编译:当只运行 go test double_test.go 时,编译器只编译测试文件,没有包含 main.go 文件
  2. 包级别可见性Init 类型是导出的(首字母大写),但测试文件找不到它的定义

解决方案

方案1:运行测试时包含所有相关文件

# 运行当前目录下所有测试
go test -v

# 或者明确指定所有文件
go test -v *.go

方案2:修改测试文件,使用正确的测试断言

首先修复 main.go 中的示例测试:

package main

import "fmt"

type Init struct {
	Number int
}

func (d *Init) Double() {
	d.Number = d.Number * 2
}

func ExampleDouble() {
	d := Init{Number: 3}
	d.Double()
	fmt.Println(d.Number)
	// Output: 6
}

然后修复 double_test.go

package main

import "testing"

func TestDouble(t *testing.T) {
	d := Init{Number: 3}
	d.Double()
	
	want := 6
	if got := d.Number; got != want {
		t.Errorf("Double() = %d, want %d", got, want)
	}
}

// 表格驱动测试示例
func TestDoubleTableDriven(t *testing.T) {
	tests := []struct {
		name   string
		input  int
		want   int
	}{
		{"positive number", 3, 6},
		{"zero", 0, 0},
		{"negative number", -5, -10},
	}
	
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			d := Init{Number: tt.input}
			d.Double()
			if got := d.Number; got != tt.want {
				t.Errorf("Double() = %d, want %d", got, tt.want)
			}
		})
	}
}

方案3:使用测试辅助函数(如果需要复杂初始化)

package main

import "testing"

func newInit(n int) *Init {
	return &Init{Number: n}
}

func TestDoubleWithHelper(t *testing.T) {
	d := newInit(3)
	d.Double()
	
	if d.Number != 6 {
		t.Fatalf("expected 6, got %d", d.Number)
	}
}

运行测试

# 运行所有测试
go test -v

# 运行特定测试
go test -v -run TestDouble

# 查看测试覆盖率
go test -cover

# 生成覆盖率报告
go test -coverprofile=coverage.out
go tool cover -html=coverage.out

关键点

  1. 测试文件命名*_test.go 文件需要与被测试文件在同一个包中
  2. 文件包含:运行测试时需要包含所有必要的 .go 文件
  3. 测试函数签名:测试函数必须以 TestXxx 开头,接受 *testing.T 参数
  4. 错误报告:使用 t.Errort.Errorf 而不是 println 来报告测试失败

正确的测试输出应该是:

=== RUN   TestDouble
--- PASS: TestDouble (0.00s)
=== RUN   TestDoubleTableDriven
=== RUN   TestDoubleTableDriven/positive_number
=== RUN   TestDoubleTableDriven/zero
=== RUN   TestDoubleTableDriven/negative_number
--- PASS: TestDoubleTableDriven (0.00s)
PASS
回到顶部