Initial buildup/teardown functionality for issue 19

pull/24/head
Sam Nelson 2013-10-14 15:13:28 -06:00
parent 2b887b0d67
commit a4c24896e3
4 changed files with 162 additions and 0 deletions

6
suite/doc.go Normal file
View File

@ -0,0 +1,6 @@
// A full testing suite, to expand upon the features of Go's built-in
// testing tool. Most importantly, this package provides interfaces
// and structs for creating suites of related tests, and putting
// related functionality into methods that will be run before and/or
// after the whole suite or each individual test.
package suite

34
suite/interfaces.go Normal file
View File

@ -0,0 +1,34 @@
package suite
import "testing"
// TestingSuite can store and return the current *testing.T context
// generated by 'go test'.
type TestingSuite interface {
T() *testing.T
SetT(*testing.T)
}
// BeforeAllSuite has a BeforeSuite method, intended to be run before
// the entire suite is tested.
type BeforeAllSuite interface {
BeforeSuite()
}
// BeforeTestSuite has a BeforeTest method, intended to be run before
// each test.
type BeforeTestSuite interface {
BeforeTest()
}
// AfterAllSuite has an AfterSuite method, intended to be run after the
// entire suite has been tested.
type AfterAllSuite interface {
AfterSuite()
}
// AfterTestSuite has an AfterTest method, intended to be run after
// each test.
type AfterTestSuite interface {
AfterTest()
}

51
suite/suite.go Normal file
View File

@ -0,0 +1,51 @@
package suite
import (
"testing"
"reflect"
"regexp"
)
// Suite is a basic testing suite with methods for storing and
// retrieving the current *testing.T context.
type Suite struct {
t *testing.T
}
// T retrieves the current *testing.T context.
func (suite *Suite) T() *testing.T {
return suite.t
}
// SetT sets the current *testing.T context.
func (suite *Suite) SetT(t *testing.T) {
suite.t = t
}
// Run takes a testing suite and runs all of the tests attached
// to it.
func Run(t *testing.T, suite TestingSuite) {
suite.SetT(t)
if beforeAllSuite, ok := suite.(BeforeAllSuite); ok {
beforeAllSuite.BeforeSuite()
}
if afterAllSuite, ok := suite.(AfterAllSuite); ok {
defer afterAllSuite.AfterSuite()
}
methodFinder := reflect.TypeOf(suite)
for index := 0; index < methodFinder.NumMethod(); index++ {
method := methodFinder.Method(index)
if ok, _ := regexp.MatchString("^Test", method.Name); ok {
if beforeTestSuite, ok := suite.(BeforeTestSuite); ok {
beforeTestSuite.BeforeTest()
}
method.Func.Call([]reflect.Value{reflect.ValueOf(suite)})
if afterTestSuite, ok := suite.(AfterTestSuite); ok {
afterTestSuite.AfterTest()
}
}
}
}

71
suite/suite_test.go Normal file
View File

@ -0,0 +1,71 @@
package suite
import (
"testing"
"github.com/stretchr/testify/assert"
)
// This suite is intended to store values to make sure that only
// testing-suite-related methods are run.
type SuiteTester struct {
Suite
BeforeSuiteRunCount int
AfterSuiteRunCount int
BeforeTestRunCount int
AfterTestRunCount int
TestOneRunCount int
TestTwoRunCount int
NonTestMethodRunCount int
}
func (suite *SuiteTester) BeforeSuite() {
suite.BeforeSuiteRunCount++
}
func (suite *SuiteTester) AfterSuite() {
suite.AfterSuiteRunCount++
}
func (suite *SuiteTester) BeforeTest() {
suite.BeforeTestRunCount++
}
func (suite *SuiteTester) AfterTest() {
suite.AfterTestRunCount++
}
func (suite *SuiteTester) TestOne() {
suite.TestOneRunCount++
}
func (suite *SuiteTester) TestTwo() {
suite.TestTwoRunCount++
}
func (suite *SuiteTester) NonTestMethod() {
suite.NonTestMethodRunCount++
}
func TestSuiteLogic(t *testing.T) {
suiteTester := new(SuiteTester)
Run(t, suiteTester)
// The suite was only run once, so the BeforeSuite and AfterSuite
// methods should have each been run only once.
assert.Equal(t, suiteTester.BeforeSuiteRunCount, 1)
assert.Equal(t, suiteTester.AfterSuiteRunCount, 1)
// There are two test methods (TestOne and TestTwo), so the
// BeforeTest and AfterTest methods (which should be run once for
// each test) should have been run twice.
assert.Equal(t, suiteTester.BeforeTestRunCount, 2)
assert.Equal(t, suiteTester.AfterTestRunCount, 2)
// Each test should have been run once.
assert.Equal(t, suiteTester.TestOneRunCount, 1)
assert.Equal(t, suiteTester.TestTwoRunCount, 1)
// Methods that don't match the test method identifier shouldn't
// have been run at all.
assert.Equal(t, suiteTester.NonTestMethodRunCount, 0)
}