test-webkitpy: move printing-related code out of the runner
[WebKit-https.git] / Tools / Scripts / webkitpy / test / runner.py
1 # Copyright (C) 2012 Google, Inc.
2 #
3 # Redistribution and use in source and binary forms, with or without
4 # modification, are permitted provided that the following conditions
5 # are met:
6 # 1.  Redistributions of source code must retain the above copyright
7 #     notice, this list of conditions and the following disclaimer.
8 # 2.  Redistributions in binary form must reproduce the above copyright
9 #     notice, this list of conditions and the following disclaimer in the
10 #     documentation and/or other materials provided with the distribution.
11 #
12 # THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND
13 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
14 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
15 # DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR
16 # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
17 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
18 # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
19 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
20 # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
21 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22
23 """code to actually run a list of python tests."""
24
25 import logging
26 import time
27 import unittest
28
29
30 _log = logging.getLogger(__name__)
31
32
33 class Runner(object):
34     def __init__(self, printer, options, loader):
35         self.options = options
36         self.printer = printer
37         self.loader = loader
38
39     def all_test_names(self, suite):
40         names = []
41         if hasattr(suite, '_tests'):
42             for t in suite._tests:
43                 names.extend(self.all_test_names(t))
44         else:
45             names.append(self.printer.test_name(suite))
46         return names
47
48     def run(self, suite):
49         run_start_time = time.time()
50         all_test_names = self.all_test_names(suite)
51         result = unittest.TestResult()
52         stop = run_start_time
53         for test_name in all_test_names:
54             self.printer.print_started_test(test_name)
55             num_failures = len(result.failures)
56             num_errors = len(result.errors)
57
58             start = time.time()
59             # FIXME: it's kinda lame that we re-load the test suites for each
60             # test, and this may slow things down, but this makes implementing
61             # the logging easy and will also allow us to parallelize nicely.
62             self.loader.loadTestsFromName(test_name, None).run(result)
63             stop = time.time()
64
65             err = None
66             failure = None
67             if len(result.failures) > num_failures:
68                 failure = result.failures[num_failures][1]
69             elif len(result.errors) > num_errors:
70                 err = result.errors[num_errors][1]
71             self.printer.print_finished_test(result, test_name, stop - start, failure, err)
72
73         self.printer.print_result(result, stop - run_start_time)
74
75         return result