테스트 패키지를 사용할 때 모든 테스트의 단계를 설정하는 전체 테스트 설정 처리를 어떻게 할 수 있습니까?
Nunit의 예로서 [SetUp]
속성이 있습니다.
[TestFixture]
public class SuccessTests
{
[SetUp] public void Init()
{ /* Load test data */ }
}
답변
Go 1.4부터는 설정 / 해체를 구현할 수 있습니다 (각 테스트 전후에 함수를 복사 할 필요 없음). 설명서는 여기 기본 섹션 에 요약되어 있습니다 .
TestMain은 메인 고 루틴에서 실행되며 m.Run 호출과 관련하여 필요한 모든 설정 및 해체를 수행 할 수 있습니다. 그런 다음 m.Run의 결과로 os.Exit를 호출해야합니다.
테스트에 함수가 포함되어 있으면 테스트 func TestMain(m *testing.M)
를 실행하는 대신이 함수가 호출 된다는 것을 알아내는 데 시간이 좀 걸렸습니다 . 이 함수에서 테스트 실행 방법을 정의 할 수 있습니다. 예를 들어 전역 설정 및 해체를 구현할 수 있습니다.
func TestMain(m *testing.M) { setup() code := m.Run() shutdown() os.Exit(code) }
여기에서 몇 가지 다른 예 를 찾을 수 있습니다 .
최신 릴리스에서 Go의 테스트 프레임 워크에 추가 된 TestMain 기능은 여러 테스트 사용 사례를위한 간단한 솔루션입니다. TestMain은 설정 및 종료를 수행하고, 테스트 환경을 제어하고, 자식 프로세스에서 다른 코드를 실행하거나, 테스트 코드에서 유출 된 리소스를 확인하기위한 전역 후크를 제공합니다. 대부분의 패키지에는 TestMain이 필요하지 않지만 필요할 때 추가 할 수 있습니다.
답변
이것은 파일에 init()
함수를 넣어서 얻을 수 있습니다 _test.go
. 이것은 init()
함수 전에 실행 됩니다.
// package_test.go
package main
func init() {
/* load test data */
}
_test.init ()는 패키지 init () 함수보다 먼저 호출됩니다.
답변
단위 테스트에 대한 간단한 함수가 주어지면 :
package math
func Sum(a, b int) int {
return a + b
}
분해 기능을 반환하는 설정 기능으로 테스트 할 수 있습니다. 그리고 setup ()을 호출 한 후 teardown ()을 지연 호출 할 수 있습니다.
package math
import "testing"
func setupTestCase(t *testing.T) func(t *testing.T) {
t.Log("setup test case")
return func(t *testing.T) {
t.Log("teardown test case")
}
}
func setupSubTest(t *testing.T) func(t *testing.T) {
t.Log("setup sub test")
return func(t *testing.T) {
t.Log("teardown sub test")
}
}
func TestAddition(t *testing.T) {
cases := []struct {
name string
a int
b int
expected int
}{
{"add", 2, 2, 4},
{"minus", 0, -2, -2},
{"zero", 0, 0, 0},
}
teardownTestCase := setupTestCase(t)
defer teardownTestCase(t)
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
teardownSubTest := setupSubTest(t)
defer teardownSubTest(t)
result := Sum(tc.a, tc.b)
if result != tc.expected {
t.Fatalf("expected sum %v, but got %v", tc.expected, result)
}
})
}
}
Go 테스트 도구는 셸 콘솔에 로깅 문을보고합니다.
% go test -v
=== RUN TestAddition
=== RUN TestAddition/add
=== RUN TestAddition/minus
=== RUN TestAddition/zero
--- PASS: TestAddition (0.00s)
math_test.go:6: setup test case
--- PASS: TestAddition/add (0.00s)
math_test.go:13: setup sub test
math_test.go:15: teardown sub test
--- PASS: TestAddition/minus (0.00s)
math_test.go:13: setup sub test
math_test.go:15: teardown sub test
--- PASS: TestAddition/zero (0.00s)
math_test.go:13: setup sub test
math_test.go:15: teardown sub test
math_test.go:8: teardown test case
PASS
ok github.com/kare/go-unit-test-setup-teardown 0.010s
%
이 접근 방식을 사용하여 설정 / 해체에 몇 가지 추가 매개 변수를 전달할 수 있습니다.
답변
일반적으로 이동중인 테스트는 다른 언어와 동일한 스타일로 작성되지 않습니다. 종종 비교적 적은 수의 테스트 함수가 있지만 각각에는 테이블 기반 테스트 사례 집합이 포함됩니다. Go 팀 중 한 사람이 작성한이 기사를 참조하십시오 .
테이블 기반 테스트에서는 테이블에 지정된 개별 테스트 케이스를 실행하는 루프 앞에 설정 코드를 넣고 나중에 정리 코드를 넣으면됩니다.
테스트 함수간에 설정 코드를 공유하고있는 경우 공유 설정 코드를 함수로 추출하고 sync.Once
정확히 한 번 실행하는 것이 중요한 경우 a를 사용할 수 있습니다 (또는 다른 답변에서 알 수 있듯이을 사용 init()
하지만 설정이 단점이 있습니다. 테스트 케이스가 실행되지 않은 경우에도 수행됩니다 (를 사용하여 테스트 케이스를 제한했기 때문일 수 있습니다 go test -run <regexp>
.)
정확히 한 번 실행되는 서로 다른 테스트간에 공유 설정이 필요하다고 생각한다면 실제로 필요한지, 테이블 기반 테스트가 더 좋지 않을지 생각 해봐야합니다.
답변
Go 테스트 프레임 워크에는 NUnit의 SetUp 속성 (스위트의 각 테스트 전에 호출 할 함수 표시)에 해당하는 것이 없습니다 . 하지만 몇 가지 옵션이 있습니다.
-
SetUp
필요한 곳에서 각 테스트에서 함수를 호출하기 만하면 됩니다. -
xUnit 패러다임과 개념을 구현하는 Go의 테스트 프레임 워크 확장을 사용합니다. 세 가지 강력한 옵션이 떠 오릅니다.
이러한 각 라이브러리는 테스트를 다른 xUnit 프레임 워크와 유사한 스위트 / 픽스처로 구성하도록 권장하고 각 메소드 이전에 스위트 / 픽스처 유형에 대한 설정 메소드를 호출합니다 Test*
.
답변
이 문제를 정확히 해결하기 위해 뻔뻔한 플러그, https://github.com/houqp/gtest 를 만들었습니다 .
다음은 간단한 예입니다.
import (
"strings"
"testing"
"github.com/houqp/gtest"
)
type SampleTests struct{}
// Setup and Teardown are invoked per test group run
func (s *SampleTests) Setup(t *testing.T) {}
func (s *SampleTests) Teardown(t *testing.T) {}
// BeforeEach and AfterEach are invoked per test run
func (s *SampleTests) BeforeEach(t *testing.T) {}
func (s *SampleTests) AfterEach(t *testing.T) {}
func (s *SampleTests) SubTestCompare(t *testing.T) {
if 1 != 1 {
t.FailNow()
}
}
func (s *SampleTests) SubTestCheckPrefix(t *testing.T) {
if !strings.HasPrefix("abc", "ab") {
t.FailNow()
}
}
func TestSampleTests(t *testing.T) {
gtest.RunSubTests(t, &SampleTests{})
}
각기 다른 설정 / 해체 루틴을 사용하여 패키지 내에서 원하는 테스트 그룹을 만들 수 있습니다.