// 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) }