為 Stdin 互動編寫 Go 測試
在軟體測試中,通常需要編寫與標準輸入流 stdin 互動的測試。當測試從控制台或使用者介面讀取輸入的應用程式時,這一點尤其重要。
考慮以下Go 應用程序,它從stdin 讀取行並將其回顯到stdout:
<code class="go">package main import ( "bufio" "fmt" "io" "os" ) func main() { reader := bufio.NewReader(os.Stdin) for { fmt.Print("> ") bytes, _, err := reader.ReadLine() if err == io.EOF { os.Exit(0) } fmt.Println(string(bytes)) } }</code>
要測試此應用程序,可以編寫一個測試用例來模擬用戶輸入並將結果與預期輸出進行比較:
<code class="go">package main import ( "bufio" "io" "os" "os/exec" "testing" ) func TestInput(t *testing.T) { subproc := exec.Command(os.Args[0]) stdin, _ := subproc.StdinPipe() stdout, _ := subproc.StdoutPipe() defer stdin.Close() input := "abc\n" subproc.Start() io.WriteString(stdin, input) reader := bufio.NewReader(stdout) bytes, _, _ := reader.ReadLine() output := string(bytes) if input != output { t.Errorf("Wanted: %v, Got: %v", input, output) } subproc.Wait() }</code>
但是,此測試可能會失敗並出現錯誤:"Wanted: abc, Got: --- FAIL: TestInput (3.32)"。
要解決此問題,請考慮以下解決方案:
不要直接在主函數中操作stdin 和stdout,而是定義一個單獨的函數接受io.Reader 和io.Writer 作為參數並執行所需的操作。然後main函數就可以呼叫這個函數了,這樣測試起來就更方便了。
例如建立一個名為Echo的函數:
<code class="go">func Echo(reader io.Reader, writer io.Writer) { reader := bufio.NewReader(reader) for { fmt.Print("> ", writer) bytes, _, err := reader.ReadLine() if err == io.EOF { return } fmt.Println(string(bytes), writer) } }</code>
在測試中,直接呼叫Echo函數,而不是與stdin 和stdout 互動:
<code class="go">// ... func TestInput(t *testing.T) { inputReader := strings.NewReader("abc\n") outputWriter := new(bytes.Buffer) Echo(inputReader, outputWriter) result := outputWriter.String() if input != result { t.Errorf("Wanted: %v, Got: %v", input, result) } }</code>
此測試現在應該通過,因為它直接測試Echo 函數,而不依賴stdin 和stdout 操作。
以上是如何測試與標準輸入(Stdin)互動的 Go 應用程式?的詳細內容。更多資訊請關注PHP中文網其他相關文章!