英文:
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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论