~bzr-pqm/bzr/bzr.dev

841 by Martin Pool
- Start splitting bzr-independent parts of the test framework into
1
# Copyright (C) 2005 by Canonical Ltd
2
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
17
18
"""Enhanced layer on unittest.
19
20
This does several things:
21
22
* nicer reporting as tests run
23
24
* test code can log messages into a buffer that is recorded to disk
25
  and displayed if the test fails
26
27
* tests can be run in a separate directory, which is useful for code that
28
  wants to create files
29
30
* utilities to run external commands and check their return code
31
  and/or output
32
1102 by Martin Pool
- merge test refactoring from robertc
33
Test cases should normally subclass testsweet.TestCase.  The test runner should
841 by Martin Pool
- Start splitting bzr-independent parts of the test framework into
34
call runsuite().
35
36
This is meant to become independent of bzr, though that's not quite
37
true yet.
38
"""  
39
1102 by Martin Pool
- merge test refactoring from robertc
40
import unittest
41
import sys
841 by Martin Pool
- Start splitting bzr-independent parts of the test framework into
42
974.1.26 by aaron.bentley at utoronto
merged mbp@sourcefrog.net-20050817233101-0939da1cf91f2472
43
# XXX: Don't need this anymore now we depend on python2.4
841 by Martin Pool
- Start splitting bzr-independent parts of the test framework into
44
def _need_subprocess():
45
    sys.stderr.write("sorry, this test suite requires the subprocess module\n"
46
                     "this is shipped with python2.4 and available separately for 2.3\n")
47
    
48
49
class CommandFailed(Exception):
50
    pass
51
52
53
class TestSkipped(Exception):
54
    """Indicates that a test was intentionally skipped, rather than failing."""
55
    # XXX: Not used yet
56
57
1102 by Martin Pool
- merge test refactoring from robertc
58
class _MyResult(unittest._TextTestResult):
841 by Martin Pool
- Start splitting bzr-independent parts of the test framework into
59
    """
60
    Custom TestResult.
61
62
    No special behaviour for now.
63
    """
64
65
    def startTest(self, test):
1102 by Martin Pool
- merge test refactoring from robertc
66
        unittest.TestResult.startTest(self, test)
841 by Martin Pool
- Start splitting bzr-independent parts of the test framework into
67
        # TODO: Maybe show test.shortDescription somewhere?
842 by Martin Pool
- don't say runit when running tests under python2.3 dammit
68
        what = test.id()
69
        # python2.3 has the bad habit of just "runit" for doctests
70
        if what == 'runit':
71
            what = test.shortDescription()
1102 by Martin Pool
- merge test refactoring from robertc
72
        if self.showAll:
73
            self.stream.write('%-60.60s' % what)
74
        self.stream.flush()
841 by Martin Pool
- Start splitting bzr-independent parts of the test framework into
75
76
    def addError(self, test, err):
1102 by Martin Pool
- merge test refactoring from robertc
77
        super(_MyResult, self).addError(test, err)
78
        self.stream.flush()
841 by Martin Pool
- Start splitting bzr-independent parts of the test framework into
79
80
    def addFailure(self, test, err):
1102 by Martin Pool
- merge test refactoring from robertc
81
        super(_MyResult, self).addFailure(test, err)
82
        self.stream.flush()
841 by Martin Pool
- Start splitting bzr-independent parts of the test framework into
83
84
    def addSuccess(self, test):
1102 by Martin Pool
- merge test refactoring from robertc
85
        if self.showAll:
86
            self.stream.writeln('OK')
87
        elif self.dots:
88
            self.stream.write('~')
89
        self.stream.flush()
90
        unittest.TestResult.addSuccess(self, test)
91
92
    def printErrorList(self, flavour, errors):
93
        for test, err in errors:
94
            self.stream.writeln(self.separator1)
95
            self.stream.writeln("%s: %s" % (flavour,self.getDescription(test)))
96
            self.stream.writeln(self.separator2)
97
            self.stream.writeln("%s" % err)
1123 by Martin Pool
* move bzr-specific code from testsweet into bzrlib.selftest
98
            if hasattr(test, '_get_log'):
1102 by Martin Pool
- merge test refactoring from robertc
99
                self.stream.writeln()
100
                self.stream.writeln('log from this test:')
101
                print >>self.stream, test._get_log()
102
103
104
class TextTestRunner(unittest.TextTestRunner):
105
106
    def _makeResult(self):
107
        return _MyResult(self.stream, self.descriptions, self.verbosity)
841 by Martin Pool
- Start splitting bzr-independent parts of the test framework into
108
109
965 by Martin Pool
- selftest is less verbose by default, and takes a -v option if you want it
110
def run_suite(suite, name='test', verbose=False):
841 by Martin Pool
- Start splitting bzr-independent parts of the test framework into
111
    import shutil
1123 by Martin Pool
* move bzr-specific code from testsweet into bzrlib.selftest
112
    from bzrlib.selftest import FunctionalTestCase
1102 by Martin Pool
- merge test refactoring from robertc
113
    FunctionalTestCase._TEST_NAME = name
114
    if verbose:
115
        verbosity = 2
116
    else:
117
        verbosity = 1
118
    runner = TextTestRunner(stream=sys.stdout,
119
                            descriptions=0,
120
                            verbosity=verbosity)
121
    result = runner.run(suite)
122
    # This is still a little bogus, 
123
    # but only a little. Folk not using our testrunner will
124
    # have to delete their temp directories themselves.
125
    if result.wasSuccessful():
1122 by Martin Pool
- only delete the test scratch directory if it was created
126
        if FunctionalTestCase.TEST_ROOT:
127
            shutil.rmtree(FunctionalTestCase.TEST_ROOT) 
1102 by Martin Pool
- merge test refactoring from robertc
128
    else:
129
        print "Failed tests working directories are in '%s'\n" % FunctionalTestCase.TEST_ROOT
841 by Martin Pool
- Start splitting bzr-independent parts of the test framework into
130
    return result.wasSuccessful()