Testable Examples in Go

1 개요[ | ]

Testable Examples in Go
  • Andrew Gerrand 2015-05-07

2 소개[ | ]

Godoc 예제는 패키지 문서로 표시되고 테스트로 실행하여 확인되는 Go 코드의 스니펫이니다. 패키지에 대한 godoc 웹 페이지를 방문하고 관련 "실행" 버튼을 클릭하는 사용자에 의해 실행될 수도 있다.

패키지에 대한 실행가능한 문서가 있으면 API가 변경되어도 정보가 최신 상태가 되지 않는다.

표준 라이브러리에는 이러한 많은 예제가 포함되어 있다(예를 들어 strings 패키지 참조).

이 문서는 예제 함수를 작성하는 방법을 설명한다.

3 예제는 테스트이다[ | ]

예제는 패키지 테스트 스위트의 일부로 컴파일(및 선택적으로 실행)된다.

일반적인 테스트와 마찬가지로 예제는 패키지의 _test.go 파일에 있는 함수이다. 그러나 일반적인 테스트 함수와 달리 예제 함수는 인수를 사용하지 않고 Test 대신 Example이라는 단어로 시작한다.

stringutil 패키지Go example 리포지토리의 일부이다. 다음은 Reverse 함수에 관한 example이다.

package stringutil_test

import (
    "fmt"

    "golang.org/x/example/stringutil"
)

func ExampleReverse() {
    fmt.Println(stringutil.Reverse("hello"))
    // Output: olleh
}

이 코드는 stringutil 디렉토리의 example_test.go에 있을 것이다.

Godoc은 Reverse 함수의 문서와 함께 이 예제를 제시할 것이다.

Go.dev blog examples reverse.png

패키지의 테스트 스위트를 실행하면 추가 준비 없이 예제 함수가 실행되는 것을 볼 수 있다.

$ go test -v
=== RUN TestReverse
--- PASS: TestReverse (0.00s)
=== RUN: ExampleReverse
--- PASS: ExampleReverse (0.00s)
PASS
ok      golang.org/x/example/stringutil 0.009s

4 Output 주석[ | ]

ExampleReverse 함수가 "통과"한다는 것은 무엇을 의미하는가?

예제를 실행하면서 테스트 프레임워크는 표준 출력에 기록된 데이터를 캡처한 다음 출력을 예제의 "Output:" 주석과 비교한다. 테스트의 출력이 출력 설명과 매칭되면 테스트가 통과된다.

실패하는 예시를 보기 위해 Ouput 주석 텍스트를 확실히 틀린 것으로 변경해보자.

func ExampleReverse() {
    fmt.Println(stringutil.Reverse("hello"))
    // Output: golly
}

그리고 다시 테스트를 실행해보자.

$ go test
--- FAIL: ExampleReverse (0.00s)
got:
olleh
want:
golly
FAIL

output 주석을 싹 없애면

func ExampleReverse() {
    fmt.Println(stringutil.Reverse("hello"))
}

예제 함수는 컴파일되지만 실행되지는 않는다.

$ go test -v
=== RUN TestReverse
--- PASS: TestReverse (0.00s)
PASS
ok      golang.org/x/example/stringutil 0.009s

ouput 주석이 없는 예제는, 네트워크 접근 같이 단위 테스트로 실행할 수 없는 코드를 시연하는 동시에 예제가 컴파일은 되도록 하고자 할 때 유용하다.

5 예제 함수 이름[ | ]

Godoc은 명명 규칙을 사용하여 예제 함수를 패키지 수준 식별자와 연결한다.

func ExampleFoo()     // Foo 함수 또는 타입 문서화
func ExampleBar_Qux() // 타입 Bar의 Quz 메소드 문서화
func Example()        // 패키지 전체 문서화

이 규칙에 따라, godoc은 Reverse 함수에 대한 문서와 함께 ExampleReverse 예제를 표시한다 .

밑줄과 소문자로 시작하는 접미사를 사용하여 주어진 식별자에 대해 여러 가지 예제를 제공할 수 있다. 이러한 각 예제는 Reverse 기능을 문서화한다.

func ExampleReverse()
func ExampleReverse_second()
func ExampleReverse_third()

6 더 큰 예제[ | ]

좋은 예제를 작성하기 위해 때로는 단순한 함수만으로 부족한 경우가 있다.

예를 들어 sort 패키지를 시연하려면 sort.Interface 메소드를 함수 본문 내에서 선언할 수 없으므로 예제에는 예제 함수 외에 일부 컨텍스트가 포함되어야 한다.

이를 달성하기 위해 "전체 파일 예제"를 사용할 수 있다. _test.go 전체 파일 예제는 정확히 하나의 예제 함수를 포함하고 테스트 또는 벤치마크 함수가 없으며 최소한 하나의 다른 패키지 수준 선언을 포함하는 파일이다. 이러한 예제를 표시할 때 godoc은 전체 파일을 표시한다.

다음은 sort 패키지의 전체 파일 예제이다.

package sort_test

import (
    "fmt"
    "sort"
)

type Person struct {
    Name string
    Age  int
}

func (p Person) String() string {
    return fmt.Sprintf("%s: %d", p.Name, p.Age)
}

// ByAge implements sort.Interface for []Person based on
// the Age field.
type ByAge []Person

func (a ByAge) Len() int           { return len(a) }
func (a ByAge) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
func (a ByAge) Less(i, j int) bool { return a[i].Age < a[j].Age }

func Example() {
    people := []Person{
        {"Bob", 31},
        {"John", 42},
        {"Michael", 17},
        {"Jenny", 26},
    }

    fmt.Println(people)
    sort.Sort(ByAge(people))
    fmt.Println(people)

    // Output:
    // [Bob: 31 John: 42 Michael: 17 Jenny: 26]
    // [Michael: 17 Jenny: 26 Bob: 31 John: 42]
}

패키지에는, 각 파일마다 하나의 예제가 있는, 전체 파일 예제 여러 개가 포함될 수 있다. 실제 사례인 sort 패키지의 소스 코드를 살펴보자.

7 마무리[ | ]

Godoc 예제는 코드를 문서로 작성하고 유지 관리하는 좋은 방법이다. 또한 사용자가 빌드할 수 있는 편집가능하고 작동하며 실행가능한 예제를 제공한다. 이 기능을 사용해보자!

8 같이 보기[ | ]

9 참고[ | ]

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