mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 13:41:24 +00:00 
			
		
		
		
	
		
			
	
	
		
			106 lines
		
	
	
	
		
			3.8 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
	
	
		
		
			
		
	
	
			106 lines
		
	
	
	
		
			3.8 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
	
	
|   | :mod:`packaging.tests.pypi_server` --- PyPI mock server
 | ||
|  | =======================================================
 | ||
|  | 
 | ||
|  | .. module:: packaging.tests.pypi_server
 | ||
|  |    :synopsis: Mock server used to test PyPI-related modules and commands.
 | ||
|  | 
 | ||
|  | 
 | ||
|  | When you are testing code that works with Packaging, you might find these tools
 | ||
|  | useful.
 | ||
|  | 
 | ||
|  | 
 | ||
|  | The mock server
 | ||
|  | ---------------
 | ||
|  | 
 | ||
|  | .. class:: PyPIServer
 | ||
|  | 
 | ||
|  |    PyPIServer is a class that implements an HTTP server running in a separate
 | ||
|  |    thread. All it does is record the requests for further inspection. The recorded
 | ||
|  |    data is available under ``requests`` attribute. The default
 | ||
|  |    HTTP response can be overridden with the ``default_response_status``,
 | ||
|  |    ``default_response_headers`` and ``default_response_data`` attributes.
 | ||
|  | 
 | ||
|  |    By default, when accessing the server with urls beginning with `/simple/`,
 | ||
|  |    the server also record your requests, but will look for files under
 | ||
|  |    the `/tests/pypiserver/simple/` path.
 | ||
|  | 
 | ||
|  |    You can tell the sever to serve static files for other paths. This could be
 | ||
|  |    accomplished by using the `static_uri_paths` parameter, as below::
 | ||
|  | 
 | ||
|  |       server = PyPIServer(static_uri_paths=["first_path", "second_path"])
 | ||
|  | 
 | ||
|  | 
 | ||
|  |    You need to create the content that will be served under the
 | ||
|  |    `/tests/pypiserver/default` path. If you want to serve content from another
 | ||
|  |    place, you also can specify another filesystem path (which needs to be under
 | ||
|  |    `tests/pypiserver/`. This will replace the default behavior of the server, and
 | ||
|  |    it will not serve content from the `default` dir ::
 | ||
|  | 
 | ||
|  |       server = PyPIServer(static_filesystem_paths=["path/to/your/dir"])
 | ||
|  | 
 | ||
|  | 
 | ||
|  |    If you just need to add some paths to the existing ones, you can do as shown,
 | ||
|  |    keeping in mind that the server will always try to load paths in reverse order
 | ||
|  |    (e.g here, try "another/super/path" then the default one) ::
 | ||
|  | 
 | ||
|  |       server = PyPIServer(test_static_path="another/super/path")
 | ||
|  |       server = PyPIServer("another/super/path")
 | ||
|  |       # or
 | ||
|  |       server.static_filesystem_paths.append("another/super/path")
 | ||
|  | 
 | ||
|  | 
 | ||
|  |    As a result of what, in your tests, while you need to use the PyPIServer, in
 | ||
|  |    order to isolates the test cases, the best practice is to place the common files
 | ||
|  |    in the `default` folder, and to create a directory for each specific test case::
 | ||
|  | 
 | ||
|  |       server = PyPIServer(static_filesystem_paths = ["default", "test_pypi_server"],
 | ||
|  |                           static_uri_paths=["simple", "external"])
 | ||
|  | 
 | ||
|  | 
 | ||
|  | Base class and decorator for tests
 | ||
|  | ----------------------------------
 | ||
|  | 
 | ||
|  | .. class:: PyPIServerTestCase
 | ||
|  | 
 | ||
|  |    ``PyPIServerTestCase`` is a test case class with setUp and tearDown methods that
 | ||
|  |    take care of a single PyPIServer instance attached as a ``pypi`` attribute on
 | ||
|  |    the test class. Use it as one of the base classes in your test case::
 | ||
|  | 
 | ||
|  | 
 | ||
|  |       class UploadTestCase(PyPIServerTestCase):
 | ||
|  | 
 | ||
|  |           def test_something(self):
 | ||
|  |               cmd = self.prepare_command()
 | ||
|  |               cmd.ensure_finalized()
 | ||
|  |               cmd.repository = self.pypi.full_address
 | ||
|  |               cmd.run()
 | ||
|  | 
 | ||
|  |               environ, request_data = self.pypi.requests[-1]
 | ||
|  |               self.assertEqual(request_data, EXPECTED_REQUEST_DATA)
 | ||
|  | 
 | ||
|  | 
 | ||
|  | .. decorator:: use_pypi_server
 | ||
|  | 
 | ||
|  |    You also can use a decorator for your tests, if you do not need the same server
 | ||
|  |    instance along all you test case. So, you can specify, for each test method,
 | ||
|  |    some initialisation parameters for the server.
 | ||
|  | 
 | ||
|  |    For this, you need to add a `server` parameter to your method, like this::
 | ||
|  | 
 | ||
|  |       class SampleTestCase(TestCase):
 | ||
|  | 
 | ||
|  |           @use_pypi_server()
 | ||
|  |           def test_something(self, server):
 | ||
|  |               ...
 | ||
|  | 
 | ||
|  | 
 | ||
|  |    The decorator will instantiate the server for you, and run and stop it just
 | ||
|  |    before and after your method call. You also can pass the server initializer,
 | ||
|  |    just like this::
 | ||
|  | 
 | ||
|  |       class SampleTestCase(TestCase):
 | ||
|  | 
 | ||
|  |           @use_pypi_server("test_case_name")
 | ||
|  |           def test_something(self, server):
 | ||
|  |               ...
 |