Given json file:
["smtp.gmail.com", "mail.python.org"]
You may simply load it to Python object and pass that object to decorator.
import json
import pytest
import smtplib
def load_params_from_json(json_path):
with open(json_path) as f:
return json.load(f)
@pytest.fixture(scope = "module", params = load_params_from_json('path/to/file.json'))
def smtp(request):
smtp = smtplib.SMTP(request.param)
def fin():
print("finalizing %s" % smtp)
smtp.close()
request.addfinalizer(fin)
return smtp
Thanks, I ended up using pytest-generate-tests for this, my json path will be changed depending on the test case.
# test_foo.py
def test_foo(param)
# conftest.py
def pytest_generate_tests(metafunc):
... my <same_name_as_test>.json
... get info from metafunc.module
with open(param_full_path,'r') as f:
obj = json.load(f)
metafunc.parametrize("param", obj)
Parametrizing fixtures and test functions,@pytest.mark.parametrize: parametrizing test functions,pytest.fixture() allows one to parametrize fixture functions.,@pytest.mark.parametrize allows one to define multiple sets of arguments and fixtures at the test function or class.
# content of test_expectation.py
import pytest
@pytest.mark.parametrize("test_input,expected", [("3+5", 8), ("2+4", 6), ("6*9", 42)])
def test_eval(test_input, expected):
assert eval(test_input) == expected
$ pytest
===
=== === === === === === === === test session starts === === === === === === === === === =
platform linux--Python 3. x.y, pytest - 6. x.y, py - 1. x.y, pluggy - 1. x.y
cachedir: $PYTHON_PREFIX / .pytest_cache
rootdir: $REGENDOC_TMPDIR
collected 3 items
test_expectation.py..F[100 % ]
===
=== === === === === === === === === === FAILURES === === === === === === === === === === ===
____________________________ test_eval[6 * 9 - 42] _____________________________
test_input = '6*9', expected = 42
@pytest.mark.parametrize("test_input,expected", [("3+5", 8), ("2+4", 6), ("6*9", 42)])
def test_eval(test_input, expected):
>
assert eval(test_input) == expected
E AssertionError: assert 54 == 42
E + where 54 = eval('6*9')
test_expectation.py: 6: AssertionError ===
=== === === === === === === = short test summary info === === === === === === === === ==
FAILED test_expectation.py::test_eval[6 * 9 - 42] - AssertionError: assert 54... ===
=== === === === === === == 1 failed, 2 passed in 0.12 s === === === === === === === ===
[pytest] disable_test_id_escaping_and_forfeit_all_rights_to_community_support = True
# content of test_expectation.py
import pytest
@pytest.mark.parametrize(
"test_input,expected",
[("3+5", 8), ("2+4", 6), pytest.param("6*9", 42, marks = pytest.mark.xfail)],
)
def test_eval(test_input, expected):
assert eval(test_input) == expected
$ pytest === === === === === === === === === test session starts === === === === === === === === === = platform linux--Python 3. x.y, pytest - 6. x.y, py - 1. x.y, pluggy - 1. x.y cachedir: $PYTHON_PREFIX / .pytest_cache rootdir: $REGENDOC_TMPDIR collected 3 items test_expectation.py..x[100 % ] === === === === === === === == 2 passed, 1 xfailed in 0.12 s === === === === === === === ==
import pytest
@pytest.mark.parametrize("x", [0, 1])
@pytest.mark.parametrize("y", [2, 3])
def test_foo(x, y):
pass
Using pytest fixtures and providing the fixture name to pytest.mark.parametrize (original issue description),atm parametrize cannot figure it, and it shouldnt figure it there will be a new object to declare a parameter will request a fixture/fixture with parameters,atm parametrize cannot figure it, and it shouldnt figure it there will be a new object to declare a parameter will request a fixture/fixture with parameters,Calling the fixture function in pytest.mark.parametrize (won’t work for fixtures that call other fixtures)
I often have a use case like the following contrived example:
@pytest.fixture
def a():
return 'a'
@pytest.fixture
def b():
return 'b'
@pytest.mark.parametrize('arg', [a, b])
def test_foo(arg):
assert len(arg) == 1
I can work around it by introducing a “meta fixture”, but that’s rather ugly:
@pytest.fixture(params = ['a', 'b'])
def arg(request, a, b):
return {
'a': a,
'b': b
} [request.param]
def test_foo(arg):
assert len(arg) == 1
+1 for this feature. BTW, combining Florian Rathgeber and Matthias Geier solutions we can get a bit nicer “meta fixture”:
@pytest.fixture
def a():
return 'a'
@pytest.fixture
def b():
return 'b'
@pytest.fixture(params = ['a', 'b'])
def arg(request):
return request.getfuncargvalue(request.param)
def test_foo(arg):
assert len(arg) == 1
I can use fixtures as arguments in parametrize using the getfixture
fixture that returns a function that calls another fixture:
import pytest
@pytest.fixture
def a():
return 'a123'
@pytest.fixture
def b():
return 'b321'
@pytest.fixture
def getfixture(request):
def _getfixture(name):
return request.getfixturevalue(name)
return _getfixture
@pytest.mark.parametrize(
'_fixture, expect', [
pytest.param('a', 'a123'),
pytest.param('b', 'b321'),
]
)
def test_foo(getfixture, _fixture, expected):
assert getfixture(_fixture) == expected
It would also be killer if this supported parameterized fixtures generating the product of the fixtures. Although this might be a little much.
@pytest.fixture(params = ["1", " ", 1, True, [None], {
1: 2
}])
def truthy(request):
return request.param
@pytest.fixture(params = [False, None, "", 0, [], {}])
def falsey(request):
return request.param
@pytest.mark.parameterize("val,res", [
(truthy, True),
(falsey, False),
])
def test_bool(val, res)
assert bool(val) is res
Another alternative to the above example is to directly call these functions in the list.
#!python
@pytest.mark.parametrize('arg', [a(), b()])
def test_foo(arg):
assert len(arg) == 1
Something like this?
import pytest
@pytest.fixture
def fixture1():
return 1
@pytest.fixture
def fixture2():
return 2
@pytest.fixture
def x(request):
return request.getfixturevalue(request.param)
@pytest.mark.parametrize('x', ['fixture1', 'fixture2'], indirect = ['x'])
def test_indirect(x):
assert 0 < x < 3
Strict key checking can be controlled individually for the response for the JSON body,the redirect query parameter, or the headers.,If our test function extracts the key name from the response body (note as above that this function should take the response object as the first argument):,The save block can save values from the response for use in future requests. Things can be saved from the body, headers, or redirect query parameters. When used to save something from the json body, this can also access dictionaries and lists recursively. If the response is:,json:off headers:on - turn off for the body, but on for the headers. redirect_query_params will stay default off.
test_name: Get some fake data from the JSON placeholder API
stages:
-name: Make sure we have the right ID
request:
url: https: //jsonplaceholder.typicode.com/posts/1
method: GET
response:
status_code: 200
json:
id: 1
userId: 1
title: "sunt aut facere repellat provident occaecati excepturi optio reprehenderit"
body: "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
save:
json:
returned_id: id
tests / integration / test_simple.tavern.yaml::Get some fake data from the JSON placeholder API
{
"thing": {
"nested": [
1, 2, 3, 4
]
}
}
response:
save:
json:
first_val: "thing.nested[0]"
response:
save:
json:
nested_thing: "thing"
request:
json:
variable_key: "{key_name:s}"
# or
# variable_key: "{key_name}"