Go test 传递命令行参数及解析所遇到的错误及解决

概述

这周的服务计算作业是使用 Golang 开发 selpg 命令行程序,selpg 程序详见 开发 Linux 命令行实用程序,笔者对其的 Golang 实现详见 gitee ;

在好不容易实现了 selpg 所需要的函数后,当然是要对其进行测试,但是在编写测试函数过程中,遇到了许多问题,经过一番摸索尝试后,才将其解决,在此将方法记录下来,和大家分享;

ProcessArgsProcessArgsos.Args-s-epflag.XxxVarPpflag.Parse

Go test 传递命令行参数

selpg -s1 -e1 input.txtselpg -s1 -e1 input.txtgo test-args
go test -v -args selpg -s1 -e1 input.txt
func TestProcessArgs(t *testing.T){
	var args selpgArgs
 	expectedArgs := selpgArgs{1, 1, "input.txt", 10, false, ""}
	ProcessArgs(&args)
	if args != expectedArgs {
		t.Errorf("got %v, expected %v", args, expectedArgs)
 	}
}
go test -v -args selpg -s1 -e1 input.txtos.Args
.../selpg.test -test.timeout=10m0s -test.v=true selpg -s1 -e1 input.txt
os.ArgsProcessArgsos.Args-s-eProcessArgs

那么如何才能拿到我们想要的参数呢?很简单,既然需要的参数被放在了最后,那就把前面不需要的参数都去掉不就好了;

os.Args[]stringos
func TestProcessArgs(t *testing.T){
	var args selpgArgs
	expectedArgs := selpgArgs{1, 1, "input.txt", 10, false, ""}
	
	os.Args = os.Args[3:len(os.Args)]
	
	ProcessArgs(&args)
	if args != expectedArgs {
		t.Errorf("got %v, expected %v", args, expectedArgs)
  	}
}
ProcessArgsgo test
ProcessArgsos.Argsos.Argsos.Argsos.Args[]string[]stringos.Args
func TestProcessArgs(t *testing.T){
	var args selpgArgs
	cmd := []string{"selpg", "-s1", "-e1", "input.txt"}	
	expectedArgs := selpgArgs{1, 1, "input.txt", 10, false, ""}
	os.Args = cmd
	ProcessArgs(&args)
	if args != expectedArgs {
		t.Errorf("got %v, expected %v", args, expectedArgs)
	}
}
go test-args

Go test 参数解析

以上只实现了一个测例的测试函数,如果想增加多个测例,只需要简单的修改即可

func TestProcessArgs(t *testing.T) {
    cases := []struct {
        cmd          []string
        expectedArgs selpgArgs
    }{
        {
            []string{"selpg", "-s1", "-e1"},
            selpgArgs{1, 1, "", 10, false, ""},
        },
        {
            []string{"selpg", "-s1", "-e1", "input.txt"},
            selpgArgs{1, 1, "input.txt", 10, false, ""},
        },
    }
    for i, c := range cases {
	var args selpgArgs
	os.Args = c.cmd
	ProcessArgs(&args)
	if args != c.expectedArgs {
	    t.Errorf("case %v: got %v, expected %v", i, args, c.expectedArgs)
	}
    }
}
go testflag redefined
.../selpg.test flag redefined: ...
flagFlagSetCommandLineCommandLine
var CommandLine = NewFlagSet(os.Args[0], ExitOnError)
os.Argsflag.CommandLine
func TestProcessArgs(t *testing.T) {
    cases := []struct {
        cmd          []string
        expectedArgs selpgArgs
    }{
        {
            []string{"selpg", "-s1", "-e1"},
            selpgArgs{1, 1, "", 10, false, ""},
        },
   	{
            []string{"selpg", "-s1", "-e1", "input.txt"},
            selpgArgs{1, 1, "input.txt", 10, false, ""},
        },
    }
    for i, c := range cases {
	var args selpgArgs
	os.Args = c.cmd
	pflag.CommandLine = pflag.NewFlagSet(os.Args[0], pflag.ExitOnError)
	ProcessArgs(&args)
	if args != c.expectedArgs {
	    t.Errorf("case %v: got %v, expected %v", i, args, c.expectedArgs)
	}
    }
}

总结

[]stringos.Argsflagflag.CommandLine = NewFlagSet(os.Args[0], ExitOnError)flag.CommandLine