英文:
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 (
"fmt"
"os"
"strings"
)
func main() {
arguments := os.Args
fmt.Println(strings.ToUpper(arguments[1]))
}
The test I have played around with
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")
}
}
}
答案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 (
"fmt"
"io"
"os"
"strings"
)
var out io.Writer = os.Stdout
func main() {
arguments := os.Args
fmt.Fprintf(out, "%s\n", 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 (
"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 {
// 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("expected '%s', but got '%s'", test.Output, actual)
}
}
}
For more detailed description see this article
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论