testing: implement testing.Cleanup
Also reorder and regroup common's fields slightly to match upstream. TODO: pull in more upstream tests once this package is goroutine-safe
Этот коммит содержится в:
родитель
0b939f93bc
коммит
ef77b645b9
2 изменённых файлов: 117 добавлений и 9 удалений
80
src/testing/sub_test.go
Обычный файл
80
src/testing/sub_test.go
Обычный файл
|
@ -0,0 +1,80 @@
|
||||||
|
// Copyright 2016 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package testing
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestCleanup(t *T) {
|
||||||
|
var cleanups []int
|
||||||
|
t.Run("test", func(t *T) {
|
||||||
|
t.Cleanup(func() { cleanups = append(cleanups, 1) })
|
||||||
|
t.Cleanup(func() { cleanups = append(cleanups, 2) })
|
||||||
|
})
|
||||||
|
if got, want := cleanups, []int{2, 1}; !reflect.DeepEqual(got, want) {
|
||||||
|
t.Errorf("unexpected cleanup record; got %v want %v", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRunCleanup(t *T) {
|
||||||
|
outerCleanup := 0
|
||||||
|
innerCleanup := 0
|
||||||
|
t.Run("test", func(t *T) {
|
||||||
|
t.Cleanup(func() { outerCleanup++ })
|
||||||
|
t.Run("x", func(t *T) {
|
||||||
|
t.Cleanup(func() { innerCleanup++ })
|
||||||
|
})
|
||||||
|
})
|
||||||
|
if innerCleanup != 1 {
|
||||||
|
t.Errorf("unexpected inner cleanup count; got %d want 1", innerCleanup)
|
||||||
|
}
|
||||||
|
if outerCleanup != 1 {
|
||||||
|
t.Errorf("unexpected outer cleanup count; got %d want 0", outerCleanup)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCleanupParallelSubtests(t *T) {
|
||||||
|
ranCleanup := 0
|
||||||
|
t.Run("test", func(t *T) {
|
||||||
|
t.Cleanup(func() { ranCleanup++ })
|
||||||
|
t.Run("x", func(t *T) {
|
||||||
|
t.Parallel()
|
||||||
|
if ranCleanup > 0 {
|
||||||
|
t.Error("outer cleanup ran before parallel subtest")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
if ranCleanup != 1 {
|
||||||
|
t.Errorf("unexpected cleanup count; got %d want 1", ranCleanup)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNestedCleanup(t *T) {
|
||||||
|
ranCleanup := 0
|
||||||
|
t.Run("test", func(t *T) {
|
||||||
|
t.Cleanup(func() {
|
||||||
|
if ranCleanup != 2 {
|
||||||
|
t.Errorf("unexpected cleanup count in first cleanup: got %d want 2", ranCleanup)
|
||||||
|
}
|
||||||
|
ranCleanup++
|
||||||
|
})
|
||||||
|
t.Cleanup(func() {
|
||||||
|
if ranCleanup != 0 {
|
||||||
|
t.Errorf("unexpected cleanup count in second cleanup: got %d want 0", ranCleanup)
|
||||||
|
}
|
||||||
|
ranCleanup++
|
||||||
|
t.Cleanup(func() {
|
||||||
|
if ranCleanup != 1 {
|
||||||
|
t.Errorf("unexpected cleanup count in nested cleanup: got %d want 1", ranCleanup)
|
||||||
|
}
|
||||||
|
ranCleanup++
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
if ranCleanup != 3 {
|
||||||
|
t.Errorf("unexpected cleanup count: got %d want 3", ranCleanup)
|
||||||
|
}
|
||||||
|
}
|
|
@ -46,13 +46,14 @@ type common struct {
|
||||||
output bytes.Buffer
|
output bytes.Buffer
|
||||||
w io.Writer // either &output, or at top level, os.Stdout
|
w io.Writer // either &output, or at top level, os.Stdout
|
||||||
indent string
|
indent string
|
||||||
|
|
||||||
failed bool // Test or benchmark has failed.
|
failed bool // Test or benchmark has failed.
|
||||||
skipped bool // Test of benchmark has been skipped.
|
skipped bool // Test of benchmark has been skipped.
|
||||||
|
cleanups []func() // optional functions to be called at the end of the test
|
||||||
finished bool // Test function has completed.
|
finished bool // Test function has completed.
|
||||||
|
|
||||||
|
parent *common
|
||||||
level int // Nesting depth of test or benchmark.
|
level int // Nesting depth of test or benchmark.
|
||||||
name string // Name of test or benchmark.
|
name string // Name of test or benchmark.
|
||||||
parent *common
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TB is the interface common to T and B.
|
// TB is the interface common to T and B.
|
||||||
|
@ -208,7 +209,34 @@ func (c *common) Parallel() {
|
||||||
// Unimplemented.
|
// Unimplemented.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Cleanup registers a function to be called when the test (or subtest) and all its
|
||||||
|
// subtests complete. Cleanup functions will be called in last added,
|
||||||
|
// first called order.
|
||||||
|
func (c *common) Cleanup(f func()) {
|
||||||
|
c.cleanups = append(c.cleanups, f)
|
||||||
|
}
|
||||||
|
|
||||||
|
// runCleanup is called at the end of the test.
|
||||||
|
func (c *common) runCleanup() {
|
||||||
|
for {
|
||||||
|
var cleanup func()
|
||||||
|
if len(c.cleanups) > 0 {
|
||||||
|
last := len(c.cleanups) - 1
|
||||||
|
cleanup = c.cleanups[last]
|
||||||
|
c.cleanups = c.cleanups[:last]
|
||||||
|
}
|
||||||
|
if cleanup == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
cleanup()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func tRunner(t *T, fn func(t *T)) {
|
func tRunner(t *T, fn func(t *T)) {
|
||||||
|
defer func() {
|
||||||
|
t.runCleanup()
|
||||||
|
}()
|
||||||
|
|
||||||
// Run the test.
|
// Run the test.
|
||||||
if flagVerbose {
|
if flagVerbose {
|
||||||
fmt.Fprintf(t.w, "=== RUN %s\n", t.name)
|
fmt.Fprintf(t.w, "=== RUN %s\n", t.name)
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче