Module 1 · Python for SDETs

pytest
Fundamentals

How tests are found, why plain assert is enough, and running exactly what you want

discovery assert -k / -x raises / approx
AI with Rufat
What pytest collects
# tests/test_demo.py
def test_this_runs():
def helper_not_a_test():
class TestProducts:
def test_inside(self):
📄

Files

test_*.py or *_test.py

🔧

Functions

start with test_

📦

Classes

start with Test (no __init__)

💡Off-pattern names are skipped silently — the #1 "why did no tests run?"
AI with Rufat
Plain assert — and a readable failure
tests/test_failure_demo.py
# line 1
def test_intentional_failure():
expected = 5
actual = 2 + 2
assert actual == expected
pytest output
python-sdet
> assert actual == expected
E assert 4 == 5
test_failure_demo.py:5: AssertionError
pytest rewrites assert to show both sides — no special methods.
AI with Rufat
The everyday flags

Run exactly the tests you want

pytest -vone line per test
pytest -qquiet, compact output
pytest -xstop at first failure
pytest -k "expr"filter by name (and/or/not)
pytest file.py::test_xrun one specific test
🔁The everyday debug loop: pytest -x -k "the_thing_im_fixing"
AI with Rufat
Two helpers you'll reach for
pytest.raises — expect an error
with pytest.raises(ValueError):
int("not a number")
Passes only if the block raises that error — how you verify invalid input is rejected.
pytest.approx — compare floats
assert 0.1 + 0.2 == pytest.approx(0.3)
# plain == 0.3 would FAIL
Floating-point math is inexact — never compare computed prices or totals with bare ==.
AI with Rufat

pytest,
in your hands

Find tests, read failures, run exactly what you want

➡️
Module 2
Fixtures & parametrize — share setup, run one test over many inputs
🧪
Practice
Write real product-API checks against TestMarket Lab
🔁
Debug loop
pytest -x -k "name" — stop fast, focus tight
AI with Rufat
← / → · space