Merge lp:~lifeless/testtools/time into lp:~testtools-committers/testtools/trunk

Proposed by Robert Collins
Status: Merged
Approved by: Jonathan Lange
Approved revision: not available
Merged at revision: not available
Proposed branch: lp:~lifeless/testtools/time
Merge into: lp:~testtools-committers/testtools/trunk
Prerequisite: lp:~lifeless/testtools/that
Diff against target: 131 lines (+65/-0)
3 files modified
MANUAL (+8/-0)
testtools/testresult.py (+29/-0)
testtools/tests/test_testresult.py (+28/-0)
To merge this branch: bzr merge lp:~lifeless/testtools/time
Reviewer Review Type Date Requested Status
Jonathan Lange Approve
Review via email: mp+15080@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Robert Collins (lifeless) wrote :

This rounds out some existing time support and doing so makes TextTestResult easier to write and test.

Revision history for this message
Jonathan Lange (jml) wrote :

Hey Rob,

This patch looks clean and potentially useful. Thanks for explaining possible uses in the docs for time().

jml

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'MANUAL'
2--- MANUAL 2009-11-20 09:25:20 +0000
3+++ MANUAL 2009-11-20 09:25:20 +0000
4@@ -116,6 +116,14 @@
5 exists. It is used as a hook point to allow clean disconnection of network
6 resources and similar concerns.
7
8+TestResult.time
9+~~~~~~~~~~~~~~~
10+
11+This method controls the time used by a TestResult, permitting accurate
12+timing of test results gathered on different machines or in different threads.
13+See pydoc testtools.TestResult.time for more details.
14+
15+
16 ThreadsafeForwardingResult
17 ~~~~~~~~~~~~~~~~~~~~~~~~~~
18
19
20=== modified file 'testtools/testresult.py'
21--- testtools/testresult.py 2009-11-17 08:35:36 +0000
22+++ testtools/testresult.py 2009-11-20 09:25:20 +0000
23@@ -10,6 +10,7 @@
24 'ThreadsafeForwardingResult',
25 ]
26
27+import datetime
28 import unittest
29
30
31@@ -33,6 +34,7 @@
32 def __init__(self):
33 super(TestResult, self).__init__()
34 self.skip_reasons = {}
35+ self.__now = None
36 # -- Start: As per python 2.7 --
37 self.expectedFailures = []
38 self.unexpectedSuccesses = []
39@@ -109,6 +111,18 @@
40 return self._exc_info_to_string(err, test)
41 return _details_to_str(details)
42
43+ def _now(self):
44+ """Return the current 'test time'.
45+
46+ If the time() method has not been called, this is equivalent to
47+ datetime.now(), otherwise its the last supplied datestamp given to the
48+ time() method.
49+ """
50+ if self.__now is None:
51+ return datetime.datetime.now()
52+ else:
53+ return self.__now
54+
55 def startTestRun(self):
56 """Called before a test run starts.
57
58@@ -121,6 +135,21 @@
59 New in python 2.7
60 """
61
62+ def time(self, a_datetime):
63+ """Provide a timestamp to represent the current time.
64+
65+ This is useful when test activity is time delayed, or happening
66+ concurrently and getting the system time between API calls will not
67+ accurately represent the duration of tests (or the whole run).
68+
69+ Calling time() sets the datetime used by the TestResult object.
70+ Time is permitted to go backwards when using this call.
71+
72+ :param a_datetime: A datetime.datetime object with TZ information or
73+ None to reset the TestResult to gathering time from the system.
74+ """
75+ self.__now = a_datetime
76+
77 def done(self):
78 """Called when the test runner is done.
79
80
81=== modified file 'testtools/tests/test_testresult.py'
82--- testtools/tests/test_testresult.py 2009-10-31 10:45:26 +0000
83+++ testtools/tests/test_testresult.py 2009-11-20 09:25:20 +0000
84@@ -4,6 +4,7 @@
85
86 __metaclass__ = type
87
88+import datetime
89 import sys
90 import threading
91
92@@ -13,6 +14,7 @@
93 TestCase,
94 TestResult,
95 ThreadsafeForwardingResult,
96+ testresult,
97 )
98 from testtools.content import Content, ContentType
99 from testtools.tests.helpers import (
100@@ -120,6 +122,32 @@
101 u"Skipped for another reason":[self]},
102 result.skip_reasons)
103
104+ def test_now_datetime_now(self):
105+ result = self.makeResult()
106+ olddatetime = testresult.datetime
107+ def restore():
108+ testresult.datetime = olddatetime
109+ self.addCleanup(restore)
110+ class Module:
111+ pass
112+ now = datetime.datetime.now()
113+ stubdatetime = Module()
114+ stubdatetime.datetime = Module()
115+ stubdatetime.datetime.now = lambda:now
116+ testresult.datetime = stubdatetime
117+ self.assertEqual(now, result._now())
118+ # Set an explicit datetime, then go back to looking it up.
119+ result.time(datetime.datetime.now())
120+ self.assertNotEqual(now, result._now())
121+ result.time(None)
122+ self.assertEqual(now, result._now())
123+
124+ def test_now_datetime_time(self):
125+ result = self.makeResult()
126+ now = datetime.datetime.now()
127+ result.time(now)
128+ self.assertEqual(now, result._now())
129+
130
131 class TestWithFakeExceptions(TestCase):
132

Subscribers

People subscribed via source and target branches