Académique Documents
Professionnel Documents
Culture Documents
test
def
test_answer():
assert
func(3)
==
5
#
content
of
test_sysexit.py
import
pytest
def
f():
raise
SystemExit(1)
!
def
test_mytest():
with
pytest.raises(SystemExit):
f()
class
TestClass:
def
test_one(self):
x
=
"this"
assert
'h'
in
x
!
def
test_two(self):
x
=
"hello"
assert
hasattr(x,
'check')
How to run cases?
• py.test tests/test_mod.py
• py.test tests/
• py.test -k match # def test_match():
How to run cases?
• py.test --showlocals # trace context
• py.test -x # stop on first failure case
• py.test --maxfail=2 # on the second
• py.test -s # enable `print` output
• py.test --durations=10 # list top10 slowest
cases
How to run cases?
import
pytest
def
test_function():
...
pytest.set_trace()
py.test -h
What to test?
• folder, file.
• recursive
• test_xxx.py, xxx_test.py
• TestClass (without __init__ method)
• all the function or method with prefix `test_`
What to test?
#
setup.cfg
/
tox.ini
/
pytest.ini
[pytest]
python_files=check_*.py
python_classes=Check
python_functions=check
What to test?
#
content
of
check_myapp.py
class
CheckMyApp:
def
check_simple(self):
pass
def
check_complex(self):
pass
Basic configuration
INI-style
• pytest.ini
• tox.ini
• setup.cfg
Basic configuration
Path
• Current dir
• Parent dir
• ...
Basic configuration
#
content
of
pytest.ini
#
(or
tox.ini
or
setup.cfg)
[pytest]
addopts
=
-‐-‐tb=short
-‐x
• assert expr
• assert a == b
• self.assertEqual(a, b)
• assert expr, “Expected message”
• pytest.raises
Assertions
• Why `assert`?
• simple
• nice output
• http://pytest.org/latest/example/
reportingdemo.html
Assertions
Define Own Comparison
Lesson 4
Assertions
Define Own Comparison
def
test_compare():
assert
Foo(1)
==
Foo(2)
@pytest.fixture
def
bookmark(app):
return
Bookmark.create(
user_id=1,
works_id=1)
Fixtures as func args
def
test_get_by_relation(bookmark):
bookmarks
=
Bookmark.get(
user_id=1,
works_id=1
)
assert
bookmarks
assert
bookmarks[0].id
==
bookmark.id
Lesson 01
Fixtures as func args
@pytest.fixture(scope="module")
def
smtp():
return
smtplib.SMTP("dou.bz")
Fixtures - finalization
@pytest.fixture(scope="session")
def
database(request):
db_name
=
"{}.db".format(time())
deferred_db.init(db_name)
def
finalizer():
if
os.path.exists(db_name):
os.remove(db_name)
request.addfinalizer(finalizer)
return
deferred_db
Lesson 2
Fixtures - parametrizing
@pytest.fixture(params=[
'/',
'/reader/',
])
def
signed_page(request):
return
requests.get(request.param)
!
def
test_fetch_pages_success_in_signed(signed_page):
assert
signed_page.status_code
<
300
Lesson 3.1
Fixtures - modular
class
App(object):
!
def
__init__(self,
request):
self.request
=
request
!
@pytest.fixture
def
app(request,
mc_logger,
db_logger
):
return
App(request)
Fixtures - autouse
class
TestClass:
@pytest.fixture(autouse=True)
def
table(self,
database):
Table.create_table()
!
def
test_select(self):
assert
not
Table.get(id=1)
Fixtures - autouse
@pytest.fixture
def
table(request,
database):
Table.create_table()
request.addfinilizer(
Table.drop_table)
!
@pytest.mark.usefixtures('table')
class
TestClass:
def
test_select(self):
assert
not
Table.get(id=1)
Fixtures - parametrizing
@pytest.mark.parametrize(
"input,expected",
[
("3+5",
8),
("2+4",
6),
("6*9",
42),
pytest.mark.xfail(("6*9",
42))
])
def
test_eval(input,
expected):
assert
eval(input)
==
expected
Lesson 3.2
Fixtures - parametrizing
#
conftest.py
import
pytest
!
def
pytest_generate_tests(metafunc):
if
'payload'
in
metafunc.fixturenames:
metafunc.parametrize('payload',
['/tmp/test.json',
])
!
#
test
file
def
test_meta(payload):
assert
payload
==
'/tmp/test.json'
...
Fixtures - xUnit
def
setup_function(function):
print
'setup'
def
teardown_function(function):
print
'teardown'
def
test_func():
print
'func'
!
#
==>
"""
setup
func
teardown
"""
Fixtures - xUnit
class
TestBookmark:
def
setup_method(self,
method):
print
'setup'
def
teardown_method(self,
method):
print
'teardown'
def
test_method(self):
print
'method'
!
#
==>
"""
setup
method
teardown
"""
Fixtures - xUnit
• setup_module / teardown_module
• setup_class / teardown_class
• setup_method / teardown_method
• setup_function / teardown_function
Fixtures - builtin
import
datetime
import
pytest
!
FAKE_TIME
=
datetime.datetime(2020,
12,
25,
17,
05,
55)
!
@pytest.fixture
def
patch_datetime_now(monkeypatch):
!
class
mydatetime:
@classmethod
def
now(cls):
return
FAKE_TIME
!
monkeypatch.setattr(datetime,
'datetime',
mydatetime)
!
!
def
test_patch_datetime(patch_datetime_now):
assert
datetime.datetime.now()
==
FAKE_TIME
Fixtures - builtin
• monkeypatch
• tmpdir
• capsys / capfd
• `py.test --fixture`
Maker
• pytest.marker
• py.test --marker
• marker is like tag.
• @pytest.mark.skipif(getenv('qaci'))
• @pytest.mark.xfail('oooops')
• @pytest.mark.skipif("config.getvalue('pass')")
• @pytest.mark.ask_sunyi
!
unittest.TestCase
• Compatible
• But be careful. There is no funcargs
mechanism for unittest cases.
Plugin
• py.test supply many hooks.
• collection / configuration / run / output
• Basic types:
• builtin
• 3-party plugins
• conftest.py plugins
Plugin - find conftest.py
• recursive
• `import conftest` X
Plugin - 3-party
• http://pytest.org/latest/plugins.html#hook-
specification-and-validation
• see source.
Plugin - example
#
content
of
suites.isolated_cases
def
pytest_addoption(parser):
group
=
parser.getgroup("isolated_cases",
"")
group._addoption(
'-‐-‐with-‐data-‐service',
action="store_true",
default=False,
dest='with_data_service',
help=(
"with
MySQL/beansdb/memcached
up
at
the
beginning
of
session"
"and
down
at
the
end
of
session."
)
)
Plugin - example
#
content
of
isolated_cases
def
pytest_configure(config):
if
config.option.with_data_service:
build_tables()
stop_kvstore()
sleep(1)
start_kvstore()