pytest is the most popular Python test framework. Tests are plain functions named test_* using the assert statement; pytest auto-discovers them and gives rich failure output.
You write def test_login(): assert result == expected in a file named test_*.py or *_test.py, and run pytest. No boilerplate class or special assert methods are required — pytest rewrites plain assert to show detailed diffs on failure. Useful flags: -v (verbose), -k 'expr' (select by name), -m marker (by marker), -x (stop on first failure), --maxfail, and -s (show prints). pytest integrates fixtures, parametrization, plugins (pytest-html, pytest-xdist for parallelism), and works with Selenium/requests. Its low ceremony makes it the default choice for test automation in Python.
A quick API check: def test_status(): assert requests.get(url).status_code == 200 — pytest discovers and runs it, and on failure shows the actual status code inline.
Why can pytest use a plain assert while unittest needs self.assertEqual?