1 개요[ | ]
- Testify - Thou Shalt Write Tests
- 테스티파이 - 테스트를 작성하라
- 코드가 의도대로 작동하는 것을 검증하기 위한 여러가지 도구를 제공하는 Go 패키지 세트
- 장점
- 쉬운 어설션(easy assertion)
- 목 작성(mocking)
- 테스트 스위트 인터페이스 및 함수
- 시작하기
- 한 줄의 코드로 testify를 설치하거나 업데이트하자.
- Go에서 테스트 코드 작성에 대한 소개는 http://golang.org/doc/code.html#Testing 을 참조하자.
- API 문서 http://godoc.org/github.com/stretchr/testify 를 확인하자.
- 테스트 활동을 더 쉽게 하려면 다른 프로젝트인 gorc 도 확인하자.
- 테스트 주도 개발(TDD)도 약간 관련 있다.
2 assert
패키지[ | ]
assert
패키지는 Go에서 더 나은 테스트 코드를 작성할 수 있는 몇 가지 유용한 메소드를 제공한다.- 친절하고 읽기 쉬운 오류 설명 프린트
- 가독성 있는 코드 작성 가능
- 필요시 각 어설션에 설명 메시지 추가
- 다음 예시를 보자.
package yours
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestSomething(t *testing.T) {
// 같음 확인
assert.Equal(t, 123, 123, "they should be equal")
// 같지 않음 확인
assert.NotEqual(t, 123, 456, "they should not be equal")
// nil 확인 (오류에 적절하다)
assert.Nil(t, object)
// nil 아님 확인 (뭔가 있기를 기대할 때 적절하다)
if assert.NotNil(t, object) {
// object가 nil이 아니라는 것을 확인했으므로
// 오류 없이 안전하게 추가 확인을 할 수 있다
assert.Equal(t, "Something", object.Value)
}
}
- 모든 assert func는 testing.T 객체를 첫 번째 인수로 사용한다. 이것이 일반적인 go 테스트 기능을 통해 오류를 작성하는 방법이다.
- 모든 assert func는 어설션이 성공했는지 여부를 나타내는 bool을 반환한다. 이는 특정 조건에서 계속해서 어설션을 계속하려는 경우에 유용하다.
- 여러 번 어설션하려는 경우, 다음과 같이 하자.
package yours
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestSomething(t *testing.T) {
assert := assert.New(t)
// 같음 확인
assert.Equal(123, 123, "they should be equal")
// 같지 않음 확인
assert.NotEqual(123, 456, "they should not be equal")
// nil 확인 (오류에 적절하다)
assert.Nil(object)
// nil 아님 확인 (뭔가 있기를 기대할 때 적절하다)
if assert.NotNil(object) {
// object가 nil이 아니라는 것을 확인했으므로
// 오류 없이 안전하게 추가 확인을 할 수 있다
assert.Equal("Something", object.Value)
}
}
3 require
패키지[ | ]
require
패키지는 assert
패키지와 동일한 글로벌 함수를 제공하지만 boolean 결과를 반환하는 대신 현재 테스트를 종료한다.
자세한 내용은 t.FailNow를 참조하자.
4 mock
패키지[ | ]
mock
패키지는 테스트 코드를 작성할 때 실제 객체 대신 사용할 수 있는 모의 객체를 쉽게 작성할 수 있는 메커니즘을 제공한다.
예시 테스트 함수는, 외부 객체 testObj
에 의존하는 코드 조각을 테스트하며, 기대값를 설정해두고 실제로 그렇게 되는지 확인할 수 있다.
package yours
import (
"testing"
"github.com/stretchr/testify/mock"
)
/*
테스트 객체
*/
// MyMockedObject는 테스트하는 코드가 의존하는 객체를 기술한 인터페이스를 구현한 모의 객체이다.
type MyMockedObject struct{
mock.Mock
}
// DoSomething은 일부 인터페이스를 구현하고 활동을 기록하고, 모의 객체가 지시한대로 return하는 MyMockedObject의 메소드이다.
//
// 실제 객체에서 이 메소드는 유용한 작업을 수행하지만 이것은 모의 객체이므로 스텁으로 처리할 것이다.
//
// NOTE: 이 메소드는 여기서 테스트되지 않으며 이 객체를 사용하는 코드가 테스트된다.
func (m *MyMockedObject) DoSomething(number int) (bool, error) {
args := m.Called(number)
return args.Bool(0), args.Error(1)
}
/*
실제 테스트 함수
*/
// TestSomething은 테스트 객체를 사용하여 테스트할 일부 대상 코드에 대한 어설션을 만드는 방법의 예시이다.
func TestSomething(t *testing.T) {
// 테스트 객체의 인스턴스 생성
testObj := new(MyMockedObject)
// 기대값 설정
testObj.On("DoSomething", 123).Return(true, nil)
// 테스트할 코드 호출
targetFuncThatDoesSomethingWithObj(testObj)
// 기대값을 충족하는지 확인
testObj.AssertExpectations(t)
}
// TestSomethingWithPlaceholder는 테스트 객체를 사용하여 테스트할 일부 대상 코드에 대한 어설션을 만드는 방법에 대한 두 번째 예시이다.
// 이번에는 플레이스홀더를 사용한다. 전달되는 데이터가 일반적으로 동적으로 생성되고 미리 예측할 수 없는 경우(예: 시간에 민감한 해시 포함) 플레이스홀더가 사용될 수 있다.
func TestSomethingWithPlaceholder(t *testing.T) {
// 테스트 객체의 인스턴스 생성
testObj := new(MyMockedObject)
// 인수 목록의 플레이스홀더를 가지고 기대값 설정
testObj.On("DoSomething", mock.Anything).Return(true, nil)
// 테스트할 코드 호출
targetFuncThatDoesSomethingWithObj(testObj)
// 기대값을 충족하는지 확인
testObj.AssertExpectations(t)
}
// TestSomethingElse2는 Unset 메소드를 사용하여 핸들러를 정리한 다음 새 핸들러를 추가하는 방법을 보여주는 세 번째 예시이다.
func TestSomethingElse2(t *testing.T) {
// 테스트 객체의 인스턴스 생성
testObj := new(MyMockedObject)
// 인수 목록의 플레이스홀더를 가지고 기대값 설정
mockCall := testObj.On("DoSomething", mock.Anything).Return(true, nil)
// 테스트할 코드 호출
targetFuncThatDoesSomethingWithObj(testObj)
// 기대값을 충족하는지 확인
testObj.AssertExpectations(t)
// 다른 핸들러를 추가할 수 있도록 기존 핸들러를 제거한다
mockCall.Unset()
// 이제 true 대신 false를 반환한다
testObj.On("DoSomething", mock.Anything).Return(false, nil)
testObj.AssertExpectations(t)
}
모의 코드를 작성하는 방법에 대한 자세한 내용은 mock
패키지에 대한 API 문서를 확인하자.
mockery 도구를 사용하면 인터페이스에 대한 모의 코드를 자동생성하여 mock을 훨씬 빠르게 사용할 수 있다.
5 suite
패키지[ | ]
suite
패키지는 보다 일반적인 객체 지향 언어에서 사용할 수 있는 기능을 제공한다. 이를 통해.0 테스트 스위트를 구조체로 빌드하고, 구조체에 셋업/해체 메서드와 테스트 메소드를 빌드하고, 'go test'로 실행할 수 있다.
suite 예시는 다음과 같다.
// 기본 임포트
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/suite"
)
// suite를 정의하고, testify로부터 빌트인 기본 스위트 기능을 흡수하며, 여기에는 현재 테스트 컨텍스트를 반환하는 T() 메소드가 포함된다.
type ExampleTestSuite struct {
suite.Suite
VariableThatShouldStartAtFive int
}
// 각 테스트 전에 VariableThatShouldStartAtFive가 5로 설정되었는지 확인한다.
func (suite *ExampleTestSuite) SetupTest() {
suite.VariableThatShouldStartAtFive = 5
}
// "Test"로 시작되는 모든 메소드는 스위트 내에서 테스트로서 실행된다.
func (suite *ExampleTestSuite) TestExample() {
assert.Equal(suite.T(), 5, suite.VariableThatShouldStartAtFive)
}
// 'go test'가 이 스위트를 실행하려면 일반적인 테스트 함수를 작성하고 스위트를 suite.Run에 전달해야 한다.
func TestExampleTestSuite(t *testing.T) {
suite.Run(t, new(ExampleTestSuite))
}
suite 패키지에서 제공하는 모든 기능을 사용하는 보다 완전한 예시를 보려면, 예제 테스트 스위트를 살펴보자.
스위트 작성에 대한 자세한 내용은, suite
패키지에 대한 API 문서를 확인하자.
Suite
객체에는 어설션 메서드가 있다.
// 기본 임포트
import (
"testing"
"github.com/stretchr/testify/suite"
)
// suite를 정의하고, testify로부터 빌트인 기본 스위트 기능을 흡수하며, 여기에는 어설션 메소드가 포함된다.
type ExampleTestSuite struct {
suite.Suite
VariableThatShouldStartAtFive int
}
// 각 테스트 전에 VariableThatShouldStartAtFive가 5로 설정되었는지 확인한다.
func (suite *ExampleTestSuite) SetupTest() {
suite.VariableThatShouldStartAtFive = 5
}
// "Test"로 시작되는 모든 메소드는 스위트 내에서 테스트로서 실행된다.
func (suite *ExampleTestSuite) TestExample() {
suite.Equal(suite.VariableThatShouldStartAtFive, 5)
}
// 'go test'가 이 스위트를 실행하려면 일반적인 테스트 함수를 작성하고 스위트를 suite.Run에 전달해야 한다.
func TestExampleTestSuite(t *testing.T) {
suite.Run(t, new(ExampleTestSuite))
}
6 설치[ | ]
- testify를 설치하려면,
go get
을 사용하자.
go get github.com/stretchr/testify
- 이렇게 하면 다음 패키지들을 사용할 수 있게 된다.
github.com/stretchr/testify/assert
github.com/stretchr/testify/require
github.com/stretchr/testify/mock
github.com/stretchr/testify/suite
github.com/stretchr/testify/http (deprecated)
다음 템플릿을 활용하여 자신의 코드에 testify/assert
패키지를 임포트해보자.
package yours
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestSomething(t *testing.T) {
assert.True(t, true, "True is true!")
}
7 최신 유지[ | ]
- testitfy를 최신 버전으로 업데이트하려면,
go get -u github.com/stretchr/testify
를 사용하자.