簡體   English   中英

如何在單元測試中測試函數的輸出 (stdout/stderr)

[英]How to test a function's output (stdout/stderr) in unit tests

我有一個要測試的簡單功能:

func (t *Thing) print(min_verbosity int, message string) {
    if t.verbosity >= minv {
        fmt.Print(message)
    }
}

但是如何測試函數實際發送到標准輸出的內容呢? Test::Output在 Perl 中做我想要的。 我知道我可以編寫自己所有的樣板來在 Go 中做同樣的事情(如這里所述):

orig = os.Stdout
r,w,_ = os.Pipe()
thing.print("Some message")
var buf bytes.Buffer
io.Copy(&buf, r)
w.Close()
os.Stdout = orig
if(buf.String() != "Some message") {
    t.Error("Failure!")
}

但是對於每一個測試來說,這都是很多額外的工作。 我希望有一種更標准的方法,或者一個抽象庫來處理這個問題。

還需要記住的一件事是,沒有什么可以阻止您編寫函數來避免樣板。

例如,我有一個使用log的命令行應用程序,我編寫了這個函數:

func captureOutput(f func()) string {
    var buf bytes.Buffer
    log.SetOutput(&buf)
    f()
    log.SetOutput(os.Stderr)
    return buf.String()
}

然后像這樣使用它:

output := captureOutput(func() {
    client.RemoveCertificate("www.example.com")
})
assert.Equal(t, "removed certificate www.example.com\n", output)

使用這個斷言庫: http : //godoc.org/github.com/stretchr/testify/assert

你可以做兩件事之一。 首先是使用示例

該包還運行並驗證示例代碼。 示例函數可能包括以“輸出:”開頭的結束行注釋,並在運行測試時與函數的標准輸出進行比較。 (比較忽略前導和尾隨空格。)這些是示例的示例:

func ExampleHello() {
        fmt.Println("hello")
        // Output: hello
}

第二個(更合適的,IMO)是為你的 IO 使用假函數。 在您的代碼中,您執行以下操作:

var myPrint = fmt.Print

func (t *Thing) print(min_verbosity int, message string) {
    if t.verbosity >= minv {
        myPrint(message) // N.B.
    }
}

在你的測試中:

func init() {
    myPrint = fakePrint // fakePrint records everything it's supposed to print.
}

func Test...

另一種選擇是將fmt.Fprintfio.Writer一起使用,該io.Writer在生產代碼中是os.Stdout ,但在測試中可能是bytes.Buffer

您可以考慮在您的函數中添加一個 return 語句以返回實際打印出的字符串。

func (t *Thing) print(min_verbosity int, message string) string {
    if t.verbosity >= minv {
        fmt.Print(message)
        return message
    }
    return ""
}

現在,您的測試可以只根據預期的字符串(而不是打印輸出)檢查返回的字符串。 也許更符合測試驅動開發 (TDD)。

而且,在您的生產代碼中,不需要更改任何內容,因為如果您不需要函數的返回值,則不必分配它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM