Тестирование приложений на основе urfave / cli с помощью go - PullRequest
0 голосов
/ 24 сентября 2019

Я пишу небольшое CLI-приложение на Golang с использованием инфраструктуры urfave / cli и хотел бы написать для него тесты, но не могу найти никакой полезной информации о том, как тестировать CLI-приложения, специально написанные с помощью urfave./ Cli библиотека.У меня много флагов в приложении, и некоторые из них являются взаимоисключающими, и я хотел бы, чтобы над ними был правильный тест - есть ли у кого-нибудь идеи, как сделать это правильно?

РЕДАКТИРОВАТЬ: рассмотрим следующий минимальный пример приложения с несколькими флагами и ограничениями вокруг них.Как бы вы протестировали использование этих флагов (требования, эксклюзивность и т. Д.) И как они влияют на функции, когда они установлены или нет?

package main

import (
    "errors"
    "fmt"
    "os"

    "github.com/urfave/cli"
)

func doSomething(flag1 string, flag2 string, flag3 bool, flag4 bool) error {
    err := errors.New("something")
    return err
}

func main() {
    app := cli.NewApp()
    app.Name = "greet"
    app.Usage = "fight the loneliness!"

    var flag1, flag2 string
    var flag3, flag4 bool

    app.Flags = []cli.Flag{
        cli.StringFlag{
            Name:        "flag1",
            Value:       "",
            Usage:       "flag1",
            Destination: &flag1,
        },
        cli.StringFlag{
            Name:        "flag2",
            Value:       "",
            Usage:       "flag2",
            Destination: &flag2,
        },
        cli.BoolFlag{
            Name:        "flag3",
            Usage:       "flag3",
            Destination: &flag3,
        },
        cli.BoolFlag{
            Name:        "flag4",
            Usage:       "flag4",
            Destination: &flag4,
        },
    }

    app.Action = func(c *cli.Context) error {

        if flag1 != "" && c.NumFlags() > 1 {
            fmt.Println("--flag1 flag cannot be used with any other flags")
            cli.ShowAppHelp(c)
            os.Exit(1)
        }

        if flag1 == "" && flag2 == "" || c.NumFlags() < 1 {
            fmt.Println("--flag2 is required")
            cli.ShowAppHelp(c)
            os.Exit(1)
        }

        if flag3 && flag4 {
            fmt.Println("--flag3 and --flag4 flags are mutually exclusive")
            cli.ShowAppHelp(c)
            os.Exit(1)
        }

        err := doSomething(flag1, flag2, flag3, flag4)
        return err
    }

}

1 Ответ

0 голосов
/ 25 сентября 2019

Как правильно написал Адриан

так же, как вы тестируете что-либо еще

Учитывая немного измененный пример примера кода проекта

package main

import (
  "fmt"
  "log"
  "os"

  "github.com/urfave/cli"
)

func Friend(c *cli.Context) error {
  fmt.Println("Hello friend!")
  return nil
}

func main() {
  app := cli.NewApp()
  app.Name = "greet"
  app.Usage = "fight the loneliness!"
  app.Action = Friend

  err := app.Run(os.Args)
  if err != nil {
    log.Fatal(err)
  }
}

Поскольку этот код на самом деле печатает что-то, а не возвращает значение, которое вы можете оценить, вы можете использовать тестируемый пример

func ExampleFriend(){
   // Yeah, technically, we can save the error check with the code above
   // but this illustrates how you can make sure the output
   // is not what the testable example expects.
   if err := Friend(nil){
     fmt.Printf("Friend: %s",err)
   }

  // Output:
  // Hello friend!
}

Обратите внимание, что Action ожидает ActionFunc.Где вы определяете, что ActionFunc в значительной степени ваша вещь.Это может даже прийти из другой упаковки.Таким образом, ваш план показывает, насколько хорошо ваше приложение будет тестируемым.

Редактировать Подпись значения, ожидаемого действием, изменится в будущем, по крайней мере, в соответствии с документацией .Я уже нахожу сомнительным использование interface{}, чтобы иметь возможность передавать nil в Action, а затем проверять и вводить assert для ActionFunc, где неактивный ActionFunc фактически будет служить той же цели, но удаляя возвращаемое значение ошибки действительно заставляет меня почесать голову.Я настоятельно рекомендую взглянуть на алефомы / воронки для приложений меньшего и среднего размера или spf13 / cobra , что подходит даже для самых сложных применений cli.

...