"Go testify 패키지"의 두 판 사이의 차이

95번째 줄: 95번째 줄:


==<code>mock</code> 패키지==
==<code>mock</code> 패키지==
<code>mock</code> 패키지는 테스트 코드를 작성할 때 실제 객체 대신 사용할 수 있는 모의 객체를 쉽게 작성할 수 있는 메커니즘을 제공한다.
예시 테스트 함수는, 외부 객체 <code>testObj</code>에 의존하는 코드 조각을 테스트하며, 기대값를 설정해두고 실제로 그렇게 되는지 확인할 수 있다.
<syntaxhighlight lang='go'>
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)
}
</syntaxhighlight>
==<code>suite</code> 패키지==
==<code>suite</code> 패키지==
==설치==
==설치==

2023년 6월 6일 (화) 16:22 판

1 개요

Testify - Thou Shalt Write Tests
테스티파이 - 테스트를 작성하라
  • 코드가 의도대로 작동하는 것을 검증하기 위한 여러가지 도구를 제공하는 Go 패키지 세트
  • 장점
    • 쉬운 어설션(easy assertion)
    • 목 작성(mocking)
    • 테스트 스위트 인터페이스 및 함수

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)
}

5 suite 패키지

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를 사용하자.

8 같이 보기

9 참고

문서 댓글 ({{ doc_comments.length }})
{{ comment.name }} {{ comment.created | snstime }}