Go-Tests für Stdin-Interaktionen schreiben
Bei Softwaretests ist es oft notwendig, Tests zu schreiben, die mit stdin, dem Standard-Eingabestream, interagieren. Dies ist besonders relevant, wenn Anwendungen getestet werden, die Eingaben von der Konsole oder einer Benutzeroberfläche lesen.
Betrachten Sie die folgende Go-Anwendung, die Zeilen von stdin liest und sie an stdout zurückgibt:
<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>
Um diese Anwendung zu testen, kann ein Testfall geschrieben werden, um Benutzereingaben zu simulieren und die Ergebnisse mit der erwarteten Ausgabe zu vergleichen:
<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>
Dieser Test kann jedoch mit der Fehlermeldung fehlschlagen: „Wanted: abc, Got: --- FAIL: TestInput (3.32s)".
Um dieses Problem zu beheben, ziehen Sie die folgende Lösung in Betracht:
Anstatt stdin und stdout direkt in der Hauptfunktion zu manipulieren, definieren Sie eine separate Funktion das io.Reader und io.Writer als Parameter akzeptiert und die gewünschten Operationen ausführt. Die Hauptfunktion kann diese Funktion dann aufrufen, was das Testen erleichtert.
Erstellen Sie beispielsweise eine Funktion namens 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>
Rufen Sie im Test direkt die Echo-Funktion auf statt Interaktion mit stdin und 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>
Dieser Test sollte jetzt bestanden werden, da er die Echo-Funktion direkt testet, ohne auf die Manipulation von stdin und stdout angewiesen zu sein.
Das obige ist der detaillierte Inhalt vonWie teste ich Go-Anwendungen, die mit der Standardeingabe (Stdin) interagieren?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!