如何管理需要 API 密钥的测试

huangapple go评论72阅读模式
英文:

How to manage tests which require an API key

问题

我有一些封闭测试,它们运行良好。foo.go 文件中的代码在 foo_test.go 文件中进行测试。

但是我还有一些需要使用 API 密钥的测试,我希望将这些测试与封闭测试分开,因为我们不在 CI 中运行它们。

我应该如何有效地将这些测试分离,并使其与 Go 工具和生态系统良好地配合?

英文:

I have some hermetic tests, and those work fine. Code in foo.go gets tested in foo_test.go.

But also I have some tests which need an API key, and I want to keep these tests separate from the hermetic tests, since we don't run them in CI.

How can I effectively segregate and these tests in a way that works well with the Go tools and ecosystem?

答案1

得分: 3

有几种方法可以跳过测试。其中大多数方法都利用了testing.T.Skip(Now)。以下是一些常见的使用情况。然而,由于这只是一个普通的函数调用,你可以根据需要进行创造性的操作。

使用环境变量

package main

import (
	"os"
	"testing"
)

func TestAlways(t *testing.T) {
}

func TestSometimes(t *testing.T) {
	key := os.Getenv("FOO_API_KEY")
	if key == "" {
		t.Skip("FOO_API_KEY为空")
	}
}

运行其中之一:

go test -v
FOO_API_KEY=bar go test -v

使用内置的short标志

package main

import (
	"testing"
)

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

func TestSometimes(t *testing.T) {
	if testing.Short() {
		t.Skip("-short已设置")
	}

	// ...
}

运行其中之一:

go test -v -short
go test -v

使用自定义标志

package main

import (
	"flag"
	"testing"
)

var withFoo = false // 或者设置为true以默认运行测试

func init() {
	flag.BoolVar(&withFoo, "with-foo", withFoo, "包括foo测试")
}

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

func TestSometimes(t *testing.T) {
	if !withFoo {
		t.Skip("-with-foo未设置")
	}

	// ...
}

运行其中之一:

go test -v
go test -v -with-foo

使用构建约束

// main_test.go
package main

import (
	"testing"
)

func TestAlways(t *testing.T) {
    // ...
}
// foo_test.go
//go:build foo
package main

import (
	"testing"
)

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

运行其中之一:

go test -v
go test -v -tags=foo

请注意,使用构建标签时,输出不会指示测试已被跳过。除非在命令行(或GOFLAGS中)包含构建标签,否则带有标签的.go文件对编译器来说是不可见的。

英文:

There are several ways to skip tests. Most of them leverage testing.T.Skip(Now). Following are a few common use-cases for SkipNow. However, since this is just like any old function call you can get as creative as you want.

Using an environment variable

package main

import (
	"os"
	"testing"
)

func TestAlways(t *testing.T) {
}

func TestSometimes(t *testing.T) {
	key := os.Getenv("FOO_API_KEY")
	if key == "" {
		t.Skip("FOO_API_KEY is empty")
	}
}

Run one of:

go test -v
FOO_API_KEY=bar go test -v

Using the built-in short flag

package main

import (
	"testing"
)

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

func TestSometimes(t *testing.T) {
	if testing.Short() {
		t.Skip("-short is set")
	}

	// ...
}

Run one of:

go test -v -short
go test -v

Using a custom flag

package main

import (
	"flag"
	"testing"
)

var withFoo = false // or true to run test by default

func init() {
	flag.BoolVar(&withFoo, "with-foo", withFoo, "Include foo tests")
}

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

func TestSometimes(t *testing.T) {
	if !withFoo {
		t.Skip("-with-foo is not set")
	}

	// ...
}

Run one of:

go test -v
go test -v -with-foo

Using build constraints

// main_test.go
package main

import (
	"testing"
)

func TestAlways(t *testing.T) {
    // ...
}
// foo_test.go
//go:build foo
package main

import (
	"testing"
)

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

Run one of:

go test -v
go test -v -tags=foo

Note that with build tags the output will not indicate that tests have been skipped. The tagged .go files simply become invisible to the compiler unless the build tag is included on the command line (or in GOFLAGS).

huangapple
  • 本文由 发表于 2023年1月9日 21:34:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/75058057.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定