首页  >  文章  >  后端开发  >  如何测试与标准输入(Stdin)交互的 Go 应用程序?

如何测试与标准输入(Stdin)交互的 Go 应用程序?

Mary-Kate Olsen
Mary-Kate Olsen原创
2024-10-27 00:24:02548浏览

How to Test Go Applications That Interact with Standard Input (Stdin)?

为 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.32s)"。

要解决此问题,请考虑以下解决方案:

不要直接在主函数中操作 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中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn