# Reporting and Metadata: How your docs show up in reports This document describes how test documentation is extracted and rendered into the HTML report, and what appears in JUnit XML. ## What the plugin does File: `conftest_plugin.py` - Hooks into `pytest_runtest_makereport` to parse the test’s docstring - Extracts the following fields: - Title - Description - Requirements - Test Steps - Expected Result - Attaches them as `user_properties` on the test report - Customizes the HTML results table to include Title and Requirements columns ## Docstring format to use ```python """ Title: Short, human-readable test name Description: What is this test proving and why does it matter. Requirements: REQ-001, REQ-00X Test Steps: 1. Describe the first step 2. Next step 3. etc. Expected Result: - Primary outcome - Any additional acceptance criteria """ ``` ## What appears in reports - HTML (`reports/report.html`): - Title and Requirements appear as columns in the table - Other fields are available in the report payload and can be surfaced with minor tweaks - JUnit XML (`reports/junit.xml`): - Standard test results and timing - Note: By default, the XML is compact and does not include custom properties; if you need properties in XML, we can extend the plugin to emit a custom JUnit format or produce an additional JSON artifact for traceability. Open the HTML report on Windows PowerShell: ```powershell start .\reports\report.html ``` Related artifacts written by the plugin: - `reports/requirements_coverage.json` — requirement → test nodeids map and unmapped tests - `reports/summary.md` — compact pass/fail/error/skip totals, environment info To generate separate HTML/JUnit reports for unit vs non-unit test sets, use the helper script: ```powershell ./scripts/run_two_reports.ps1 ``` ## Parameterized tests and metadata When using `@pytest.mark.parametrize`, each parameter set is treated as a distinct test case with its own nodeid, e.g.: ``` tests/test_babylin_wrapper_mock.py::test_babylin_master_request_with_mock_wrapper[wrapper0-True] tests/test_babylin_wrapper_mock.py::test_babylin_master_request_with_mock_wrapper[wrapper1-False] ``` Metadata handling: - The docstring on the test function is parsed once per case; the same Title/Requirements are attached to each parameterized instance. - Requirement mapping (coverage JSON) records each parameterized nodeid under the normalized requirement keys, enabling fine-grained coverage. - In the HTML table, you will see a row per parameterized instance with identical Title/Requirements but differing nodeids (and potentially differing outcomes if parameters influence behavior). ## Markers Declared in `pytest.ini` and used via `@pytest.mark.` in tests. They also appear in the HTML payload for each test (as user properties) and can be added as a column with a small change if desired. ## Extensibility - Add more columns to HTML by updating `pytest_html_results_table_header/row` - Persist full metadata (steps, expected) to a JSON file after the run for audit trails - Populate requirement coverage map by scanning markers and aggregating results ## Runtime properties (record_property) and the `rp` helper fixture Beyond static docstrings, you can attach dynamic key/value properties during a test. - Built-in: `record_property("key", value)` in any test - Convenience: use the shared `rp` fixture which wraps `record_property` and also prints a short line to captured output for quick scanning. Example usage: ```python def test_example(rp): rp("device", "mock") rp("tx_id", "0x12") rp("rx_present", True) ``` Where they show up: - HTML report: expand a test row to see a Properties table listing all recorded key/value pairs - Captured output: look for lines like `[prop] key=value` emitted by the `rp` helper Suggested standardized keys across suites live in `docs/15_report_properties_cheatsheet.md`.