Skip to content

Commit 853b896

Browse files
authored
Merge pull request #105 from alissa-huskey/master
Update README to provide more clear examples
2 parents 2205798 + 6ab38e2 commit 853b896

File tree

1 file changed

+103
-41
lines changed

1 file changed

+103
-41
lines changed

README.rst

+103-41
Original file line numberDiff line numberDiff line change
@@ -29,46 +29,89 @@ no further!
2929
Quickstart
3030
==========
3131

32+
`myproject.py`
33+
34+
.. code:: python
35+
36+
import requests
37+
38+
39+
def make_request(url):
40+
"""A function that makes a web request."""
41+
rsp = requests.get(url)
42+
return rsp.text
43+
44+
`test_myproject.py`
45+
46+
.. code:: python
47+
48+
from myproject import request
49+
50+
51+
def test_make_request(httpserver):
52+
httpserver.serve_content(
53+
content="success",
54+
code=200,
55+
)
56+
57+
assert make_request(httpserver.url) == "success"
58+
59+
How-To
60+
======
61+
3262
Let's say you have a function to scrape HTML which only required to be pointed
33-
at a URL ::
63+
at a URL :
64+
65+
.. code:: python
3466
3567
import requests
68+
3669
def scrape(url):
37-
html = requests.get(url).text
38-
# some parsing happens here
39-
# ...
40-
return result
70+
html = requests.get(url).text
71+
# some parsing happens here
72+
# ...
73+
return result
4174
4275
You want to test this function in its entirety without having to rely on a
4376
remote server whose content you cannot control, neither do you want to waste
4477
time setting up a complex mechanism to mock or patch the underlying Python
4578
modules dealing with the actual HTTP request (of which there are more than one
4679
BTW). So what do you do?
4780

48-
You simply use pytest's `funcargs feature`_ and simulate an entire server
49-
locally! ::
81+
You simply use pytest's `fixture feature`_ and simulate an entire server
82+
locally!
83+
84+
.. code:: python
5085
5186
def test_retrieve_some_content(httpserver):
52-
httpserver.serve_content(open('cached-content.html').read())
53-
assert scrape(httpserver.url) == 'Found it!'
87+
httpserver.serve_content(open("cached-content.html").read())
88+
assert scrape(httpserver.url) == "Found it!"
5489
5590
What happened here is that for the duration of your tests an HTTP server is
5691
started on a random port on localhost which will serve the content you tell it
5792
to and behaves just like the real thing.
5893

5994
The added bonus is that you can test whether your code behaves gracefully if
60-
there is a network problem::
95+
there is a network problem:
96+
97+
.. code:: python
6198
62-
def test_content_retrieval_fails_graciously(httpserver):
63-
httpserver.serve_content('File not found!', 404)
64-
pytest.raises(ContentNotFoundException, scrape, httpserver.url)
99+
def test_content_retrieval_fails_graciously(httpserver):
100+
httpserver.serve_content("File not found!", 404)
101+
pytest.raises(ContentNotFoundException, scrape, httpserver.url)
65102
66-
The same thing works for SMTP servers, too::
103+
The same thing works for SMTP servers, too:
104+
105+
.. code:: python
67106
68107
def test_sending_some_message(smtpserver):
69108
mailer = MyMailer(host=smtpserver.addr[0], port=smtpserver.addr[1])
70-
mailer.send(to='[email protected]', from_='[email protected]',
71-
subject='MyMailer v1.0', body='Check out my mailer!')
109+
mailer.send(
110+
111+
112+
subject="MyMailer v1.0",
113+
body="Check out my mailer!"
114+
)
72115
assert len(smtpserver.outbox)==1
73116
74117
Here an SMTP server is started which accepts e-mails being sent to it. The
@@ -77,11 +120,12 @@ and what was sent by looking into the smtpserver's ``outbox``.
77120

78121
It is really that easy!
79122

80-
Available funcargs
81-
==================
123+
Fixtures
124+
========
82125

83-
Here is a short overview of the available funcargs. For more details I suggest
84-
poking around in the code itself.
126+
Here is a short overview of the available pytest fixtures and their usage. This
127+
information is also available via `pytest --fixtures`. For more details I
128+
suggest poking around in the code itself.
85129

86130
``httpserver``
87131
provides a threaded HTTP server instance running on localhost. It has the
@@ -95,9 +139,17 @@ poking around in the code itself.
95139

96140
Once these attributes are set, all subsequent requests will be answered with
97141
these values until they are changed or the server is stopped. A more
98-
convenient way to change these is ::
142+
convenient way to change these is :
143+
144+
.. code:: python
99145
100-
httpserver.serve_content(content=None, code=200, headers=None, chunked=pytest_localserver.http.Chunked.NO, store_request_data=True)
146+
httpserver.serve_content(
147+
content=None,
148+
code=200,
149+
headers=None,
150+
chunked=pytest_localserver.http.Chunked.NO,
151+
store_request_data=True
152+
)
101153
102154
The ``chunked`` attribute or parameter can be set to
103155

@@ -149,27 +201,37 @@ Using your a WSGI application as test server
149201
============================================
150202

151203
As of version 0.3 you can now use a `WSGI application`_ to run on the test
152-
server ::
204+
server :
205+
206+
.. code:: python
207+
208+
import pytest
209+
from pytest_localserver.http import WSGIServer
210+
211+
from myproject import make_request
212+
213+
214+
def simple_app(environ, start_response):
215+
"""Respond with success."""
216+
status = "200 OK"
217+
response_headers = [("Content-type", "text/plain")]
218+
start_response(status, response_headers)
219+
return ["success".encode("utf-8")]
220+
153221
154-
from pytest_localserver.http import WSGIServer
222+
@pytest.fixture
223+
def testserver():
224+
"""Server for simple_app."""
225+
server = WSGIServer(application=simple_app)
226+
server.start()
227+
yield server
228+
server.stop()
155229
156-
def simple_app(environ, start_response):
157-
"""Simplest possible WSGI application"""
158-
status = '200 OK'
159-
response_headers = [('Content-type', 'text/plain')]
160-
start_response(status, response_headers)
161-
return ['Hello world!\n']
162230
163-
@pytest.fixture
164-
def testserver(request):
165-
"""Defines the testserver funcarg"""
166-
server = WSGIServer(application=simple_app)
167-
server.start()
168-
request.addfinalizer(server.stop)
169-
return server
231+
def test_make_request(testserver):
232+
"""make_request() should return "success"."""
233+
assert make_request(testserver.url) == "success"
170234
171-
def test_retrieve_some_content(testserver):
172-
assert scrape(testserver.url) == 'Hello world!\n'
173235
174236
Have a look at the following page for more information on WSGI:
175237
http://wsgi.readthedocs.org/en/latest/learn.html
@@ -253,9 +315,9 @@ For package maintainers, here is how we release a new version:
253315
Having unsuccessfully tried to mock a server, I stumbled across
254316
`linkchecker`_ which uses a the same idea to test its internals.
255317
256-
.. _monkeypatching: http://pytest.org/latest/monkeypatch.html
318+
.. _monkeypatching: https://docs.pytest.org/en/stable/how-to/monkeypatch.html
257319
.. _pytest: http://pytest.org/
258-
.. _funcargs feature: http://pytest.org/latest/funcargs.html
320+
.. _fixture feature: https://pytest.org/en/stable/explanation/fixtures.html
259321
.. _linkchecker: http://linkchecker.sourceforge.net/
260322
.. _WSGI application: http://www.python.org/dev/peps/pep-0333/
261323
.. _PyPI: http://pypi.python.org/pypi/pytest-localserver/

0 commit comments

Comments
 (0)