frankban / quicktest

Quick helpers for testing Go applications
MIT License
529 stars 27 forks source link

quicktest.Assert panics when called in a testscript command #143

Closed datacharmer closed 2 years ago

datacharmer commented 2 years ago

When quickest.Assert is called on a failing comparison within a custom command in testscript, it panics. By contrast, when using testscript.Fatalf, the test exits regularly.

How to reproduce:

// go.mod
module testscript-explore

go 1.18

require (
    github.com/frankban/quicktest v1.14.3
    github.com/rogpeppe/go-internal v1.8.2-0.20220706194532-9d15b660d1d6
)
// qt-integration_test.go
package main

import (
    "testing"

    qt "github.com/frankban/quicktest"
    "github.com/rogpeppe/go-internal/testscript"
)

func TestQtIntegration(t *testing.T) {
    testscript.Run(t, testscript.Params{
        Dir: "testdata",
        Cmds: map[string]func(ts *testscript.TestScript, neg bool, args []string){
            "wants_two_args": func(ts *testscript.TestScript, neg bool, args []string) {
                c := qt.New(t)
                c.Assert(len(args), qt.Equals, 2)
                c.Assert(args[0], qt.Equals, args[1])
                if len(args) < 2 {
                    ts.Fatalf("needs two arguments")
                }
                if args[0] != args[1] {
                    ts.Fatalf("want: %s - got %s", args[0], args[1])
                }
            },
        },
    })
}
# testdata/qt-integration.txt
env other=one

# this one passes
wants_two_args one $other

# this one fails
wants_two_args

sample run

$ go test
--- FAIL: TestQtIntegration (0.00s)
    qt-bug_test.go:16:
        error:
          values are not equal
        got:
          int(0)
        want:
          int(2)
        stack:
          $workdir/testscript-explore/qt-bug/qt-bug_test.go:16
            c.Assert(len(args), qt.Equals, 2)
        $HOME/go/pkg/mod/github.com/rogpeppe/go-internal@v1.8.2-0.20220706194532-9d15b660d1d6/testscript/testscript.go:527
            cmd(ts, neg, args[1:])
          $HOME/go/pkg/mod/github.com/rogpeppe/go-internal@v1.8.2-0.20220706194532-9d15b660d1d6/testscript/testscript.go:271
            ts.run()
         $HOME/go/pkg/mod/github.com/rogpeppe/go-internal@v1.8.2-0.20220706194532-9d15b660d1d6/testscript/testscript.go:198
            f(tshim{t})

    --- FAIL: TestQtIntegration/qt-integration (0.00s)
        testscript.go:428:
            # this one passes (0.000s)
            # this one fails (0.001s)
            > wants_two_args

        testing.go:1336: test executed panic(nil) or runtime.Goexit: subtest may have called FailNow on a parent test
FAIL
exit status 1
FAIL    testscript-explore/qt-bug   0.422s

After commenting out the quickest lines (15 to 17), the failure doesn't include a panic.

go test
--- FAIL: TestQtIntegration (0.00s)
    --- FAIL: TestQtIntegration/qt-integration (0.00s)
        testscript.go:428:
            # this one passes (0.000s)
            # this one fails (0.000s)
            > wants_two_args
            FAIL: testdata/qt-integration.txt:7: needs two arguments

FAIL
exit status 1
FAIL    testscript-explore/qt-bug   0.567s

I don't know if this is a bug or an incorrect usage from my side. I'd like it to know how to address it, as I plan to use quickest in a larger project where this kind of integration is quite common (See this blog post for more detail.)

datacharmer commented 2 years ago

Further observations:

datacharmer commented 2 years ago

On further examination, I saw that even the plain t.Fatalf produces the same panic. Thus, I am going to close this issue and open it in testscript.