blob: f3b77203f4c74326d4a6c1be4cf3fcbb385837f1 [file] [log] [blame]
Éric Araujo3a9f58f2011-06-01 20:42:49 +02001:mod:`packaging.tests.pypi_server` --- PyPI mock server
2=======================================================
3
4.. module:: packaging.tests.pypi_server
5 :synopsis: Mock server used to test PyPI-related modules and commands.
6
7
8When you are testing code that works with Packaging, you might find these tools
9useful.
10
11
12The mock server
13---------------
14
15.. class:: PyPIServer
16
17 PyPIServer is a class that implements an HTTP server running in a separate
18 thread. All it does is record the requests for further inspection. The recorded
19 data is available under ``requests`` attribute. The default
20 HTTP response can be overridden with the ``default_response_status``,
21 ``default_response_headers`` and ``default_response_data`` attributes.
22
23 By default, when accessing the server with urls beginning with `/simple/`,
24 the server also record your requests, but will look for files under
25 the `/tests/pypiserver/simple/` path.
26
27 You can tell the sever to serve static files for other paths. This could be
28 accomplished by using the `static_uri_paths` parameter, as below::
29
30 server = PyPIServer(static_uri_paths=["first_path", "second_path"])
31
32
33 You need to create the content that will be served under the
34 `/tests/pypiserver/default` path. If you want to serve content from another
35 place, you also can specify another filesystem path (which needs to be under
36 `tests/pypiserver/`. This will replace the default behavior of the server, and
37 it will not serve content from the `default` dir ::
38
39 server = PyPIServer(static_filesystem_paths=["path/to/your/dir"])
40
41
42 If you just need to add some paths to the existing ones, you can do as shown,
43 keeping in mind that the server will always try to load paths in reverse order
44 (e.g here, try "another/super/path" then the default one) ::
45
46 server = PyPIServer(test_static_path="another/super/path")
47 server = PyPIServer("another/super/path")
48 # or
49 server.static_filesystem_paths.append("another/super/path")
50
51
52 As a result of what, in your tests, while you need to use the PyPIServer, in
53 order to isolates the test cases, the best practice is to place the common files
54 in the `default` folder, and to create a directory for each specific test case::
55
56 server = PyPIServer(static_filesystem_paths = ["default", "test_pypi_server"],
57 static_uri_paths=["simple", "external"])
58
59
60Base class and decorator for tests
61----------------------------------
62
63.. class:: PyPIServerTestCase
64
65 ``PyPIServerTestCase`` is a test case class with setUp and tearDown methods that
66 take care of a single PyPIServer instance attached as a ``pypi`` attribute on
67 the test class. Use it as one of the base classes in your test case::
68
69
70 class UploadTestCase(PyPIServerTestCase):
71
72 def test_something(self):
73 cmd = self.prepare_command()
74 cmd.ensure_finalized()
75 cmd.repository = self.pypi.full_address
76 cmd.run()
77
78 environ, request_data = self.pypi.requests[-1]
79 self.assertEqual(request_data, EXPECTED_REQUEST_DATA)
80
81
82.. decorator:: use_pypi_server
83
84 You also can use a decorator for your tests, if you do not need the same server
85 instance along all you test case. So, you can specify, for each test method,
86 some initialisation parameters for the server.
87
88 For this, you need to add a `server` parameter to your method, like this::
89
90 class SampleTestCase(TestCase):
91
92 @use_pypi_server()
93 def test_something(self, server):
94 ...
95
96
97 The decorator will instantiate the server for you, and run and stop it just
98 before and after your method call. You also can pass the server initializer,
99 just like this::
100
101 class SampleTestCase(TestCase):
102
103 @use_pypi_server("test_case_name")
104 def test_something(self, server):
105 ...