Skip to content

Commit 4e38ead

Browse files
committed
Merge pull request #6 from pytest-dev/test-methods
Add support for test methods
2 parents 3fe4ef6 + f11bd95 commit 4e38ead

File tree

2 files changed

+37
-30
lines changed

2 files changed

+37
-30
lines changed

pytest_asyncio/plugin.py

+25-29
Original file line numberDiff line numberDiff line change
@@ -27,40 +27,36 @@ def pytest_pycollect_makeitem(collector, name, obj):
2727
return list(collector._genfunctions(name, obj))
2828

2929

30-
def _argnames(func):
31-
spec = inspect.getfullargspec(func)
32-
if spec.defaults:
33-
return spec.args[:-len(spec.defaults)]
34-
return spec.args
35-
36-
3730
@pytest.mark.tryfirst
3831
def pytest_pyfunc_call(pyfuncitem):
39-
"""A hook wrapper."""
40-
if 'asyncio_process_pool' in pyfuncitem.keywords:
41-
event_loop = pyfuncitem.funcargs.get('event_loop_process_pool')
42-
funcargs = dict((arg, pyfuncitem.funcargs[arg])
43-
for arg in _argnames(pyfuncitem.obj))
44-
event_loop.run_until_complete(asyncio.async(pyfuncitem.obj(**funcargs)))
45-
# prevent other pyfunc calls from executing
46-
return True
47-
elif 'asyncio' in pyfuncitem.keywords:
48-
event_loop = pyfuncitem.funcargs.get('event_loop')
49-
funcargs = dict((arg, pyfuncitem.funcargs[arg])
50-
for arg in _argnames(pyfuncitem.obj))
51-
event_loop.run_until_complete(asyncio.async(pyfuncitem.obj(**funcargs)))
52-
# prevent other pyfunc calls from executing
53-
return True
32+
"""
33+
Run asyncio marked test functions in an event loop instead of a normal
34+
function call.
35+
"""
36+
for marker_name, fixture_name in _markers_2_fixtures.items():
37+
if marker_name in pyfuncitem.keywords:
38+
event_loop = pyfuncitem.funcargs[fixture_name]
39+
funcargs = pyfuncitem.funcargs
40+
testargs = {arg: funcargs[arg]
41+
for arg in pyfuncitem._fixtureinfo.argnames}
42+
event_loop.run_until_complete(
43+
asyncio.async(pyfuncitem.obj(**testargs)))
44+
return True
5445

5546

5647
def pytest_runtest_setup(item):
57-
if 'asyncio' in item.keywords and 'event_loop' not in item.fixturenames:
58-
# inject an event loop fixture for all async tests
59-
item.fixturenames.append('event_loop')
60-
61-
if ('asyncio_process_pool' in item.keywords and
62-
'event_loop_process_pool' not in item.fixturenames):
63-
item.fixturenames.append('event_loop_process_pool')
48+
for marker, fixture in _markers_2_fixtures.items():
49+
if marker in item.keywords and fixture not in item.fixturenames:
50+
# inject an event loop fixture for all async tests
51+
item.fixturenames.append(fixture)
52+
53+
54+
# maps marker to the name of the event loop fixture that will be available
55+
# to marked test functions
56+
_markers_2_fixtures = {
57+
'asyncio': 'event_loop',
58+
'asyncio_process_pool': 'event_loop_process_pool',
59+
}
6460

6561

6662
@pytest.fixture

tests/test_simple.py

+12-1
Original file line numberDiff line numberDiff line change
@@ -87,4 +87,15 @@ def closer(_, writer):
8787
port=unused_tcp_port)
8888

8989
server1.close()
90-
yield from server1.wait_closed()
90+
yield from server1.wait_closed()
91+
92+
93+
class Test:
94+
"""Test that asyncio marked functions work in test methods."""
95+
96+
@pytest.mark.asyncio
97+
def test_asyncio_marker_method(self):
98+
"""Test the asyncio pytest marker in a Test class."""
99+
url = 'http://httpbin.org/get'
100+
resp = yield from simple_http_client(url)
101+
assert b'HTTP/1.1 200 OK' in resp

0 commit comments

Comments
 (0)