2014-12-03 23 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) 
}