运行测试的终端输出

huangapple go评论85阅读模式
英文:

Go test terminal output

问题

我已经翻译好了你提供的内容,请查看以下翻译结果:

我搜索到的Go测试教程使用返回值进行测试。

我想编写一个测试,检查终端的输出。

以下是我想要实现的示例代码:

main.go

package main

import (
    "fmt"
    "os"
    "strings"
)

func main() {
    arguments := os.Args   

    fmt.Println(strings.ToUpper(arguments[1]))
}

我尝试过的测试代码:

main_test.go

package main

import (
    "log"
    "os/exec"
    "testing"
)

type checkResult struct {
    inp      string
    expected string
}

var testCases = []checkResult{
    {"Go <3", "GO <3"},
}

func TestMain(t *testing.T) {
    for _, test := range testCases {
        output, err := exec.Command("go run main.go ", test.inp).Output()
        if err != nil {
            log.Fatal(err)
        }
        if string(output) != (test.expected) {
            t.Fatal("Expected result is wrong")
        }
    }
}
英文:

The Go test tutorials I have searched use the return value to the testing.

I would like to write a test that checks the output from the terminal.

Here is an example of what I want to achieve:

main.go

package main

import (
	&quot;fmt&quot;
	&quot;os&quot;
	&quot;strings&quot;
)

func main() {
	arguments := os.Args   

	fmt.Println(strings.ToUpper(arguments[1]))
}

The test I have played around with

main_test.go

package main

import (
	&quot;log&quot;
	&quot;os/exec&quot;
	&quot;testing&quot;
)

type checkResult struct {
	inp      string
	expected string
}

var testCases = []checkResult{
	{&quot;Go &lt;3&quot;, &quot;GO &lt;3&quot;},
}

func TestMain(t *testing.T) {
	for _, test := range testCases {
		output, err := exec.Command(&quot;go run main.go &quot;, test.inp).Output()
		if err != nil {
			log.Fatal(err)
		}
		if string(output) != (test.expected) {
			t.Fatal(&quot;Expected result is wrong&quot;)
		}
	}
}

答案1

得分: 1

如果你稍微改变一下你的CLI设计,它将更容易进行测试。创建一个类型为io.Writer的全局变量,并使用fmt.Fprintf将输出写入os.Stdout

main.go

package main

import (
	"fmt"
	"io"
	"os"
	"strings"
)

var out io.Writer = os.Stdout

func main() {
	arguments := os.Args

	fmt.Fprintf(out, "%s\n", strings.ToUpper(arguments[1]))
}

现在,在测试场景中,设置变量out以重定向输出和os.Args以获取CLI参数没有问题。

main_test.go

package main

import (
	"bytes"
	"os"
	"testing"
)

func TestOutput(t *testing.T) {
	testData := []struct {
		Args   []string
		Output string
	}{
		{
			Args:   []string{"./macli", "hello"},
			Output: "HELLO\n",
		},
		{
			Args:   []string{"", "Go <3"},
			Output: "GO <3\n",
		},
	}
	for _, test := range testData {
		// 初始化测试
		os.Args = test.Args
		out = bytes.NewBuffer(nil)
		// 运行测试
		main()
		// 评估输出
		if actual := out.(*bytes.Buffer).String(); actual != test.Output {
			t.Errorf("期望值为 '%s',但得到 '%s'", test.Output, actual)
		}
	}
}

更详细的描述请参考这篇文章

英文:

If you change design of your CLI little bit, it will be more testable. Create global variable of type io.Writter and use fmt.Fprintf to write your output into os.Stdout.

main.go

package main

import (
	&quot;fmt&quot;
	&quot;io&quot;
	&quot;os&quot;
	&quot;strings&quot;
)

var out io.Writer = os.Stdout

func main() {
	arguments := os.Args

	fmt.Fprintf(out, &quot;%s\n&quot;, strings.ToUpper(arguments[1]))
}

Now it is no problem to set variable out to redirect output and os.Args to CLI arguments in test scenario.

main_test.go

package main

import (
	&quot;bytes&quot;
	&quot;os&quot;
	&quot;testing&quot;
)

func TestOutput(t *testing.T) {
	testData := []struct {
		Args   []string
		Output string
	}{
		{
			Args:   []string{&quot;./macli&quot;, &quot;hello&quot;},
			Output: &quot;HELLO\n&quot;,
		},
		{
			Args:   []string{&quot;&quot;, &quot;Go &lt;3&quot;},
			Output: &quot;GO &lt;3\n&quot;,
		},
	}
	for _, test := range testData {
		// Init test
		os.Args = test.Args
		out = bytes.NewBuffer(nil)
		// Run test
		main()
		// Evaluate output
		if actual := out.(*bytes.Buffer).String(); actual != test.Output {
			t.Errorf(&quot;expected &#39;%s&#39;, but got &#39;%s&#39;&quot;, test.Output, actual)
		}
	}
}

For more detailed description see this article

huangapple
  • 本文由 发表于 2021年10月24日 03:54:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/69691554.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定