blob: f41fffc3f5b56ea845c2694c98744743e0673cc4 [file] [log] [blame]
// These tests verify the test running logic.
package check_test
import (
"errors"
. "gopkg.in/check.v1"
"os"
"sync"
)
var runnerS = Suite(&RunS{})
type RunS struct{}
func (s *RunS) TestCountSuite(c *C) {
suitesRun += 1
}
// -----------------------------------------------------------------------
// Tests ensuring result counting works properly.
func (s *RunS) TestSuccess(c *C) {
output := String{}
result := Run(&SuccessHelper{}, &RunConf{Output: &output})
c.Check(result.Succeeded, Equals, 1)
c.Check(result.Failed, Equals, 0)
c.Check(result.Skipped, Equals, 0)
c.Check(result.Panicked, Equals, 0)
c.Check(result.FixturePanicked, Equals, 0)
c.Check(result.Missed, Equals, 0)
c.Check(result.RunError, IsNil)
}
func (s *RunS) TestFailure(c *C) {
output := String{}
result := Run(&FailHelper{}, &RunConf{Output: &output})
c.Check(result.Succeeded, Equals, 0)
c.Check(result.Failed, Equals, 1)
c.Check(result.Skipped, Equals, 0)
c.Check(result.Panicked, Equals, 0)
c.Check(result.FixturePanicked, Equals, 0)
c.Check(result.Missed, Equals, 0)
c.Check(result.RunError, IsNil)
}
func (s *RunS) TestFixture(c *C) {
output := String{}
result := Run(&FixtureHelper{}, &RunConf{Output: &output})
c.Check(result.Succeeded, Equals, 2)
c.Check(result.Failed, Equals, 0)
c.Check(result.Skipped, Equals, 0)
c.Check(result.Panicked, Equals, 0)
c.Check(result.FixturePanicked, Equals, 0)
c.Check(result.Missed, Equals, 0)
c.Check(result.RunError, IsNil)
}
func (s *RunS) TestPanicOnTest(c *C) {
output := String{}
helper := &FixtureHelper{panicOn: "Test1"}
result := Run(helper, &RunConf{Output: &output})
c.Check(result.Succeeded, Equals, 1)
c.Check(result.Failed, Equals, 0)
c.Check(result.Skipped, Equals, 0)
c.Check(result.Panicked, Equals, 1)
c.Check(result.FixturePanicked, Equals, 0)
c.Check(result.Missed, Equals, 0)
c.Check(result.RunError, IsNil)
}
func (s *RunS) TestPanicOnSetUpTest(c *C) {
output := String{}
helper := &FixtureHelper{panicOn: "SetUpTest"}
result := Run(helper, &RunConf{Output: &output})
c.Check(result.Succeeded, Equals, 0)
c.Check(result.Failed, Equals, 0)
c.Check(result.Skipped, Equals, 0)
c.Check(result.Panicked, Equals, 0)
c.Check(result.FixturePanicked, Equals, 1)
c.Check(result.Missed, Equals, 2)
c.Check(result.RunError, IsNil)
}
func (s *RunS) TestPanicOnSetUpSuite(c *C) {
output := String{}
helper := &FixtureHelper{panicOn: "SetUpSuite"}
result := Run(helper, &RunConf{Output: &output})
c.Check(result.Succeeded, Equals, 0)
c.Check(result.Failed, Equals, 0)
c.Check(result.Skipped, Equals, 0)
c.Check(result.Panicked, Equals, 0)
c.Check(result.FixturePanicked, Equals, 1)
c.Check(result.Missed, Equals, 2)
c.Check(result.RunError, IsNil)
}
// -----------------------------------------------------------------------
// Check result aggregation.
func (s *RunS) TestAdd(c *C) {
result := &Result{
Succeeded: 1,
Skipped: 2,
Failed: 3,
Panicked: 4,
FixturePanicked: 5,
Missed: 6,
ExpectedFailures: 7,
}
result.Add(&Result{
Succeeded: 10,
Skipped: 20,
Failed: 30,
Panicked: 40,
FixturePanicked: 50,
Missed: 60,
ExpectedFailures: 70,
})
c.Check(result.Succeeded, Equals, 11)
c.Check(result.Skipped, Equals, 22)
c.Check(result.Failed, Equals, 33)
c.Check(result.Panicked, Equals, 44)
c.Check(result.FixturePanicked, Equals, 55)
c.Check(result.Missed, Equals, 66)
c.Check(result.ExpectedFailures, Equals, 77)
c.Check(result.RunError, IsNil)
}
// -----------------------------------------------------------------------
// Check the Passed() method.
func (s *RunS) TestPassed(c *C) {
c.Assert((&Result{}).Passed(), Equals, true)
c.Assert((&Result{Succeeded: 1}).Passed(), Equals, true)
c.Assert((&Result{Skipped: 1}).Passed(), Equals, true)
c.Assert((&Result{Failed: 1}).Passed(), Equals, false)
c.Assert((&Result{Panicked: 1}).Passed(), Equals, false)
c.Assert((&Result{FixturePanicked: 1}).Passed(), Equals, false)
c.Assert((&Result{Missed: 1}).Passed(), Equals, false)
c.Assert((&Result{RunError: errors.New("!")}).Passed(), Equals, false)
}
// -----------------------------------------------------------------------
// Check that result printing is working correctly.
func (s *RunS) TestPrintSuccess(c *C) {
result := &Result{Succeeded: 5}
c.Check(result.String(), Equals, "OK: 5 passed")
}
func (s *RunS) TestPrintFailure(c *C) {
result := &Result{Failed: 5}
c.Check(result.String(), Equals, "OOPS: 0 passed, 5 FAILED")
}
func (s *RunS) TestPrintSkipped(c *C) {
result := &Result{Skipped: 5}
c.Check(result.String(), Equals, "OK: 0 passed, 5 skipped")
}
func (s *RunS) TestPrintExpectedFailures(c *C) {
result := &Result{ExpectedFailures: 5}
c.Check(result.String(), Equals, "OK: 0 passed, 5 expected failures")
}
func (s *RunS) TestPrintPanicked(c *C) {
result := &Result{Panicked: 5}
c.Check(result.String(), Equals, "OOPS: 0 passed, 5 PANICKED")
}
func (s *RunS) TestPrintFixturePanicked(c *C) {
result := &Result{FixturePanicked: 5}
c.Check(result.String(), Equals, "OOPS: 0 passed, 5 FIXTURE-PANICKED")
}
func (s *RunS) TestPrintMissed(c *C) {
result := &Result{Missed: 5}
c.Check(result.String(), Equals, "OOPS: 0 passed, 5 MISSED")
}
func (s *RunS) TestPrintAll(c *C) {
result := &Result{Succeeded: 1, Skipped: 2, ExpectedFailures: 3,
Panicked: 4, FixturePanicked: 5, Missed: 6}
c.Check(result.String(), Equals,
"OOPS: 1 passed, 2 skipped, 3 expected failures, 4 PANICKED, "+
"5 FIXTURE-PANICKED, 6 MISSED")
}
func (s *RunS) TestPrintRunError(c *C) {
result := &Result{Succeeded: 1, Failed: 1,
RunError: errors.New("Kaboom!")}
c.Check(result.String(), Equals, "ERROR: Kaboom!")
}
// -----------------------------------------------------------------------
// Verify that the method pattern flag works correctly.
func (s *RunS) TestFilterTestName(c *C) {
helper := FixtureHelper{}
output := String{}
runConf := RunConf{Output: &output, Filter: "Test[91]"}
Run(&helper, &runConf)
c.Check(helper.calls[0], Equals, "SetUpSuite")
c.Check(helper.calls[1], Equals, "SetUpTest")
c.Check(helper.calls[2], Equals, "Test1")
c.Check(helper.calls[3], Equals, "TearDownTest")
c.Check(helper.calls[4], Equals, "TearDownSuite")
c.Check(len(helper.calls), Equals, 5)
}
func (s *RunS) TestFilterTestNameWithAll(c *C) {
helper := FixtureHelper{}
output := String{}
runConf := RunConf{Output: &output, Filter: ".*"}
Run(&helper, &runConf)
c.Check(helper.calls[0], Equals, "SetUpSuite")
c.Check(helper.calls[1], Equals, "SetUpTest")
c.Check(helper.calls[2], Equals, "Test1")
c.Check(helper.calls[3], Equals, "TearDownTest")
c.Check(helper.calls[4], Equals, "SetUpTest")
c.Check(helper.calls[5], Equals, "Test2")
c.Check(helper.calls[6], Equals, "TearDownTest")
c.Check(helper.calls[7], Equals, "TearDownSuite")
c.Check(len(helper.calls), Equals, 8)
}
func (s *RunS) TestFilterSuiteName(c *C) {
helper := FixtureHelper{}
output := String{}
runConf := RunConf{Output: &output, Filter: "FixtureHelper"}
Run(&helper, &runConf)
c.Check(helper.calls[0], Equals, "SetUpSuite")
c.Check(helper.calls[1], Equals, "SetUpTest")
c.Check(helper.calls[2], Equals, "Test1")
c.Check(helper.calls[3], Equals, "TearDownTest")
c.Check(helper.calls[4], Equals, "SetUpTest")
c.Check(helper.calls[5], Equals, "Test2")
c.Check(helper.calls[6], Equals, "TearDownTest")
c.Check(helper.calls[7], Equals, "TearDownSuite")
c.Check(len(helper.calls), Equals, 8)
}
func (s *RunS) TestFilterSuiteNameAndTestName(c *C) {
helper := FixtureHelper{}
output := String{}
runConf := RunConf{Output: &output, Filter: "FixtureHelper\\.Test2"}
Run(&helper, &runConf)
c.Check(helper.calls[0], Equals, "SetUpSuite")
c.Check(helper.calls[1], Equals, "SetUpTest")
c.Check(helper.calls[2], Equals, "Test2")
c.Check(helper.calls[3], Equals, "TearDownTest")
c.Check(helper.calls[4], Equals, "TearDownSuite")
c.Check(len(helper.calls), Equals, 5)
}
func (s *RunS) TestFilterAllOut(c *C) {
helper := FixtureHelper{}
output := String{}
runConf := RunConf{Output: &output, Filter: "NotFound"}
Run(&helper, &runConf)
c.Check(len(helper.calls), Equals, 0)
}
func (s *RunS) TestRequirePartialMatch(c *C) {
helper := FixtureHelper{}
output := String{}
runConf := RunConf{Output: &output, Filter: "est"}
Run(&helper, &runConf)
c.Check(len(helper.calls), Equals, 8)
}
func (s *RunS) TestFilterError(c *C) {
helper := FixtureHelper{}
output := String{}
runConf := RunConf{Output: &output, Filter: "]["}
result := Run(&helper, &runConf)
c.Check(result.String(), Equals,
"ERROR: Bad filter expression: error parsing regexp: missing closing ]: `[`")
c.Check(len(helper.calls), Equals, 0)
}
// -----------------------------------------------------------------------
// Verify that List works correctly.
func (s *RunS) TestListFiltered(c *C) {
names := List(&FixtureHelper{}, &RunConf{Filter: "1"})
c.Assert(names, DeepEquals, []string{
"FixtureHelper.Test1",
})
}
func (s *RunS) TestList(c *C) {
names := List(&FixtureHelper{}, &RunConf{})
c.Assert(names, DeepEquals, []string{
"FixtureHelper.Test1",
"FixtureHelper.Test2",
})
}
// -----------------------------------------------------------------------
// Verify that verbose mode prints tests which pass as well.
func (s *RunS) TestVerboseMode(c *C) {
helper := FixtureHelper{}
output := String{}
runConf := RunConf{Output: &output, Verbose: true}
Run(&helper, &runConf)
expected := "PASS: check_test\\.go:[0-9]+: FixtureHelper\\.Test1\t *[.0-9]+s\n" +
"PASS: check_test\\.go:[0-9]+: FixtureHelper\\.Test2\t *[.0-9]+s\n"
c.Assert(output.value, Matches, expected)
}
func (s *RunS) TestVerboseModeWithFailBeforePass(c *C) {
helper := FixtureHelper{panicOn: "Test1"}
output := String{}
runConf := RunConf{Output: &output, Verbose: true}
Run(&helper, &runConf)
expected := "(?s).*PANIC.*\n-+\n" + // Should have an extra line.
"PASS: check_test\\.go:[0-9]+: FixtureHelper\\.Test2\t *[.0-9]+s\n"
c.Assert(output.value, Matches, expected)
}
// -----------------------------------------------------------------------
// Verify the stream output mode. In this mode there's no output caching.
type StreamHelper struct {
l2 sync.Mutex
l3 sync.Mutex
}
func (s *StreamHelper) SetUpSuite(c *C) {
c.Log("0")
}
func (s *StreamHelper) Test1(c *C) {
c.Log("1")
s.l2.Lock()
s.l3.Lock()
go func() {
s.l2.Lock() // Wait for "2".
c.Log("3")
s.l3.Unlock()
}()
}
func (s *StreamHelper) Test2(c *C) {
c.Log("2")
s.l2.Unlock()
s.l3.Lock() // Wait for "3".
c.Fail()
c.Log("4")
}
func (s *RunS) TestStreamMode(c *C) {
helper := &StreamHelper{}
output := String{}
runConf := RunConf{Output: &output, Stream: true}
Run(helper, &runConf)
expected := "START: run_test\\.go:[0-9]+: StreamHelper\\.SetUpSuite\n0\n" +
"PASS: run_test\\.go:[0-9]+: StreamHelper\\.SetUpSuite\t *[.0-9]+s\n\n" +
"START: run_test\\.go:[0-9]+: StreamHelper\\.Test1\n1\n" +
"PASS: run_test\\.go:[0-9]+: StreamHelper\\.Test1\t *[.0-9]+s\n\n" +
"START: run_test\\.go:[0-9]+: StreamHelper\\.Test2\n2\n3\n4\n" +
"FAIL: run_test\\.go:[0-9]+: StreamHelper\\.Test2\n\n"
c.Assert(output.value, Matches, expected)
}
type StreamMissHelper struct{}
func (s *StreamMissHelper) SetUpSuite(c *C) {
c.Log("0")
c.Fail()
}
func (s *StreamMissHelper) Test1(c *C) {
c.Log("1")
}
func (s *RunS) TestStreamModeWithMiss(c *C) {
helper := &StreamMissHelper{}
output := String{}
runConf := RunConf{Output: &output, Stream: true}
Run(helper, &runConf)
expected := "START: run_test\\.go:[0-9]+: StreamMissHelper\\.SetUpSuite\n0\n" +
"FAIL: run_test\\.go:[0-9]+: StreamMissHelper\\.SetUpSuite\n\n" +
"START: run_test\\.go:[0-9]+: StreamMissHelper\\.Test1\n" +
"MISS: run_test\\.go:[0-9]+: StreamMissHelper\\.Test1\n\n"
c.Assert(output.value, Matches, expected)
}
// -----------------------------------------------------------------------
// Verify that that the keep work dir request indeed does so.
type WorkDirSuite struct {}
func (s *WorkDirSuite) Test(c *C) {
c.MkDir()
}
func (s *RunS) TestKeepWorkDir(c *C) {
output := String{}
runConf := RunConf{Output: &output, Verbose: true, KeepWorkDir: true}
result := Run(&WorkDirSuite{}, &runConf)
c.Assert(result.String(), Matches, ".*\nWORK=" + result.WorkDir)
stat, err := os.Stat(result.WorkDir)
c.Assert(err, IsNil)
c.Assert(stat.IsDir(), Equals, true)
}