Skip to content

Commit 123948e

Browse files
committed
update python pytest
1 parent abfb441 commit 123948e

File tree

1 file changed

+84
-8
lines changed

1 file changed

+84
-8
lines changed

docs/posts/2021/2021-06-12-python-unittest-cheat-sheet.md

Lines changed: 84 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ categories:
77
comments: true
88
date:
99
created: 2021-06-12
10-
updated: 2025-02-21
10+
updated: 2025-02-27
1111
description: ''
1212
---
1313

@@ -55,6 +55,13 @@ addopts = """
5555
env = ["TESTING=yes"]
5656
```
5757

58+
## Bypass default config
59+
60+
Normally pytest will discover config in `pyproject.toml` or `pytest.ini`, if you want to bypass these settings you can:
61+
62+
- Bypass all the settings by pointing to a null config file: `pytest -c /dev/null...`
63+
- Bypass specific settings (for .e.g `addopts` and `testpaths`): `pytest -o addopts='' -o testpaths='tests'`
64+
5865
## asyncio support
5966

6067
- <https://github.com/ETretyakov/hero-app/blob/master/app/conftest.py>
@@ -139,7 +146,7 @@ addopts = """
139146
"""
140147
```
141148

142-
PS: an alternatif: `pdbpp` (successor of `pytest-ipdb`) at: https://github.com/pdbpp/pdbpp
149+
PS: an alternatif: `pdbpp` (successor of `pytest-ipdb`) at: <https://github.com/pdbpp/pdbpp>
143150

144151
## export PYTHONBREAKPOINT=ipdb.set_trace
145152

@@ -235,6 +242,75 @@ pytest -k "not send_http" -v
235242
pytest -k "send_http or quick" -v
236243
```
237244

245+
## pytest -s
246+
247+
pytest captures stdout/stderr (including print) by default, and only shows that captured output when it's useful, usually on failures.
248+
249+
For e.g.,by default, we will only see the ouput of `setting up <function test_func2 at 0x785a4a11c180>` for `test_func2` only, not `test_func1`, even the print statement is in the setup_function, which is shared by both `test_func1` and `test_func2`. But with `pytest -s`, we will see the output for both tests.
250+
251+
So by default, without `-s` (same for `--capture=no`), print() output is hidden unless pytest decides to show it (typically for failing tests).
252+
253+
```python
254+
# content of test_module.py
255+
256+
def setup_function(function):
257+
print("setting up", function)
258+
259+
def test_func1():
260+
assert True
261+
262+
def test_func2():
263+
assert False
264+
```
265+
266+
Without `-s`, which is the defaut Pytest capture mode, all the print outputs are caapptured by Pytest, and is only displayed for the failed test `test_func2` (lines 16-17):
267+
268+
```bash title="pytest without -s" hl_lines="16-17" linenums="1"
269+
> pytest test_module.py
270+
271+
collected 2 items
272+
273+
test_module.py .F [100%]
274+
275+
===================== FAILURES =====================
276+
_____________________ test_func2 ___________________
277+
278+
def test_func2():
279+
> assert False
280+
E assert False
281+
282+
test_module.py:10: AssertionError
283+
------------------ Captured stdout setup -----------
284+
setting up <function test_func2 at 0x7d7ba8b38180>
285+
============= short test summary info ==============
286+
FAILED test_module.py::test_func2 - assert False
287+
=========== 1 failed, 1 passed in 0.21s ===
288+
```
289+
290+
With `-s` print on both func1 and func2 are displayed (lines 5,-), as Pytest capture is disabled:
291+
292+
```bash title="pytest -s" hl_lines="5-6" linenums="1"
293+
> pytest test_module.py -s
294+
295+
collected 2 items
296+
297+
test_module.py setting up <function test_func1 at 0x781fbcc1c0e0>
298+
.setting up <function test_func2 at 0x781fbcc1c180>
299+
F
300+
301+
===================== FAILURES =====================
302+
_____________________ test_func2 ___________________
303+
304+
def test_func2():
305+
> assert False
306+
E assert False
307+
308+
test_module.py:10: AssertionError
309+
============= short test summary info ==============
310+
FAILED test_module.py::test_func2 - assert False
311+
=========== 1 failed, 1 passed in 0.16s ============
312+
```
313+
238314
## Failfast
239315

240316
<https://docs.pytest.org/en/stable/how-to/failures.html#stopping-after-the-first-or-n-failures>
@@ -404,9 +480,9 @@ def test_class_inventory_item():
404480

405481
### Monkeypatching functions or the property of a class
406482

407-
https://docs.pytest.org/en/stable/monkeypatch.html#simple-example-monkeypatching-functions
483+
<https://docs.pytest.org/en/stable/monkeypatch.html#simple-example-monkeypatching-functions>
408484

409-
Very similar to Python standard lib `unittest.mock.patch` decorator since Python 3, but `monkeypatch` is a fixture. Some people find `monkeypatch` is less effort to write than `unittest.mock.patch`. Ref. https://github.com/pytest-dev/pytest/issues/4576
485+
Very similar to Python standard lib `unittest.mock.patch` decorator since Python 3, but `monkeypatch` is a fixture. Some people find `monkeypatch` is less effort to write than `unittest.mock.patch`. Ref. <https://github.com/pytest-dev/pytest/issues/4576>
410486

411487
To use the native `unittest.mock.patch`, use the [`wraps` parameter](https://stackoverflow.com/a/59460964/5095636):
412488

@@ -583,7 +659,7 @@ pytest -n auto
583659

584660
## Ensure each pytest-xdist worker has its own database connection
585661

586-
Based on `worker_id` fixture, possible values are: `gw0`, `gw1`, etc., and `master` if no parallel fixture: https://breadcrumbscollector.tech/posts/running-tests-in-parallel-with-pytest/#worker_id-fixture
662+
Based on `worker_id` fixture, possible values are: `gw0`, `gw1`, etc., and `master` if no parallel fixture: <https://breadcrumbscollector.tech/posts/running-tests-in-parallel-with-pytest/#worker_id-fixture>
587663

588664
## Showing the tests durations
589665

@@ -616,7 +692,7 @@ mock.patch returns a mock object, a mock object can have whatever attributes and
616692
# using simple speccing, mock.asssert_called_with() is detected as an error
617693
>>> mock = Mock(spec=request.Request)
618694
>>> mock.asssert_called_with()
619-
---------------------------------------------------------------------------
695+
------------
620696
AttributeError Traceback (most recent call last)
621697
...
622698
AttributeError: Mock object has no attribute 'asssert_called_with'
@@ -761,7 +837,7 @@ def test_bar(fix_w_yield1, fix_w_yield2):
761837

762838
```bash title="pytest output"
763839
$ pytest demo_pytest.py
764-
============= test session starts ===========================
840+
============= test session starts ==
765841
platform linux -- Python 3.10.15, pytest-7.4.4, pluggy-1.5.0
766842
rootdir: /home/xiang/git/demo
767843
plugins: xdist-3.6.1, cov-3.0.0
@@ -776,7 +852,7 @@ test_bar
776852
.after_yield_2
777853
after_yield_1
778854

779-
============== 1 passed in 0.01s ===========================
855+
============== 1 passed in 0.01s ==
780856
```
781857

782858
### Safe teardowns

0 commit comments

Comments
 (0)