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