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
1=== modified file 'autopilot/tests/test_autopilot_functional.py'
2--- autopilot/tests/test_autopilot_functional.py 2012-08-28 02:23:46 +0000
3+++ autopilot/tests/test_autopilot_functional.py 2012-09-10 05:14:26 +0000
4@@ -79,7 +79,7 @@
5
6 environ = os.environ
7 environ.update(dict(
8- PYTHONPATH='%s:%s' % (self.base_path, ap_base_path),
9+ PYTHONPATH=ap_base_path,
10 DISPLAY=':0'))
11
12 process = subprocess.Popen(
13@@ -100,6 +100,27 @@
14
15 return (retcode, stdout, stderr)
16
17+ def assertTestsInOutput(self, tests, output):
18+ """Asserts that 'tests' are all present in 'output'."""
19+
20+ if type(tests) is not list:
21+ raise TypeError("tests must be a list, not %r" % type(tests))
22+ if not isinstance(output, basestring):
23+ raise TypeError("output must be a string, not %r" % type(output))
24+
25+ expected = '''\
26+Loading tests from: %s
27+
28+%s
29+
30+ %d total tests.
31+''' % (self.base_path,
32+ ''.join([' %s\n' % t for t in sorted(tests)]),
33+ len(tests))
34+
35+ self.assertThat(output, Equals(expected))
36+
37+
38 def create_test_file(self, name, contents):
39 """Create a test file with the given name and contents.
40
41@@ -118,11 +139,9 @@
42 """Autopilot list must report 0 tests found with an empty test module."""
43 code, output, error = self.run_autopilot_list()
44
45- expected_output = '\n\n 0 total tests.\n'
46-
47 self.assertThat(code, Equals(0))
48 self.assertThat(error, Equals(''))
49- self.assertThat(output, Equals(expected_output))
50+ self.assertTestsInOutput([], output)
51
52 def test_can_list_tests(self):
53 """Autopilot must find tests in a file."""
54@@ -138,13 +157,6 @@
55 """
56 ))
57
58- expected_output = '''\
59- tests.test_simple.SimpleTest.test_simple
60-
61-
62- 1 total tests.
63-'''
64-
65 # ideally these would be different tests, but I'm lazy:
66 valid_test_specs = [
67 'tests',
68@@ -156,7 +168,7 @@
69 code, output, error = self.run_autopilot_list(test_spec)
70 self.assertThat(code, Equals(0))
71 self.assertThat(error, Equals(''))
72- self.assertThat(output, Equals(expected_output))
73+ self.assertTestsInOutput(['tests.test_simple.SimpleTest.test_simple'], output)
74
75 def test_list_tests_with_import_error(self):
76 self.create_test_file('test_simple.py', dedent("""\
77@@ -173,6 +185,8 @@
78 ))
79 code, output, error = self.run_autopilot_list()
80 expected_regex = '''\
81+Loading tests from: %s
82+
83 Failed to import test module: tests.test_simple
84 Traceback \(most recent call last\):
85 File "/usr/lib/python2.7/unittest/loader.py", line 252, in _find_tests
86@@ -186,7 +200,7 @@
87
88
89 0 total tests.
90-'''
91+''' % self.base_path
92 self.assertThat(code, Equals(0))
93 self.assertThat(error, Equals(''))
94 self.assertThat(output, MatchesRegex(expected_regex, re.MULTILINE))
95@@ -206,6 +220,8 @@
96 ))
97 code, output, error = self.run_autopilot_list()
98 expected_regex = '''\
99+Loading tests from: %s
100+
101 Failed to import test module: tests.test_simple
102 Traceback \(most recent call last\):
103 File "/usr/lib/python2.7/unittest/loader.py", line 252, in _find_tests
104@@ -220,7 +236,7 @@
105
106
107 0 total tests.
108-'''
109+''' % self.base_path
110 self.assertThat(code, Equals(0))
111 self.assertThat(error, Equals(''))
112 self.assertThat(output, MatchesRegex(expected_regex, re.MULTILINE))
113@@ -244,11 +260,13 @@
114 ))
115
116 expected_output = '''\
117+Loading tests from: %s
118+
119 *1 tests.test_simple.SimpleTest.test_simple
120
121
122 1 total tests.
123-'''
124+''' % self.base_path
125
126 code, output, error = self.run_autopilot_list()
127 self.assertThat(code, Equals(0))
128@@ -282,12 +300,14 @@
129 ))
130
131 expected_output = '''\
132+Loading tests from: %s
133+
134 *2 tests.test_simple.SimpleTest.test_simple
135 *2 tests.test_simple.SimpleTest.test_simple_two
136
137
138 4 total tests.
139-'''
140+''' % self.base_path
141
142 code, output, error = self.run_autopilot_list()
143 self.assertThat(code, Equals(0))
144@@ -310,15 +330,7 @@
145 """
146 ))
147
148- expected_output = '''\
149- tests.test_simple.SimpleTest.test_simple
150-
151-
152- 1 total tests.
153-'''
154-
155 code, output, error = self.run_autopilot_list()
156 self.assertThat(code, Equals(0))
157 self.assertThat(error, Equals(''))
158- self.assertThat(output, Equals(expected_output))
159-
160+ self.assertTestsInOutput(['tests.test_simple.SimpleTest.test_simple'], output)
161
162=== modified file 'bin/autopilot'
163--- bin/autopilot 2012-08-28 02:23:46 +0000
164+++ bin/autopilot 2012-09-10 05:14:26 +0000
165@@ -13,11 +13,9 @@
166 from imp import find_module
167 import os
168 import os.path
169-from os import remove, putenv
170+from os import putenv
171 from platform import node
172-from subprocess import call
173 import sys
174-from tempfile import NamedTemporaryFile
175 from testtools import iterate_tests
176 from textwrap import dedent
177 from argparse import ArgumentParser
178@@ -192,6 +190,7 @@
179
180 def load_test_suite_from_name(test_names):
181 """Returns a test suite object given a dotted test names."""
182+ patch_python_path()
183 loader = TestLoader()
184 if isinstance(test_names, basestring):
185 test_names = list(test_names)
186@@ -200,6 +199,7 @@
187 % (type(test_names)))
188
189 tests = []
190+ test_package_locations = []
191 for test_name in test_names:
192 top_level_pkg = test_name.split('.')[0]
193 package = __import__(top_level_pkg)
194@@ -209,9 +209,14 @@
195 '..'
196 )
197 )
198+ if package_parent_path not in test_package_locations:
199+ test_package_locations.append(package_parent_path)
200 tests.append(loader.discover(top_level_pkg, top_level_dir=package_parent_path))
201 all_tests = TestSuite(tests)
202
203+ test_dirs = ", ".join(sorted(test_package_locations))
204+ print "Loading tests from: %s\n" % test_dirs
205+
206 requested_tests = {}
207 for test in iterate_tests(all_tests):
208 # The test loader returns tests that start with 'unittest.loader' if for
209@@ -230,6 +235,15 @@
210 return TestSuite(requested_tests.values())
211
212
213+def patch_python_path():
214+ """Prepend the current directory to sys.path to ensure that we can load & run
215+ autopilot tests if the caller is in the parent directory.
216+
217+ """
218+ if os.getcwd() not in sys.path:
219+ sys.path.insert(0, os.getcwd())
220+
221+
222 def main():
223 args = parse_arguments()
224 if args.mode == 'list':

Subscribers

People subscribed via source and target branches