METADATA 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. Metadata-Version: 2.1
  2. Name: pytest-localserver
  3. Version: 0.5.1.post0
  4. Summary: py.test plugin to test server connections locally.
  5. Home-page: https://github.com/pytest-dev/pytest-localserver
  6. Author: Sebastian Rahlf
  7. Author-email: basti@redtoad.de
  8. Maintainer: David Zaslavsky
  9. Maintainer-email: diazona@ellipsix.net
  10. License: MIT License
  11. Keywords: py.test pytest server localhost http smtp
  12. Platform: UNKNOWN
  13. Classifier: Framework :: Pytest
  14. Classifier: Operating System :: OS Independent
  15. Classifier: Development Status :: 4 - Beta
  16. Classifier: Intended Audience :: Developers
  17. Classifier: License :: OSI Approved :: MIT License
  18. Classifier: Programming Language :: Python :: 2
  19. Classifier: Programming Language :: Python :: 2.7
  20. Classifier: Programming Language :: Python :: 3
  21. Classifier: Programming Language :: Python :: 3.3
  22. Classifier: Programming Language :: Python :: 3.4
  23. Classifier: Programming Language :: Python :: 3.5
  24. Classifier: Programming Language :: Python :: 3.6
  25. Classifier: Programming Language :: Python :: 3.7
  26. Classifier: Programming Language :: Python :: 3.8
  27. Classifier: Programming Language :: Python :: 3.9
  28. Classifier: Programming Language :: Python :: 3.10
  29. Classifier: Topic :: Software Development :: Testing
  30. Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*
  31. License-File: LICENSE
  32. License-File: AUTHORS
  33. Requires-Dist: werkzeug (>=0.10)
  34. ==================
  35. pytest-localserver
  36. ==================
  37. pytest-localserver is a plugin for the `pytest`_ testing framework which enables
  38. you to test server connections locally.
  39. Sometimes `monkeypatching`_ ``urllib2.urlopen()`` just does not cut it, for
  40. instance if you work with ``urllib2.Request``, define your own openers/handlers
  41. or work with ``httplib``. In these cases it may come in handy to have an HTTP
  42. server running locally which behaves just like the real thing [1]_. Well, look
  43. no further!
  44. Quickstart
  45. ==========
  46. Let's say you have a function to scrape HTML which only required to be pointed
  47. at a URL ::
  48. import requests
  49. def scrape(url):
  50. html = requests.get(url).text
  51. # some parsing happens here
  52. # ...
  53. return result
  54. You want to test this function in its entirety without having to rely on a
  55. remote server whose content you cannot control, neither do you want to waste
  56. time setting up a complex mechanism to mock or patch the underlying Python
  57. modules dealing with the actual HTTP request (of which there are more than one
  58. BTW). So what do you do?
  59. You simply use pytest's `funcargs feature`_ and simulate an entire server
  60. locally! ::
  61. def test_retrieve_some_content(httpserver):
  62. httpserver.serve_content(open('cached-content.html').read())
  63. assert scrape(httpserver.url) == 'Found it!'
  64. What happened here is that for the duration of your tests an HTTP server is
  65. started on a random port on localhost which will serve the content you tell it
  66. to and behaves just like the real thing.
  67. The added bonus is that you can test whether your code behaves gracefully if
  68. there is a network problem::
  69. def test_content_retrieval_fails_graciously(httpserver):
  70. httpserver.serve_content('File not found!', 404)
  71. pytest.raises(ContentNotFoundException, scrape, httpserver.url)
  72. The same thing works for SMTP servers, too::
  73. def test_sending_some_message(smtpserver):
  74. mailer = MyMailer(host=smtpserver.addr[0], port=smtpserver.addr[1])
  75. mailer.send(to='bob@example.com', from_='alice@example.com',
  76. subject='MyMailer v1.0', body='Check out my mailer!')
  77. assert len(smtpserver.outbox)==1
  78. Here an SMTP server is started which accepts e-mails being sent to it. The
  79. nice feature here is that you can actually check if the message was received
  80. and what was sent by looking into the smtpserver's ``outbox``.
  81. It is really that easy!
  82. Available funcargs
  83. ==================
  84. Here is a short overview of the available funcargs. For more details I suggest
  85. poking around in the code itself.
  86. ``httpserver``
  87. provides a threaded HTTP server instance running on localhost. It has the
  88. following attributes:
  89. * ``code`` - HTTP response code (int)
  90. * ``content`` - content of next response (str)
  91. * ``headers`` - response headers (dict)
  92. Once these attribute are set, all subsequent requests will be answered with
  93. these values until they are changed or the server is stopped. A more
  94. convenient way to change these is ::
  95. httpserver.serve_content(content=None, code=200, headers=None)
  96. The server address can be found in property
  97. * ``url``
  98. which is the string representation of tuple ``server_address`` (host as str,
  99. port as int).
  100. If you want to check which form fields have been POSTed, Try ::
  101. httpserver.serve_content(..., show_post_vars=True)
  102. which will display them as parsable text.
  103. If you need to inspect the requests sent to the server, a list of all
  104. received requests can be found in property
  105. * ``requests``
  106. which is a list of ``werkzeug.wrappers.Request`` objects.
  107. ``httpsserver``
  108. is the same as ``httpserver`` only with SSL encryption.
  109. ``smtpserver``
  110. provides a threaded instance of ``smtpd.SMTPServer`` runnning on localhost.
  111. It has the following attributes:
  112. * ``addr`` - server address as tuple (host as str, port as int)
  113. * ``outbox`` - list of ``email.message.Message`` instances received.
  114. Using your a WSGI application as test server
  115. ============================================
  116. As of version 0.3 you can now use a `WSGI application`_ to run on the test
  117. server ::
  118. from pytest_localserver.http import WSGIServer
  119. def simple_app(environ, start_response):
  120. """Simplest possible WSGI application"""
  121. status = '200 OK'
  122. response_headers = [('Content-type', 'text/plain')]
  123. start_response(status, response_headers)
  124. return ['Hello world!\n']
  125. @pytest.fixture
  126. def testserver(request):
  127. """Defines the testserver funcarg"""
  128. server = WSGIServer(application=simple_app)
  129. server.start()
  130. request.addfinalizer(server.stop)
  131. return server
  132. def test_retrieve_some_content(testserver):
  133. assert scrape(testserver.url) == 'Hello world!\n'
  134. Have a look at the following page for more information on WSGI:
  135. http://wsgi.readthedocs.org/en/latest/learn.html
  136. Download and Installation
  137. =========================
  138. You can install the plugin by running ::
  139. pip install pytest-localserver
  140. Alternatively, get the latest stable version from `PyPI`_ or the latest
  141. `bleeding-edge`_ from Github.
  142. License and Credits
  143. ===================
  144. This plugin is released under the MIT license. You can find the full text of
  145. the license in the LICENSE file.
  146. Copyright (C) 2010-2021 Sebastian Rahlf and others (see AUTHORS).
  147. Some parts of this package is based on ideas or code from other people:
  148. - I borrowed some implementation ideas for the httpserver from `linkchecker`_.
  149. - The implementation for the SMTP server is based on the `Mailsink recipe`_ by
  150. Adam Feuer, Matt Branthwaite and Troy Frever.
  151. - The HTTPS implementation is based on work by `Sebastien Martini`_.
  152. Thanks guys!
  153. Development and future plans
  154. ============================
  155. Feel free to clone the repository and add your own changes. Pull requests are
  156. always welcome!::
  157. git clone https://github.com/pytest-dev/pytest-localserver
  158. If you find any bugs, please file a `report`_.
  159. Test can be run with tox. Note that you need virtualenv<1.8 to run tests for
  160. Python 2.4.
  161. I already have a couple of ideas for future versions:
  162. * support for FTP, SSH (maybe base all on twisted?)
  163. * making the SMTP outbox as convenient to use as ``django.core.mail.outbox``
  164. * add your own here!
  165. ----
  166. .. [1] The idea for this project was born when I needed to check that `a piece
  167. of software`_ behaved itself when receiving HTTP error codes 404 and 500.
  168. Having unsuccessfully tried to mock a server, I stumbled across
  169. `linkchecker`_ which uses a the same idea to test its internals.
  170. .. _monkeypatching: http://pytest.org/latest/monkeypatch.html
  171. .. _pytest: http://pytest.org/
  172. .. _funcargs feature: http://pytest.org/latest/funcargs.html
  173. .. _linkchecker: http://linkchecker.sourceforge.net/
  174. .. _WSGI application: http://www.python.org/dev/peps/pep-0333/
  175. .. _PyPI: http://pypi.python.org/pypi/pytest-localserver/
  176. .. _bleeding-edge: https://github.com/pytest-dev/pytest-localserver
  177. .. _report: https://github.com/pytest-dev/pytest-localserver/issues/
  178. .. _tox: http://testrun.org/tox/
  179. .. _a piece of software: http://pypi.python.org/pypi/python-amazon-product-api/
  180. .. _Mailsink recipe: http://code.activestate.com/recipes/440690/
  181. .. _Sebastien Martini: http://code.activestate.com/recipes/442473/