2014-12-03 24 views
3

我想测试一个golang命令行应用程序的输出,但我不太知道怎么做,用GO的测试库。你怎么测试golang命令行输出

比方说,我有一个这样的程序:

package main 

import (
    "flag" 
    "fmt" 
) 

func main() { 
    const (
     cityDefault = "San Francisco" 
     cityDoc  = "the city you want the forecast for" 
    ) 
    var city string 
    flag.StringVar(&city, "city", cityDefault, cityDoc) 
    flag.StringVar(&city, "c", cityDefault, cityDoc) 
    flag.Parse() 

    fmt.Println(city) 
} 

我想测试这两种:

$ ./myapp -c "Los Angeles" 
$ ./myapp -city "Los Angeles" 

...输出Lost Angeles。所以,我想问题是,你如何去整合测试golang命令行应用程序的输出?

+0

可能重复[如何在走我的单元测试的命令行标志?(http://stackoverflow.com/questions/17412908/how-do-i-unit-test-command-line-国旗,在-GO) – TheHippo 2014-12-03 18:26:57

+0

@TheHippo我的问题是不雷尔y关于如何测试标志本身。我给出的例子有点归结到这一点,但主要是因为它是一个简单的例子。设想一个更复杂的应用程序,其中有许多其他功能单独进行测试。我想集成测试使用这些组件的应用程序的输出。 – 2014-12-03 18:35:41

回答

2

如何test "$(./myapp -c "Los Angeles")" = "Los Angeles" 与同为-city。这与Go无关,只需让您的集成测试套件进行测试即可。

+0

当然,这是有道理的。我想我希望从你那里得到更多关于你如何去做这件事的指导。但是我猜这最终会让Stack Overflow响应变得过于开放,因为它会转变成一种自以为是的工具链讨论(天堂禁止)。不过,我认为这是指向正确的方向。谢谢。 – 2014-12-03 18:47:41

1

这是解析命令行参数的一个坏榜样,但它表明我用我的应用程序来测试命令行参数的框架。

main.go

package main 

import (
    "log" 
    "os" 
) 

func main() { 
    var city string 
    parseFlags(&city, os.Args) 

    log.Println(city) 
} 

func parseFlags(result *string, args []string) { 
    cityDefault := "San Francisco" 

    switch len(args) { 
    case 3: 
     *result = args[2] 
    default: 
     *result = cityDefault 
    } 
} 

main_unit_test.go

package main 

import (
    "log" 
    "testing" 
) 

// TestParseFlags - test our command line flags 
func TestParseFlags(t *testing.T) { 
    var parseFlagsTests = []struct { 
     flags []string // input flags to the command line 
     expected string // expected 
    }{ 
     {[]string{"/fake/loc/main"}, "San Francisco"}, 
     {[]string{"/fake/loc/main", "-c", "Los Angeles"}, "Los Angeles"}, 
     {[]string{"/fake/loc/main", "--city", "Los Angeles"}, "Los Angeles"}, 
    } 

    for _, tt := range parseFlagsTests { 
     var output string 
     parseFlags(&output, tt.flags) 
     if output != tt.expected { 
      t.Errorf("expected: %s, actual: %s", tt.expected, output) 
     } 
    } 
} 

我通常使用this package解析命令行参数在我所有的应用程序。我会组织我的代码如下所示(未显示的测试,但他们一般按照上面的测试的要点):

main.go

package main 

import (
    "log" 
    "os" 

    "myDir/cli" 
) 

func main() { 
    // Grab the user inputed CLI flags 
    cliFlags := cli.FlagsStruct{} 
    cliErr := cli.StartCLI(&cliFlags, os.Args) 
    if cliErr != nil { 
     log.Println("Error grabbing command line args") 
     log.Fatal(cliErr) 
    } 

    // Do stuff ... 
} 

/myDir/cli.go

package cli 

import "github.com/urfave/cli" 

// FlagsStruct - holds command line args 
type FlagsStruct struct { 
    MyFlag string 
} 

// StartCLI - gathers command line args 
func StartCLI(cliFlags *FlagsStruct, args []string) error { 
    app := cli.NewApp() 
    app.Action = func(ctx *cli.Context) error { 
     MyFlag := ctx.GlobalString("my-flag") 

     // build the cli struct to send back to main 
     cliFlags.MyFlag = MyFlag 
     return nil 
    } 
    app.Authors = []cli.Author{ 
     { 
      Email: "[email protected]", 
      Name: "Adam Hanna", 
     }, 
    } 
    app.Flags = []cli.Flag{ 
     cli.StringFlag{ 
      Name: "my-flag, f", 
      Usage: "My flag usage goes here", 
      Value: "myDefault", 
     }, 
    } 
    app.Name = "myAppName" 
    app.Usage = "My App's Usage" 
    app.Version = "0.0.1" 
    return app.Run(args) 
}