Merge lp:~thomir-deactivatedaccount/autopilot/fix-autopilot-import-issues into lp:autopilot

Proposed by Thomi Richards
Status: Merged
Approved by: Christopher Lee
Approved revision: 70
Merged at revision: 68
Proposed branch: lp:~thomir-deactivatedaccount/autopilot/fix-autopilot-import-issues
Merge into: lp:autopilot
Diff against target: 224 lines (+54/-28)
2 files modified
autopilot/tests/test_autopilot_functional.py (+37/-25)
bin/autopilot (+17/-3)
To merge this branch: bzr merge lp:~thomir-deactivatedaccount/autopilot/fix-autopilot-import-issues
Reviewer Review Type Date Requested Status
Christopher Lee (community) Approve
jenkins (community) continuous-integration Approve
Review via email: mp+123475@code.launchpad.net

Commit message

Fix autopilot test import behavior to be more convenient, and work around an odd bug inside the unittest module.

Description of the change

This branch changes the autopilot behavior in a couple of important ways:

First, it adds the current working directory to the python module search path (i.e.- sys.path). This means that in order to run a particular set of tests, you now just need to: cd into the directory that contains the tests, and run 'autopilot run testpackagename' - no mode mucking about with PYTHONPATH variables.

Second, it's reasonably common to have several instances of the same test suite on a developers machine. Autopilot now tells you where it's loading tests from for both the 'list' and 'run' commands.

The existing tests around the 'autopilot list' functionality have been modified to cope with this new feature.

To post a comment you must log in.
Revision history for this message
jenkins (martin-mrazik+qa) wrote :
review: Approve (continuous-integration)
69. By Thomi Richards

Fixed code.

70. By Thomi Richards

more cleanups.

Revision history for this message
jenkins (martin-mrazik+qa) wrote :
review: Approve (continuous-integration)
Revision history for this message
Christopher Lee (veebers) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'autopilot/tests/test_autopilot_functional.py'
--- autopilot/tests/test_autopilot_functional.py 2012-08-28 02:23:46 +0000
+++ autopilot/tests/test_autopilot_functional.py 2012-09-10 05:14:26 +0000
@@ -79,7 +79,7 @@
7979
80 environ = os.environ80 environ = os.environ
81 environ.update(dict(81 environ.update(dict(
82 PYTHONPATH='%s:%s' % (self.base_path, ap_base_path),82 PYTHONPATH=ap_base_path,
83 DISPLAY=':0'))83 DISPLAY=':0'))
8484
85 process = subprocess.Popen(85 process = subprocess.Popen(
@@ -100,6 +100,27 @@
100100
101 return (retcode, stdout, stderr)101 return (retcode, stdout, stderr)
102102
103 def assertTestsInOutput(self, tests, output):
104 """Asserts that 'tests' are all present in 'output'."""
105
106 if type(tests) is not list:
107 raise TypeError("tests must be a list, not %r" % type(tests))
108 if not isinstance(output, basestring):
109 raise TypeError("output must be a string, not %r" % type(output))
110
111 expected = '''\
112Loading tests from: %s
113
114%s
115
116 %d total tests.
117''' % (self.base_path,
118 ''.join([' %s\n' % t for t in sorted(tests)]),
119 len(tests))
120
121 self.assertThat(output, Equals(expected))
122
123
103 def create_test_file(self, name, contents):124 def create_test_file(self, name, contents):
104 """Create a test file with the given name and contents.125 """Create a test file with the given name and contents.
105126
@@ -118,11 +139,9 @@
118 """Autopilot list must report 0 tests found with an empty test module."""139 """Autopilot list must report 0 tests found with an empty test module."""
119 code, output, error = self.run_autopilot_list()140 code, output, error = self.run_autopilot_list()
120141
121 expected_output = '\n\n 0 total tests.\n'
122
123 self.assertThat(code, Equals(0))142 self.assertThat(code, Equals(0))
124 self.assertThat(error, Equals(''))143 self.assertThat(error, Equals(''))
125 self.assertThat(output, Equals(expected_output))144 self.assertTestsInOutput([], output)
126145
127 def test_can_list_tests(self):146 def test_can_list_tests(self):
128 """Autopilot must find tests in a file."""147 """Autopilot must find tests in a file."""
@@ -138,13 +157,6 @@
138 """157 """
139 ))158 ))
140159
141 expected_output = '''\
142 tests.test_simple.SimpleTest.test_simple
143
144
145 1 total tests.
146'''
147
148 # ideally these would be different tests, but I'm lazy:160 # ideally these would be different tests, but I'm lazy:
149 valid_test_specs = [161 valid_test_specs = [
150 'tests',162 'tests',
@@ -156,7 +168,7 @@
156 code, output, error = self.run_autopilot_list(test_spec)168 code, output, error = self.run_autopilot_list(test_spec)
157 self.assertThat(code, Equals(0))169 self.assertThat(code, Equals(0))
158 self.assertThat(error, Equals(''))170 self.assertThat(error, Equals(''))
159 self.assertThat(output, Equals(expected_output))171 self.assertTestsInOutput(['tests.test_simple.SimpleTest.test_simple'], output)
160172
161 def test_list_tests_with_import_error(self):173 def test_list_tests_with_import_error(self):
162 self.create_test_file('test_simple.py', dedent("""\174 self.create_test_file('test_simple.py', dedent("""\
@@ -173,6 +185,8 @@
173 ))185 ))
174 code, output, error = self.run_autopilot_list()186 code, output, error = self.run_autopilot_list()
175 expected_regex = '''\187 expected_regex = '''\
188Loading tests from: %s
189
176Failed to import test module: tests.test_simple190Failed to import test module: tests.test_simple
177Traceback \(most recent call last\):191Traceback \(most recent call last\):
178 File "/usr/lib/python2.7/unittest/loader.py", line 252, in _find_tests192 File "/usr/lib/python2.7/unittest/loader.py", line 252, in _find_tests
@@ -186,7 +200,7 @@
186200
187201
188 0 total tests.202 0 total tests.
189'''203''' % self.base_path
190 self.assertThat(code, Equals(0))204 self.assertThat(code, Equals(0))
191 self.assertThat(error, Equals(''))205 self.assertThat(error, Equals(''))
192 self.assertThat(output, MatchesRegex(expected_regex, re.MULTILINE))206 self.assertThat(output, MatchesRegex(expected_regex, re.MULTILINE))
@@ -206,6 +220,8 @@
206 ))220 ))
207 code, output, error = self.run_autopilot_list()221 code, output, error = self.run_autopilot_list()
208 expected_regex = '''\222 expected_regex = '''\
223Loading tests from: %s
224
209Failed to import test module: tests.test_simple225Failed to import test module: tests.test_simple
210Traceback \(most recent call last\):226Traceback \(most recent call last\):
211 File "/usr/lib/python2.7/unittest/loader.py", line 252, in _find_tests227 File "/usr/lib/python2.7/unittest/loader.py", line 252, in _find_tests
@@ -220,7 +236,7 @@
220236
221237
222 0 total tests.238 0 total tests.
223'''239''' % self.base_path
224 self.assertThat(code, Equals(0))240 self.assertThat(code, Equals(0))
225 self.assertThat(error, Equals(''))241 self.assertThat(error, Equals(''))
226 self.assertThat(output, MatchesRegex(expected_regex, re.MULTILINE))242 self.assertThat(output, MatchesRegex(expected_regex, re.MULTILINE))
@@ -244,11 +260,13 @@
244 ))260 ))
245261
246 expected_output = '''\262 expected_output = '''\
263Loading tests from: %s
264
247 *1 tests.test_simple.SimpleTest.test_simple265 *1 tests.test_simple.SimpleTest.test_simple
248266
249267
250 1 total tests.268 1 total tests.
251'''269''' % self.base_path
252270
253 code, output, error = self.run_autopilot_list()271 code, output, error = self.run_autopilot_list()
254 self.assertThat(code, Equals(0))272 self.assertThat(code, Equals(0))
@@ -282,12 +300,14 @@
282 ))300 ))
283301
284 expected_output = '''\302 expected_output = '''\
303Loading tests from: %s
304
285 *2 tests.test_simple.SimpleTest.test_simple305 *2 tests.test_simple.SimpleTest.test_simple
286 *2 tests.test_simple.SimpleTest.test_simple_two306 *2 tests.test_simple.SimpleTest.test_simple_two
287307
288308
289 4 total tests.309 4 total tests.
290'''310''' % self.base_path
291311
292 code, output, error = self.run_autopilot_list()312 code, output, error = self.run_autopilot_list()
293 self.assertThat(code, Equals(0))313 self.assertThat(code, Equals(0))
@@ -310,15 +330,7 @@
310 """330 """
311 ))331 ))
312332
313 expected_output = '''\
314 tests.test_simple.SimpleTest.test_simple
315
316
317 1 total tests.
318'''
319
320 code, output, error = self.run_autopilot_list()333 code, output, error = self.run_autopilot_list()
321 self.assertThat(code, Equals(0))334 self.assertThat(code, Equals(0))
322 self.assertThat(error, Equals(''))335 self.assertThat(error, Equals(''))
323 self.assertThat(output, Equals(expected_output))336 self.assertTestsInOutput(['tests.test_simple.SimpleTest.test_simple'], output)
324
325337
=== modified file 'bin/autopilot'
--- bin/autopilot 2012-08-28 02:23:46 +0000
+++ bin/autopilot 2012-09-10 05:14:26 +0000
@@ -13,11 +13,9 @@
13from imp import find_module13from imp import find_module
14import os14import os
15import os.path15import os.path
16from os import remove, putenv16from os import putenv
17from platform import node17from platform import node
18from subprocess import call
19import sys18import sys
20from tempfile import NamedTemporaryFile
21from testtools import iterate_tests19from testtools import iterate_tests
22from textwrap import dedent20from textwrap import dedent
23from argparse import ArgumentParser21from argparse import ArgumentParser
@@ -192,6 +190,7 @@
192190
193def load_test_suite_from_name(test_names):191def load_test_suite_from_name(test_names):
194 """Returns a test suite object given a dotted test names."""192 """Returns a test suite object given a dotted test names."""
193 patch_python_path()
195 loader = TestLoader()194 loader = TestLoader()
196 if isinstance(test_names, basestring):195 if isinstance(test_names, basestring):
197 test_names = list(test_names)196 test_names = list(test_names)
@@ -200,6 +199,7 @@
200 % (type(test_names)))199 % (type(test_names)))
201200
202 tests = []201 tests = []
202 test_package_locations = []
203 for test_name in test_names:203 for test_name in test_names:
204 top_level_pkg = test_name.split('.')[0]204 top_level_pkg = test_name.split('.')[0]
205 package = __import__(top_level_pkg)205 package = __import__(top_level_pkg)
@@ -209,9 +209,14 @@
209 '..'209 '..'
210 )210 )
211 )211 )
212 if package_parent_path not in test_package_locations:
213 test_package_locations.append(package_parent_path)
212 tests.append(loader.discover(top_level_pkg, top_level_dir=package_parent_path))214 tests.append(loader.discover(top_level_pkg, top_level_dir=package_parent_path))
213 all_tests = TestSuite(tests)215 all_tests = TestSuite(tests)
214216
217 test_dirs = ", ".join(sorted(test_package_locations))
218 print "Loading tests from: %s\n" % test_dirs
219
215 requested_tests = {}220 requested_tests = {}
216 for test in iterate_tests(all_tests):221 for test in iterate_tests(all_tests):
217 # The test loader returns tests that start with 'unittest.loader' if for222 # The test loader returns tests that start with 'unittest.loader' if for
@@ -230,6 +235,15 @@
230 return TestSuite(requested_tests.values())235 return TestSuite(requested_tests.values())
231236
232237
238def patch_python_path():
239 """Prepend the current directory to sys.path to ensure that we can load & run
240 autopilot tests if the caller is in the parent directory.
241
242 """
243 if os.getcwd() not in sys.path:
244 sys.path.insert(0, os.getcwd())
245
246
233def main():247def main():
234 args = parse_arguments()248 args = parse_arguments()
235 if args.mode == 'list':249 if args.mode == 'list':

Subscribers

People subscribed via source and target branches