Cobra: Document a best practice for testing a cobra app

Created on 18 Oct 2018  路  12Comments  路  Source: spf13/cobra

Hey there, I'm quite new to go and cobra, but I'm leveraging the framework to build some tools for work and loving it.

I've been trying to set up testing for my project, but I'm wondering how other people using cobra are implementing testing for sub-commands. The typical go example led me to believe that in the cmds folder, i would make a command x.go and then create a test x_test.go. Because of the way that all of the commands are passed to the root command, I don't believe this is possible.

To other users, how would you suggest doing testing on your sub-commands? If this isn't just a noob misunderstanding, maybe it would be good to add a best practice for testing into the main readme?

kinstale

Most helpful comment

If you are coming here from a Google or DuckDuckGo search, in our project we wrapped the var and init sections of the commands in functions so that they can be called by unit tests and re-initialize all variables.

Hi! @lpabon your links are broken. Could you reupload? :pray:

All 12 comments

Could anyone share how they write tests for sub-commands? I am also stuck i find it really hard to write any kind of test for a more complex sub-command. Thanks

If you are coming here from a Google or DuckDuckGo search, in our project we wrapped the var and init sections of the commands in functions so that they can be called by unit tests and re-initialize all variables.

Hi! I think you can get inspiration from who are using Cobra like helm or kubectl

If you are coming here from a Google or DuckDuckGo search, in our project we wrapped the var and init sections of the commands in functions so that they can be called by unit tests and re-initialize all variables.

Hi! @lpabon your links are broken. Could you reupload? :pray:

@lpabon Maybe the repo px is private?

it would be nice to have guidance or even some kind of default skeleton which includes a test director and hooks that up in an opinionated way. instead of having to search around for how everyone else is doing it their specific quirky way

This issue is being marked as stale due to a long period of inactivity

Thanks for the reference test implementation, it was helpful. However, i'm struggling with resetting flags to default values. I've ended up with this monstrosity:

func resetFlags(cmd *cobra.Command) {
    cmd.Flags().VisitAll(func(flag *pflag.Flag) {
        if flag.Value.Type() == "stringSlice" {
            // XXX: unfortunately, flag.Value.Set() appends to original
            // slice, not resets it, so we retrieve pointer to the slice here
            // and set it to new empty slice manually
            value := reflect.ValueOf(flag.Value).Elem().FieldByName("value")
            ptr := (*[]string)(unsafe.Pointer(value.Pointer()))
            *ptr = make([]string, 0)
        }

        flag.Value.Set(flag.DefValue)
    })
    for _, cmd := range cmd.Commands() {
        resetFlags(cmd)
    }
}

Is there a better way to reset flags?

@myaut Cobra does have a ResetFlags() method. Does that help you at all?

I went with the strategy described at https://stackoverflow.com/questions/59709345/how-to-implement-unit-tests-for-cli-commands-in-go/59714127#59714127

It's been 2 years but still +1 for the issue.

Any best-practice-article or samples for testing cobra will help me a lot.

As a Golang beginner, even a simple "Hello, world!" command which has a "hello" sub-command with best practices and tests that cover 100% of coverage would help. I never get covered the last few percentages ...

I know that keeping 100% coverage is a fantasy. But at least we can start at 100%, don't we?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

anuraaga picture anuraaga  路  5Comments

supershal picture supershal  路  4Comments

garthk picture garthk  路  3Comments

andygrunwald picture andygrunwald  路  6Comments

alapidas picture alapidas  路  3Comments