comparison tests/conftest.py @ 391:3e4bb57d8506

tests: Add support for testing the Chef server. * Make the server be functional without calling `getWsgiApp`. * Add new type of test files that use a Werkzeug test client.
author Ludovic Chabant <ludovic@chabant.com>
date Sun, 17 May 2015 10:48:41 -0700
parents 2d5f2289885a
children 879b6b5647a8
comparison
equal deleted inserted replaced
390:3a184fbc900b 391:3e4bb57d8506
27 logging.getLogger('piecrust').addHandler(hdl) 27 logging.getLogger('piecrust').addHandler(hdl)
28 logging.getLogger('piecrust').setLevel(logging.DEBUG) 28 logging.getLogger('piecrust').setLevel(logging.DEBUG)
29 29
30 30
31 def pytest_collect_file(parent, path): 31 def pytest_collect_file(parent, path):
32 if path.ext == ".bake" and path.basename.startswith("test"): 32 if path.basename.startswith("test"):
33 return BakeTestFile(path, parent) 33 if path.ext == ".bake":
34 elif path.ext == ".chef" and path.basename.startswith("test"): 34 return BakeTestFile(path, parent)
35 return ChefTestFile(path, parent) 35 elif path.ext == ".chef":
36 return ChefTestFile(path, parent)
37 elif path.ext == ".serve":
38 return ServeTestFile(path, parent)
36 39
37 40
38 class YamlTestFileBase(pytest.File): 41 class YamlTestFileBase(pytest.File):
39 def collect(self): 42 def collect(self):
40 spec = yaml.load_all(self.fspath.open()) 43 spec = yaml.load_all(self.fspath.open())
185 pass 188 pass
186 189
187 190
188 class BakeTestFile(YamlTestFileBase): 191 class BakeTestFile(YamlTestFileBase):
189 __item_class__ = BakeTestItem 192 __item_class__ = BakeTestItem
193
194
195 class ServeTestItem(YamlTestItemBase):
196 class _TestApp(object):
197 def __init__(self, server):
198 self.server = server
199
200 def __call__(self, environ, start_response):
201 return self.server._try_run_request(environ, start_response)
202
203 def runtest(self):
204 fs = self._prepareMockFs()
205
206 url = self.spec.get('url')
207 if url is None:
208 raise Exception("Missing URL in test spec.")
209
210 expected_status = self.spec.get('status', 200)
211 expected_headers = self.spec.get('headers')
212 expected_output = self.spec.get('out')
213 expected_contains = self.spec.get('out_contains')
214
215 from werkzeug.test import Client
216 from werkzeug.wrappers import BaseResponse
217 from piecrust.serving.server import Server
218 with mock_fs_scope(fs):
219 server = Server(fs.path('/kitchen'))
220 test_app = self._TestApp(server)
221 client = Client(test_app, BaseResponse)
222 resp = client.get(url)
223 assert expected_status == resp.status_code
224
225 if expected_headers:
226 for k, v in expected_headers.items():
227 assert v == resp.headers.get(k)
228
229 actual = resp.data.decode('utf8').rstrip()
230 if expected_output:
231 assert expected_output.rstrip() == actual
232
233 if expected_contains:
234 assert expected_contains.rstrip() in actual
235
236 def reportinfo(self):
237 return self.fspath, 0, "serve: %s" % self.name
238
239
240 class ServeTestFile(YamlTestFileBase):
241 __item_class__ = ServeTestItem
190 242
191 243
192 def _add_mock_files(fs, parent_path, spec): 244 def _add_mock_files(fs, parent_path, spec):
193 for name, subspec in spec.items(): 245 for name, subspec in spec.items():
194 path = os.path.join(parent_path, name) 246 path = os.path.join(parent_path, name)