簡體   English   中英

為 Cobra CLI 傳遞持久性標志以進行測試

[英]Passing Persistant flags for Cobra CLI for testing

我有一個用 Cobra 編寫的 CLI 應用程序。 該應用程序包含一個根命令RootCmd ,其中包含兩個PersistentFlags 持久性標志之一稱為threads ,其默認值為 1 和簡寫-h

    RootCmd.PersistentFlags().IntVarP(&threads, "threads", "t", 1, "Number of concurrent workers, using Stdin overrides this flag")

PersistentPreRun中,我檢查該值是否設置為小於 1 以打印錯誤消息threads can't be less than 1並退出。

問題是我需要為應用程序編寫一些測試,但我找不到設置標志的方法。 目前,我使用os/exec進行測試,這非常煩人並且不提供代碼覆蓋率。

我正在嘗試執行以下操作

func Test(t *testing.T) {
    root := cmd.RootCmd
    root.SetArgs([]string{"-t", "12"})
    // or even: root.SetArgs([]string{"-t 12"})
    root.Execute()
}

這將輸出消息Error: unknown shorthand flag: 't' in -t 12 完全省略標志並嘗試使用任何子命令會顯示錯誤消息,指出該值不能小於 1(請注意,我設置了默認值)。

有沒有辦法設置SetArgs以外的標志或解決方法?

我無法重現這個問題。

我有一個通過運行cobra-cli init創建的簡單 Cobra 應用程序,並且添加了一個子命令foo 這給了我這個布局:

.
├── cmd
│   ├── foo.go
│   └── root.go
├── go.mod
├── go.sum
└── main.go

main.go是最小的:

package main

import "clitest/cmd"

func main() {
  cmd.Execute()
}

cmd/root.go ,我添加了一個PersistentFlag--threads (或-t ):

package cmd

import (
  "fmt"
  "os"

  "github.com/spf13/cobra"
)

var threads int

var rootCmd = &cobra.Command{
  Use:   "clitest",
  Short: "A simple cli test",
  RunE:  runRoot,
}

func runRoot(cmd *cobra.Command, args []string) error {
  fmt.Printf("This is the root command, threads=%d\n", threads)
  return nil
}

func Execute() {
  err := rootCmd.Execute()
  if err != nil {
    os.Exit(1)
  }
}

func init() {
  rootCmd.PersistentFlags().IntVarP(&threads, "threads", "t", 1, "Number of threads")
}

cmd/foo.go ,我定義了一個子命令:

package cmd

import (
  "fmt"

  "github.com/spf13/cobra"
)

var count int

var fooCmd = &cobra.Command{
  Use:   "foo",
  Short: "The foo command",
  RunE:  runFoo,
}

func runFoo(cmd *cobra.Command, args []string) (err error) {
  fmt.Printf("This is the foo command; count=%d\n", count)
  return nil
}

func init() {
  fooCmd.Flags().IntVarP(&count, "count", "c", 0, "Count of foo")
  rootCmd.AddCommand(fooCmd)
}

有了上面的代碼,我可以運行:

$ ./clitest
This is the root command, threads=1
$ ./clitest -t 12
This is the root command, threads=12
$ ./clitest foo
This is the foo command; count=0, threads=1
$ ./clitest foo -t 12 -c 2
This is the foo command; count=2, threads=12

我可以像這樣為 root 命令編寫測試:

package cmd

import (
    "testing"
)

func TestRootCmdWithArgs(t *testing.T) {
    rootCmd.SetArgs([]string{"-t", "12"})
    if err := rootCmd.Execute(); err != nil {
        t.Errorf("failed to execute rootCmd")
    }

    if threads != 12 {
        t.Errorf("expected 12, got %d", threads)
    }
}

func TestRootCmdInvalidArgs(t *testing.T) {
    rootCmd.SetArgs([]string{"--arg-that-does-not-exist"})
    if err := rootCmd.Execute(); err == nil {
        t.Errorf("command succeeded when it should have failed")
    }
}

func TestFooCmdWithArgs(t *testing.T) {
    rootCmd.SetArgs([]string{"foo", "-c", "2"})
    if err := rootCmd.Execute(); err != nil {
        t.Errorf("failed to execute rootCmd")
    }

    if count != 2 {
        t.Errorf("execpted 2, got %d", count)
    }
}

這些測試按預期成功:

$ go test ./...
?       clitest [no test files]
ok      clitest/cmd (cached)

您可以在此存儲庫中找到此答案中引用的所有文件。

我想我發現了問題。 感謝 Iarsks 提供的示例。

我以前的根有


func Execute() {
    RootCmd.CompletionOptions.HiddenDefaultCmd = true
    RootCmd.PersistentFlags().IntVarP(&threads, "threads", "t", 1, "Number of concurrent workers, using Stdin overrides this flag")
    RootCmd.PersistentFlags().StringVarP(&delimiter, "delimiter", "d", ",", "Choose delimiter")
    if err := RootCmd.Execute(); err != nil {
        fmt.Fprintf(os.Stderr, "csvutil encountered an error while executing")
        os.Exit(1)
    }
}

我將這個 function 拆分為:


func init() {
    RootCmd.CompletionOptions.HiddenDefaultCmd = true
    RootCmd.PersistentFlags().IntVarP(&threads, "threads", "t", 1, "Number of concurrent workers, using Stdin overrides this flag")
    RootCmd.PersistentFlags().StringVarP(&delimiter, "delimiter", "d", ",", "Choose delimiter")
}

func Execute() {
    if err := RootCmd.Execute(); err != nil {
        fmt.Fprintf(os.Stderr, "csvutil encountered an error while executing")
        os.Exit(1)
    }
}

現在它工作正常。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM