๐ Module 1: Introduction to Pytest (Deep Dive)
- What is Pytest? Why is it preferred over unittest and nose?
- Understanding Pytest architecture & internal test discovery mechanism
- Installation using pip, virtual environments, dependency management
- Pytest test discovery rules: file naming, class naming, function naming
- Understanding how Pytest collects tests internally (collector, node, runner)
- Running tests with flags: -k, -m, -v, -q, --maxfail, --disable-warnings
# test_basic.py
# Pytest will auto-detect this file because it starts with "test_"
def test_example():
assert 5 * 5 == 25
๐งช Module 2: Assertions (Low-Level Details)
- How Python's native assert works
- Difference between assert and unittest assertions
- String comparison, list comparison, dict comparison
- Floating point precision handling
- Exception validation using pytest.raises()
- Using match keyword inside raises() for error validation
def test_string_compare():
assert "prakura".upper() == "PRAKURA"
def test_exception_message():
with pytest.raises(ValueError, match="invalid value"):
raise ValueError("invalid value provided")
๐ง Module 3: Fixtures (Complete Low-Level Deep Dive)
- What is a fixture? Why Pytest fixtures are better than setup/teardown?
- Fixture scopes explained in detail with memory lifecycle:
- function: runs before every test
- class: runs once per test class
- module: created once per file
- session: created once per entire execution
- Autouse fixtures (automatic execution without calling)
- Fixture dependency chaining (fixtures using other fixtures)
- Fixture parametrization
- Returning vs yielding values
- Database/driver setup & teardown with yield
- Class-level fixtures vs module-level fixtures
@pytest.fixture(scope="module")
def db_connection():
print("Connecting to DB...")
conn = {"status": "connected"}
yield conn
print("Closing DB connection")
๐ท๏ธ Module 4: Markers (Full Explanation)
- Built-in markers (skip, xfail, parameterize)
- Creating custom markers & registering in pytest.ini
- Running specific tests: pytest -m smoke
- Conditional skipping using skipif()
- Expected failures (xfail) with strict mode
@pytest.mark.regression
@ pytest.mark.skipif(sys.platform == "win32", reason="Not supported on Windows")
def test_platform_feature():
assert True
๐ Module 5: Parametrization (Low-Level + Nested Parametrization)
- Single-parameter tests
- Multi-parameter tests
- Parametrizing fixtures
- Matrix-based parameterization
- Loading test data from CSV/JSON/YAML
@pytest.mark.parametrize("username, password", [
("admin", "admin123"),
("user", "pass123"),
])
def test_login(username, password):
assert len(username) > 0 and len(password) > 0
๐ Module 6: conftest.py (Low-Level Internal Behavior)
- How Pytest discovers conftest.py
- Sharing fixtures across directories
- Multiple conftest.py files use-case
- Common mistakes and debugging fixture overrides
# conftest.py
@pytest.fixture
def api_base_url():
return "https://api.prakura.in/v1"
โ๏ธ Module 7: Hooks (Internal Execution Flow)
- Understanding Pytest hook architecture
- pytest_configure
- pytest_runtest_setup
- pytest_runtest_call
- pytest_runtest_teardown
- Modifying test behavior dynamically
def pytest_runtest_setup(item):
print(f"Setting up test: {item.name}")
๐ฆ Module 8: Pytest Plugins (Deep Usage)
- pytest-xdist for parallel execution
- pytest-html for beautiful reports
- pytest-rerunfailures
- pytest-order
- pytest-cov for coverage
- Creating custom plugins
๐ Module 9: Reporting & Logging
- HTML and JUnit reports
- Customizing HTML report with environment metadata
- Log file generation
- Adding screenshots for Selenium tests
pytest --html=report.html --self-contained-html
๐ Module 10: CI/CD Integration
- Running Pytest in GitHub Actions
- Running Pytest in Jenkins pipeline
- Artifacts & Report archival
- Version control workflows
๐งช Module 11: Real-Time Project (End-to-End)
- Building a complete automation framework
- Implementing fixtures + markers + parameterization
- Logging + reporting
- CI/CD execution