Skip to content

Commit

Permalink
Merge pull request #57 from dnephin/coverage-in-short-format
Browse files Browse the repository at this point in the history
Identify and, filter or display coverage output
  • Loading branch information
dnephin committed Jun 26, 2019
2 parents 6b99016 + 4445661 commit 1796188
Show file tree
Hide file tree
Showing 11 changed files with 375 additions and 10 deletions.
31 changes: 25 additions & 6 deletions testjson/execution.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ type Package struct {
Skipped []TestCase
Passed []TestCase
output map[string][]string
// coverage stores the code coverage output for the package without the
// trailing newline (ex: coverage: 91.1% of statements).
coverage string
// action identifies if the package passed or failed. A package may fail
// with no test failures if an init() or TestMain exits non-zero.
// skip indicates there were no tests.
Expand Down Expand Up @@ -131,15 +134,25 @@ func (e *Execution) add(event TestEvent) {
e.packages[event.Package] = pkg
}
if event.PackageEvent() {
switch event.Action {
case ActionPass, ActionFail:
pkg.action = event.Action
case ActionOutput:
pkg.output[""] = append(pkg.output[""], event.Output)
}
e.addPackageEvent(pkg, event)
return
}
e.addTestEvent(pkg, event)
}

func (e *Execution) addPackageEvent(pkg *Package, event TestEvent) {
switch event.Action {
case ActionPass, ActionFail:
pkg.action = event.Action
case ActionOutput:
if isCoverageOutput(event.Output) {
pkg.coverage = strings.TrimRight(event.Output, "\n")
}
pkg.output[""] = append(pkg.output[""], event.Output)
}
}

func (e *Execution) addTestEvent(pkg *Package, event TestEvent) {
switch event.Action {
case ActionRun:
pkg.Total++
Expand Down Expand Up @@ -173,6 +186,12 @@ func elapsedDuration(elapsed float64) time.Duration {
return time.Duration(elapsed*1000) * time.Millisecond
}

func isCoverageOutput(output string) bool {
return all(
strings.HasPrefix(output, "coverage:"),
strings.HasSuffix(output, "% of statements\n"))
}

// Output returns the full test output for a test.
func (e *Execution) Output(pkg, test string) string {
return strings.Join(e.packages[pkg].output[test], "")
Expand Down
21 changes: 21 additions & 0 deletions testjson/execution_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"testing"
"time"

"github.com/google/go-cmp/cmp"
"gotest.tools/assert"
)

Expand All @@ -22,3 +23,23 @@ func TestPackage_Elapsed(t *testing.T) {
}
assert.Equal(t, pkg.Elapsed(), 3100*time.Millisecond)
}

func TestExecution_Add_PackageCoverage(t *testing.T) {
exec := NewExecution()
exec.add(TestEvent{
Package: "mytestpkg",
Action: ActionOutput,
Output: "coverage: 33.1% of statements\n",
})

pkg := exec.Package("mytestpkg")
expected := &Package{
coverage: "coverage: 33.1% of statements",
output: map[string][]string{
"": {"coverage: 33.1% of statements\n"},
},
}
assert.DeepEqual(t, pkg, expected, cmpPackage)
}

var cmpPackage = cmp.AllowUnexported(Package{})
22 changes: 18 additions & 4 deletions testjson/format.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,10 @@ func standardVerboseFormat(event TestEvent, _ *Execution) (string, error) {

// go test
func standardQuietFormat(event TestEvent, _ *Execution) (string, error) {
if event.PackageEvent() && event.Output != "PASS\n" {
if !event.PackageEvent() {
return "", nil
}
if event.Output != "PASS\n" && !isCoverageOutput(event.Output) {
return event.Output, nil
}
return "", nil
Expand Down Expand Up @@ -96,7 +99,7 @@ func all(cond ...bool) bool {
return true
}

func shortFormat(event TestEvent, _ *Execution) (string, error) {
func shortFormat(event TestEvent, exec *Execution) (string, error) {
if !event.PackageEvent() {
return "", nil
}
Expand All @@ -107,9 +110,20 @@ func shortFormat(event TestEvent, _ *Execution) (string, error) {
}
return fmt.Sprintf(" (%s)", d)
}
fmtCoverage := func() string {
pkg := exec.Package(event.Package)
if pkg.coverage == "" {
return ""
}
return " (" + pkg.coverage + ")"
}
fmtEvent := func(action string) (string, error) {
return fmt.Sprintf("%s %s%s\n",
action, relativePackagePath(event.Package), fmtElapsed()), nil
return fmt.Sprintf("%s %s%s%s\n",
action,
relativePackagePath(event.Package),
fmtElapsed(),
fmtCoverage(),
), nil
}
withColor := colorEvent(event)
switch event.Action {
Expand Down
58 changes: 58 additions & 0 deletions testjson/format_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,18 @@ func TestScanTestOutputWithShortFormat(t *testing.T) {
assert.DeepEqual(t, exec, expectedExecution, cmpExecutionShallow)
}

func TestScanTestOutputWithShortFormat_WithCoverage(t *testing.T) {
defer patchPkgPathPrefix("gotest.tools")()

shim := newFakeHandler(shortFormat, "go-test-json-with-cover")
exec, err := ScanTestOutput(shim.Config(t))

assert.NilError(t, err)
golden.Assert(t, shim.out.String(), "short-format-coverage.out")
golden.Assert(t, shim.err.String(), "short-format-coverage.err")
assert.DeepEqual(t, exec, expectedCoverageExecution, cmpExecutionShallow)
}

func TestScanTestOutputWithStandardVerboseFormat(t *testing.T) {
defer patchPkgPathPrefix("github.com/gotestyourself/gotestyourself")()

Expand All @@ -166,3 +178,49 @@ func TestScanTestOutputWithStandardQuietFormat(t *testing.T) {
golden.Assert(t, shim.err.String(), "standard-quiet-format.err")
assert.DeepEqual(t, exec, expectedExecution, cmpExecutionShallow)
}

func TestScanTestOutputWithStandardQuietFormat_WithCoverage(t *testing.T) {
defer patchPkgPathPrefix("gotest.tools")()

shim := newFakeHandler(standardQuietFormat, "go-test-json-with-cover")
exec, err := ScanTestOutput(shim.Config(t))

assert.NilError(t, err)
golden.Assert(t, shim.out.String(), "standard-quiet-format-coverage.out")
golden.Assert(t, shim.err.String(), "standard-quiet-format-coverage.err")
assert.DeepEqual(t, exec, expectedCoverageExecution, cmpExecutionShallow)
}

var expectedCoverageExecution = &Execution{
started: time.Now(),
errors: []string{"internal/broken/broken.go:5:21: undefined: somepackage"},
packages: map[string]*Package{
"gotest.tools/gotestsum/testjson/internal/good": {
Total: 18,
Skipped: []TestCase{
{Test: "TestSkipped"},
{Test: "TestSkippedWitLog"},
},
action: ActionPass,
coverage: "coverage: 0.0% of statements",
},
"gotest.tools/gotestsum/testjson/internal/stub": {
Total: 28,
Failed: []TestCase{
{Test: "TestFailed"},
{Test: "TestFailedWithStderr"},
{Test: "TestNestedWithFailure/c"},
{Test: "TestNestedWithFailure"},
},
Skipped: []TestCase{
{Test: "TestSkipped"},
{Test: "TestSkippedWitLog"},
},
action: ActionFail,
coverage: "coverage: 0.0% of statements",
},
"gotest.tools/gotestsum/testjson/internal/badmain": {
action: ActionFail,
},
},
}
6 changes: 6 additions & 0 deletions testjson/generate.sh
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,10 @@ go test -p 1 -json -timeout 10ms -tags 'stubpkg timeout' ./internal/... \
go test -p 1 -json -tags 'stubpkg panic' ./internal/... \
> testdata/go-test-json-with-panic.out \
2> testdata/go-test-json-with-panic.err \
| true


go test -p 1 -json -tags stubpkg -cover ./internal/... \
> testdata/go-test-json-with-cover.out \
2> testdata/go-test-json-with-cover.err \
| true
2 changes: 2 additions & 0 deletions testjson/testdata/go-test-json-with-cover.err
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# gotest.tools/gotestsum/testjson/internal/broken
internal/broken/broken.go:5:21: undefined: somepackage
Loading

0 comments on commit 1796188

Please sign in to comment.