Reputation: 10984
As its document says, pytest accepts fixtures as function arguments. However, this somewhat contradicts the convention in almost all languages that parameter names shouldn't affect a function's behavior. For example:
This works:
import pytest
@pytest.fixture()
def name():
return 'foo'
def test_me(name):
assert name == 'foo'
But this doesn't:
import pytest
@pytest.fixture()
def name():
return 'foo'
def test_me(nam):
assert nam == 'foo'
I think there must be some introspection here which requires testing function parameters to be valid fixtures. Am I correct on this?
Besides fixtures, there are other magic parameter names that confused me. One of them is request
:
import pytest
@pytest.fixture(params=['foo', 'bar'])
def name(request):
return request.param
def test_me(name):
assert name == 'foo'
Without reading its doc, it might seem you can rename request
to another name such as req
:
import pytest
@pytest.fixture(params=['foo', 'bar'])
def name(req):
return req.param
def test_me(name):
assert name == 'foo'
But then running the test will complain fixture req
not found. It further confused me because the listed available fixtures didn't include request
. I'm not sure it's proper to call request
a fixture here, but the error message is contradicting itself:
E fixture 'req' not found
> available fixtures: cache, capfd, capfdbinary, caplog, capsys, capsysbinary, doctest_namespace, monkeypatch, name, pytestconfig, record_xml_attribute, record_xml_property, recwarn, tmpdir, tmpdir_factory, worker_id
> use 'pytest --fixtures [testpath]' for help on them.
So how many magic names like this I must take care of when using pytest to not get into a pitfall?
Upvotes: 4
Views: 3703
Reputation: 169338
Yup, Py.test injects a little bit of argument-name introspection magic to keep your test cases concise.
Aside from any fixtures you have available (as you found out with pytest --fixtures
), I do think request
is the only additional magic parameter (unless, of course, you use, say, @pytest.mark.parametrize('foo', (...))
, in which case foo
is a magic parameter for that marked test case or fixture, etc.).
As an aside, I think it's best not to think about Py.test test_
functions as regular old functions anyway, as they're not directly called as such by Py.test.
Upvotes: 5