PageRenderTime 39ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/src/pkg/testing/testing.go

https://bitbucket.org/taruti/go.plan9
Go | 174 lines | 99 code | 18 blank | 57 comment | 18 complexity | a0918f6affc2fb026ae7413ea1635683 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. // Copyright 2009 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. // The testing package provides support for automated testing of Go packages.
  5. // It is intended to be used in concert with the ``gotest'' utility, which automates
  6. // execution of any function of the form
  7. // func TestXxx(*testing.T)
  8. // where Xxx can be any alphanumeric string (but the first letter must not be in
  9. // [a-z]) and serves to identify the test routine.
  10. // These TestXxx routines should be declared within the package they are testing.
  11. //
  12. // Functions of the form
  13. // func BenchmarkXxx(*testing.B)
  14. // are considered benchmarks, and are executed by gotest when the -benchmarks
  15. // flag is provided.
  16. //
  17. // A sample benchmark function looks like this:
  18. // func BenchmarkHello(b *testing.B) {
  19. // for i := 0; i < b.N; i++ {
  20. // fmt.Sprintf("hello")
  21. // }
  22. // }
  23. // The benchmark package will vary b.N until the benchmark function lasts
  24. // long enough to be timed reliably. The output
  25. // testing.BenchmarkHello 500000 4076 ns/op
  26. // means that the loop ran 500000 times at a speed of 4076 ns per loop.
  27. //
  28. // If a benchmark needs some expensive setup before running, the timer
  29. // may be stopped:
  30. // func BenchmarkBigLen(b *testing.B) {
  31. // b.StopTimer()
  32. // big := NewBig()
  33. // b.StartTimer()
  34. // for i := 0; i < b.N; i++ {
  35. // big.Len()
  36. // }
  37. // }
  38. package testing
  39. import (
  40. "flag"
  41. "fmt"
  42. "os"
  43. "runtime"
  44. )
  45. // Report as tests are run; default is silent for success.
  46. var chatty = flag.Bool("v", false, "verbose: print additional output")
  47. var match = flag.String("match", "", "regular expression to select tests to run")
  48. // Insert final newline if needed and tabs after internal newlines.
  49. func tabify(s string) string {
  50. n := len(s)
  51. if n > 0 && s[n-1] != '\n' {
  52. s += "\n"
  53. n++
  54. }
  55. for i := 0; i < n-1; i++ { // -1 to avoid final newline
  56. if s[i] == '\n' {
  57. return s[0:i+1] + "\t" + tabify(s[i+1:n])
  58. }
  59. }
  60. return s
  61. }
  62. // T is a type passed to Test functions to manage test state and support formatted test logs.
  63. // Logs are accumulated during execution and dumped to standard error when done.
  64. type T struct {
  65. errors string
  66. failed bool
  67. ch chan *T
  68. }
  69. // Fail marks the Test function as having failed but continues execution.
  70. func (t *T) Fail() { t.failed = true }
  71. // Failed returns whether the Test function has failed.
  72. func (t *T) Failed() bool { return t.failed }
  73. // FailNow marks the Test function as having failed and stops its execution.
  74. // Execution will continue at the next Test.
  75. func (t *T) FailNow() {
  76. t.Fail()
  77. t.ch <- t
  78. runtime.Goexit()
  79. }
  80. // Log formats its arguments using default formatting, analogous to Print(),
  81. // and records the text in the error log.
  82. func (t *T) Log(args ...interface{}) { t.errors += "\t" + tabify(fmt.Sprintln(args...)) }
  83. // Log formats its arguments according to the format, analogous to Printf(),
  84. // and records the text in the error log.
  85. func (t *T) Logf(format string, args ...interface{}) {
  86. t.errors += "\t" + tabify(fmt.Sprintf(format, args...))
  87. }
  88. // Error is equivalent to Log() followed by Fail().
  89. func (t *T) Error(args ...interface{}) {
  90. t.Log(args...)
  91. t.Fail()
  92. }
  93. // Errorf is equivalent to Logf() followed by Fail().
  94. func (t *T) Errorf(format string, args ...interface{}) {
  95. t.Logf(format, args...)
  96. t.Fail()
  97. }
  98. // Fatal is equivalent to Log() followed by FailNow().
  99. func (t *T) Fatal(args ...interface{}) {
  100. t.Log(args...)
  101. t.FailNow()
  102. }
  103. // Fatalf is equivalent to Logf() followed by FailNow().
  104. func (t *T) Fatalf(format string, args ...interface{}) {
  105. t.Logf(format, args...)
  106. t.FailNow()
  107. }
  108. // An internal type but exported because it is cross-package; part of the implementation
  109. // of gotest.
  110. type InternalTest struct {
  111. Name string
  112. F func(*T)
  113. }
  114. func tRunner(t *T, test *InternalTest) {
  115. test.F(t)
  116. t.ch <- t
  117. }
  118. // An internal function but exported because it is cross-package; part of the implementation
  119. // of gotest.
  120. func Main(matchString func(pat, str string) (bool, os.Error), tests []InternalTest) {
  121. flag.Parse()
  122. ok := true
  123. if len(tests) == 0 {
  124. println("testing: warning: no tests to run")
  125. }
  126. for i := 0; i < len(tests); i++ {
  127. matched, err := matchString(*match, tests[i].Name)
  128. if err != nil {
  129. println("invalid regexp for -match:", err.String())
  130. os.Exit(1)
  131. }
  132. if !matched {
  133. continue
  134. }
  135. if *chatty {
  136. println("=== RUN ", tests[i].Name)
  137. }
  138. t := new(T)
  139. t.ch = make(chan *T)
  140. go tRunner(t, &tests[i])
  141. <-t.ch
  142. if t.failed {
  143. println("--- FAIL:", tests[i].Name)
  144. print(t.errors)
  145. ok = false
  146. } else if *chatty {
  147. println("--- PASS:", tests[i].Name)
  148. print(t.errors)
  149. }
  150. }
  151. if !ok {
  152. println("FAIL")
  153. os.Exit(1)
  154. }
  155. println("PASS")
  156. }