표준 출력에 기록된 문자열을 Go로 테스트하는 방법

개시하다


본고는 단원 테스트 테스트를 통해 표준 출력의 문자열을 쓰는 방법을 소개한다.이 방법으로 fmt.Print 및 fmtPintf 함수 출력을 테스트할 수 있는 문자열입니다.

문자열의 출력 대상을 표준 출력에서 Buffer로 변경하여 테스트 수행


Go칙os.Pipe 함수를 사용하여 표준 출력 또는 표준 오류 출력의 출력 위치를 수정할 수 있습니다.
이 함수, fmt를 사용합니다.Print 등 표준 출력 (os.Stdout) 에서 출력된 문자열이 예상한 테스트에 부합되는지 작성해 보십시오.

테스트 대상의 함수


테스트 대상 코드.fmt.문자열의 단순 함수는 Print 함수로만 출력됩니다.
// テスト対象の関数
func Print() {
	fmt.Print("test1")
	fmt.Print("test2")
}
이 함수를 실행하면 표준 출력은 문자test1test2를 출력합니다.

테스트 도우미 함수 준비


테스트를 진행하기 전에 다음 테스트용 조수 함수를 준비하세요.조수 함수 중의 os.Pipe 함수를 사용합니다.
// Stdoutに書き込まれた文字列を抽出する関数
// (Stderrも同じ要領で出力先を変更できます)
func extractStdout(t *testing.T, fnc func()) string {
	t.Helper()

	// 既存のStdoutを退避する
	orgStdout := os.Stdout
	defer func() {
		// 出力先を元に戻す
		os.Stdout = orgStdout
	}()
	// パイプの作成(r: Reader, w: Writer)
	r, w, _ := os.Pipe()
	// Stdoutの出力先をパイプのwriterに変更する
	os.Stdout = w
	// テスト対象の関数を実行する
	fnc()
	// Writerをクローズする
	// Writerオブジェクトはクローズするまで処理をブロックするので注意
	w.Close()
	// Bufferに書き込こまれた内容を読み出す
	var buf bytes.Buffer
	if _, err := buf.ReadFrom(r); err != nil {
		t.Fatalf("failed to read buf: %v", err)
	}
	// 文字列を取得する
	return strings.TrimRight(buf.String(), "\n")
}
조수 함수로 독립된 것은 테스트가 실시된 후에 Stdout의 출력 위치로 되돌아오기 위해서이다.출력 주소를 되돌려 주지 않으면 다른 테스트를 할 때 로그를 확인할 수 없기 때문에 주의해야 합니다.앞으로 조수 함수t.Helper()를 잊지 마세요.

테스트 실현


상기 조수 함수를 사용하여 진행된 단원 테스트는 다음과 같다.
// テスト関数
func TestFoo(t *testing.T) {
	// テスト対象の関数が出力した文字列を取得する
	got := extractStdout(t, Print)
	// 想定される文字列
	want := "test1test2"
	if got != want {
		t.Errorf("failed to test. got: %s, want: %s", got, want)
	}
}

총결산

  • os.Pipe를 사용하면.Stdout에서 다른 출력 대상으로 방향 변경 가능
  • 출력 목적지를 변경한 후 반드시 돌아오지 않으면 다른 테스트에 영향을 줄 수 있으니 주의하세요
  • 유닉스의 시스템 호출에 대해 자세히 알면 쉽게 생각할 수 있지만 처음 이 방법을 알았을 때 놀랐다.이번에 소개한 테스트 방법은 로그를 확인할 때 사용하기 때문에 의외로 사용된 부분이 있다고 생각합니다.

    보충: 조수 함수는os입니다.피프로 뭐 해?


    Go os.Pipe 함수를 사용하면 OS의 파일 스크립트에 파이프(Unix의 pipe 시스템 호출)를 생성할 수 있습니다.Go os.Stdout의 실제 상태는 표준 출력에 연결된 파일 객체(os.File)입니다.이 객체를 파이프의 Writer 객체로 대체하여 출력 대상을 변경합니다.다음은 프로그램이 실행될 때와 테스트가 실행될 때의 차이점입니다.
    pipeシステムコール
    프로그램 실행 시
  • fmt.Print 함수는 표준 출력(파일 스크립트의 인덱스 1)에서 문자열
  • 을 출력합니다.
    테스트 수행 시
  • os.Pipe 함수를 사용하여 파이프 생성하기
  • 파일 스크립트의 인덱스 3에 Reader, 인덱스 4에 Writer
  • os.Stdout 객체를 파이프의 Writer 객체로 대체
  • 테스트 대상의 함수 실행
  • fmt.Print 함수 출력 문자열
  • 파이프를 닫는 Writer 객체
  • 파이프의 Reader 객체의 내용을 bytes로 설정합니다.Buffer로 읽기
  • 참고 자료

  • Package os
  • Unix/Linux 프로그래밍 이론과 실천
  • Go의 테스트에서 T.Helper() 를 사용하는 것을 잊지 마십시오.
  • 좋은 웹페이지 즐겨찾기