Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 35.2k
bpo-4080: unittest durations#12271
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Uh oh!
There was an error while loading. Please reload this page.
bpo-4080: unittest durations #12271
Changes from all commits
6f0b1fe2b16e5749aa7914830509f8a49d3875e93d59dfc67c92bc24d88087e1952ffa9f308dc226288a89e915f968c3afa8b38e9f95edc79beb93186fc3f8a1f5e499d985367223bc93c4af913f4d638b3bb3e0a93b4600a6bcbb961ba55d0330f69935349f4cd001447192864124391a9c098c9172065a4e21b2ffe2502fdfe1dc0e137e86a094c36490133217b89b2b37ad2b7f3dccfd65b04772f963ea0be819f9c4bed5f317e6d3b5890a3d70File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -244,6 +244,10 @@ Command-line options | ||
| Show local variables in tracebacks. | ||
| .. cmdoption:: --durations N | ||
| Show the N slowest test cases (N=0 for all). | ||
| .. versionadded:: 3.2 | ||
| The command-line options ``-b``, ``-c`` and ``-f`` were added. | ||
| @@ -253,10 +257,12 @@ Command-line options | ||
| .. versionadded:: 3.7 | ||
| The command-line option ``-k``. | ||
| .. versionadded:: 3.12 | ||
| The command-line option ``--durations``. | ||
| The command line can also be used for test discovery, for running all of the | ||
| tests in a project or just a subset. | ||
| .. _unittest-test-discovery: | ||
| Test Discovery | ||
| @@ -2009,6 +2015,13 @@ Loading and running tests | ||
| A list containing :class:`TestCase` instances that were marked as expected | ||
| failures, but succeeded. | ||
| .. attribute:: collectedDurations | ||
| A list containing 2-tuples of :class:`TestCase` instances and floats | ||
| representing the elapsed time of each test which was run. | ||
| .. versionadded:: 3.12 | ||
| .. attribute:: shouldStop | ||
| Set to ``True`` when the execution of tests should stop by :meth:`stop`. | ||
| @@ -2160,14 +2173,27 @@ Loading and running tests | ||
| .. versionadded:: 3.4 | ||
| .. method:: addDuration(test, elapsed) | ||
| Called when the test case finishes. *elapsed* is the time represented in | ||
| seconds, and it includes the execution of cleanup functions. | ||
| .. versionadded:: 3.12 | ||
| .. class:: TextTestResult(stream, descriptions, verbosity) | ||
| .. class:: TextTestResult(stream, descriptions, verbosity, *, durations=None) | ||
| A concrete implementation of :class:`TestResult` used by the | ||
| :class:`TextTestRunner`. | ||
| :class:`TextTestRunner`. Subclasses should accept ``**kwargs`` to ensure | ||
| compatibility as the interface changes. | ||
| .. versionadded:: 3.2 | ||
| .. versionadded:: 3.12 | ||
| Added *durations* keyword argument. | ||
| .. versionchanged:: 3.12 | ||
| Subclasses should accept ``**kwargs`` to ensure compatibility as the | ||
giampaolo marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| interface changes. | ||
| .. data:: defaultTestLoader | ||
| @@ -2177,7 +2203,8 @@ Loading and running tests | ||
| .. class:: TextTestRunner(stream=None, descriptions=True, verbosity=1, failfast=False, \ | ||
| buffer=False, resultclass=None, warnings=None, *, tb_locals=False) | ||
| buffer=False, resultclass=None, warnings=None, *, \ | ||
| tb_locals=False, durations=None) | ||
| A basic test runner implementation that outputs results to a stream. If *stream* | ||
| is ``None``, the default, :data:`sys.stderr` is used as the output stream. This class | ||
| @@ -2195,14 +2222,17 @@ Loading and running tests | ||
| *warnings* to ``None``. | ||
| .. versionchanged:: 3.2 | ||
| Added the ``warnings`` argument. | ||
| Added the *warnings* parameter. | ||
| .. versionchanged:: 3.2 | ||
| The default stream is set to :data:`sys.stderr` at instantiation time rather | ||
| than import time. | ||
| .. versionchanged:: 3.5 | ||
| Added the tb_locals parameter. | ||
| Added the *tb_locals* parameter. | ||
| .. versionchanged:: 3.12 | ||
| Added the *durations* parameter. | ||
| .. method:: _makeResult() | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -8,8 +8,11 @@ | ||
| import unittest | ||
| from unittest.case import _Outcome | ||
| from test.test_unittest.support import (LoggingResult, | ||
| ResultWithNoStartTestRunStopTestRun) | ||
| from test.test_unittest.support import ( | ||
| BufferedWriter, | ||
| LoggingResult, | ||
| ResultWithNoStartTestRunStopTestRun, | ||
| ) | ||
| def resultFactory(*_): | ||
| @@ -1176,6 +1179,7 @@ def test_init(self): | ||
| self.assertTrue(runner.descriptions) | ||
| self.assertEqual(runner.resultclass, unittest.TextTestResult) | ||
| self.assertFalse(runner.tb_locals) | ||
| self.assertIsNone(runner.durations) | ||
| def test_multiple_inheritance(self): | ||
| class AResult(unittest.TestResult): | ||
| @@ -1362,6 +1366,65 @@ def testSpecifiedStreamUsed(self): | ||
| runner = unittest.TextTestRunner(f) | ||
| self.assertTrue(runner.stream.stream is f) | ||
| def test_durations(self): | ||
| def run(test, expect_durations): | ||
giampaolo marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| stream = BufferedWriter() | ||
| runner = unittest.TextTestRunner(stream=stream, durations=5, verbosity=2) | ||
| result = runner.run(test) | ||
| self.assertEqual(result.durations, 5) | ||
| stream.flush() | ||
| text = stream.getvalue() | ||
| regex = r"\n\d+.\d\d\ds" | ||
| if expect_durations: | ||
| self.assertEqual(len(result.collectedDurations), 1) | ||
| self.assertIn('Slowest test durations', text) | ||
| self.assertRegex(text, regex) | ||
| else: | ||
| self.assertEqual(len(result.collectedDurations), 0) | ||
| self.assertNotIn('Slowest test durations', text) | ||
| self.assertNotRegex(text, regex) | ||
| # success | ||
| class Foo(unittest.TestCase): | ||
| def test_1(self): | ||
| pass | ||
| run(Foo('test_1'), True) | ||
| # failure | ||
| class Foo(unittest.TestCase): | ||
| def test_1(self): | ||
| self.assertEqual(0, 1) | ||
| run(Foo('test_1'), True) | ||
| # error | ||
| class Foo(unittest.TestCase): | ||
| def test_1(self): | ||
| 1 / 0 | ||
| run(Foo('test_1'), True) | ||
| # error in setUp and tearDown | ||
| class Foo(unittest.TestCase): | ||
| def setUp(self): | ||
| 1 / 0 | ||
| tearDown = setUp | ||
| def test_1(self): | ||
| pass | ||
| run(Foo('test_1'), True) | ||
| # skip (expect no durations) | ||
| class Foo(unittest.TestCase): | ||
| @unittest.skip("reason") | ||
| def test_1(self): | ||
| pass | ||
| run(Foo('test_1'), False) | ||
| if __name__ == "__main__": | ||
| unittest.main() | ||
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.