Debugging Failed Test Cases

Introduction

Even well-designed Selenium automation frameworks occasionally encounter test failures caused by application changes, synchronization issues, incorrect locators, or unexpected browser behavior. Simply knowing that a test has failed is rarely sufficient for effective troubleshooting. Automation engineers need reliable evidence that explains what happened at the exact moment the failure occurred.

One of the most effective approaches for troubleshooting failed Selenium tests is automatically collecting failure artifacts whenever a test fails. These artifacts commonly include:

  • Screenshots.

  • HTML page source.

  • Browser logs.

  • Logging information.

  • Failure reports.

In this section, the shared conftest.py file automatically captures a screenshot and the current page source whenever a test fails. This provides valuable debugging information without requiring developers to manually capture failure details.

In this tutorial, you will learn how automatic failure handling works in PyTest, understand how conftest.py simplifies debugging, explore practical examples, common mistakes, best practices, and frequently asked interview questions.


What is Debugging Failed Test Cases?

Debugging failed test cases refers to automatically collecting useful failure information whenever an automation test does not execute successfully.

Instead of:

Test Fails
     │
     ▼
No Failure Information
     │
     ▼
Run the Test Again
     │
     ▼
Investigate Manually

we can automatically preserve failure artifacts.

Test Fails
      │
      ▼
Capture Screenshot
      │
      ▼
Capture HTML Source
      │
      ▼
Store Failure Artifacts
      │
      ▼
Analyze the Failure
      │
      ▼
Fix the Problem Quickly

Automatic failure handling significantly improves troubleshooting capabilities in Selenium automation frameworks.


Why Should We Automatically Capture Failure Artifacts?

Automatic failure handling allows developers to:

  • Preserve browser state.

  • Capture screenshots.

  • Save page source files.

  • Simplify failure analysis.

  • Improve framework maintainability.

  • Reduce troubleshooting efforts.

Large automation frameworks almost always implement automatic failure capture mechanisms.


Shared conftest.py File

The following shared fixture and PyTest hook automatically save screenshots and page source files whenever a test fails.

from pathlib import Path

import pytest
from selenium import webdriver


# Shared fixtures/hooks for 61_examples.
# On any test failure, capture a screenshot and the page source.


@pytest.hookimpl(
    hookwrapper=True,
    tryfirst=True
)
def pytest_runtest_makereport(
    item,
    call
):

    outcome = yield

    report = outcome.get_result()

    setattr(
        item,
        "rep_" + report.when,
        report
    )


@pytest.fixture
def driver(request):

    browser = webdriver.Chrome()

    yield browser

    failed = (
        hasattr(
            request.node,
            "rep_call"
        )
        and
        request.node.rep_call.failed
    )

    if failed:

        artifacts = Path(
            "screenshots"
        )

        artifacts.mkdir(
            exist_ok=True
        )

        name = (
            request.node.name
        )

        browser.save_screenshot(
            str(
                artifacts /
                f"{name}.png"
            )
        )

        (
            artifacts /
            f"{name}.html"
        ).write_text(
            browser.page_source,
            encoding="utf-8"
        )

    browser.quit()

This fixture automatically performs failure handling without requiring additional code inside the test itself.


Practical Example

The following example demonstrates how Selenium tests utilize the shared fixture for automatic failure handling.

from selenium.webdriver.common.by import By


# Topic: Debugging Failed Test Cases
# Practice site:
# https://www.testmuai.com/selenium-playground/simple-form-demo
# Run:
# pytest -s 64_examples/test_05_debugging_failed_test_cases.py
#
# The shared conftest.py file automatically captures screenshots and page
# source files whenever a Selenium test fails.


def test_debugging_failed_test_cases(
    driver
):

    driver.get(
        "https://www.testmuai.com/"
        "selenium-playground/simple-form-demo"
    )

    driver.find_element(
        By.ID,
        "user-message"
    ).send_keys(
        "Debug Failures"
    )

    driver.find_element(
        By.ID,
        "showInput"
    ).click()

    assert (
        driver.find_element(
            By.ID,
            "message"
        ).text
        ==
        "Debug Failures"
    )

Output

Successful Execution

Chrome browser launched successfully.

Website opened successfully.

Assertions Passed.

Test Executed Successfully.

No failure artifacts generated.

Failed Execution

Suppose the following assertion fails.

assert (
    driver.find_element(
        By.ID,
        "message"
    ).text
    ==
    "Incorrect Value"
)

The framework automatically generates:

screenshots
      │
      ├──
      │
      ├── test_debugging_failed_
      │   test_cases.png
      │
      └── test_debugging_failed_
          test_cases.html

which preserves valuable debugging information.


Understanding the Code

Use the Shared Driver Fixture

def test_debugging_failed_test_cases(
    driver
):

Notice that:

driver

is provided by:

conftest.py

which means Selenium automatically handles:

  • Browser creation.

  • Failure detection.

  • Screenshot capture.

  • Page source capture.

  • Browser cleanup.


Open the Website

driver.get(
    "https://www.testmuai.com/"
    "selenium-playground/simple-form-demo"
)

Opens the Selenium Playground webpage.


Enter the Message

driver.find_element(
    By.ID,
    "user-message"
).send_keys(
    "Debug Failures"
)

This enters the desired test data into the webpage.


Display the Message

driver.find_element(
    By.ID,
    "showInput"
).click()

which displays the entered message.


Verify the Result

assert (
    driver.find_element(
        By.ID,
        "message"
    ).text
    ==
    "Debug Failures"
)

If this assertion succeeds:

Test Passes

↓

No Failure Artifacts Generated

However, if the assertion fails:

Test Fails

↓

Failure Detected

↓

Execute conftest.py Hook

↓

Capture Screenshot

↓

Capture HTML Source

↓

Store Failure Artifacts

Everything happens automatically.


How Does conftest.py Detect Failures?

The following hook monitors test execution.

pytest_runtest_makereport()

Its responsibility is to determine:

Did the Test Fail?

↓

YES

↓

Capture Failure Artifacts


NO

↓

Continue Normally

The following statement performs the actual failure check.

request.node.rep_call.failed

which returns:

True

↓

Test Failed


False

↓

Test Passed

Automatic Screenshot Capture

When failures occur:

browser.save_screenshot()

generates:

screenshots

↓

failed_test.png

which preserves the exact browser state during failure.


Automatic Page Source Capture

Similarly:

browser.page_source

is automatically saved as:

screenshots

↓

failed_test.html

which preserves the complete DOM structure.


Running the Example

Execute the following command:

py -3 -m pytest -s ^
"64_examples/test_05_debugging_failed_test_cases.py"

Run all troubleshooting examples together:

py -3 -m pytest -s ^
"61_examples/"

Execution Flow

Launch Browser
       │
       ▼
Execute the Test
       │
       ▼
Assertions Executed
       │
       ▼
Did the Test Fail?
       │
      YES
       │
       ▼
Capture Screenshot
       │
       ▼
Capture HTML Source
       │
       ▼
Store Failure Artifacts
       │
       ▼
Close Browser

Relationship with Other Troubleshooting Topics

This section includes:

  • Python Logging.

  • Capturing Screenshots.

  • Capturing Page Source.

  • Browser Console Logs.

  • Debugging Failed Test Cases.

Each technique provides different troubleshooting capabilities.

Automation Failure
       │
       ▼
Python Logging
       │
       ▼
Screenshots
       │
       ▼
HTML Source
       │
       ▼
Browser Logs
       │
       ▼
Automatic Failure Handling
       │
       ▼
Comprehensive Troubleshooting

Combining all these mechanisms significantly improves debugging capabilities.


Real-World Example

Large automation frameworks frequently implement:

Failed Test
      │
      ▼
Capture Screenshot
      │
      ▼
Capture HTML Source
      │
      ▼
Capture Logs
      │
      ▼
Generate Reports
      │
      ▼
Analyze Failure

Automatic failure handling substantially reduces troubleshooting time during CI/CD executions.


Common Mistakes Beginners Make

Performing Failure Handling Manually

Avoid writing:

if failed:

    driver.save_screenshot(...)

    save_page_source(...)

inside every test case.

Prefer centralizing failure handling inside:

conftest.py

which greatly improves framework maintainability.


Ignoring Failure Artifacts

Screenshots and page source files frequently reveal:

  • Incorrect locators.

  • Synchronization problems.

  • Application failures.

  • Unexpected webpage behavior.

Always inspect generated failure artifacts carefully.


Closing the Browser Too Early

Avoid executing:

driver.quit()

before failure artifacts are captured.

Always ensure screenshots and HTML files are generated before the browser session ends.


Best Practices

  • Implement centralized failure handling using conftest.py.

  • Capture screenshots automatically whenever failures occur.

  • Preserve HTML page source files during failed executions.

  • Combine failure artifacts with logging mechanisms.

  • Maintain meaningful file names for generated artifacts.

  • Integrate automatic failure handling into CI/CD pipelines whenever appropriate.

  • Preserve failure artifacts whenever troubleshooting information is valuable.


Conclusion

Automatic failure handling significantly improves Selenium automation troubleshooting capabilities by preserving valuable failure artifacts whenever tests fail. Screenshots and page source files provide essential information that simplifies debugging efforts and improves framework maintainability.

Centralizing failure handling inside conftest.py eliminates code duplication while providing a consistent and reliable troubleshooting mechanism across the entire automation framework.

Mastering automatic failure handling techniques is an essential Selenium automation and interview skill.


Frequently Asked Questions (FAQs)

Why should failure artifacts be captured automatically?

Automatic failure handling preserves valuable debugging information without requiring developers to manually investigate failures repeatedly.


What does conftest.py capture in this example?

Whenever a test fails, it automatically captures:

  • A screenshot.

  • The current HTML page source.


Can automatic failure handling be implemented for every Selenium test?

Yes.

Large automation frameworks commonly centralize failure handling inside shared PyTest fixtures and hooks.


Is pytest_runtest_makereport() useful for framework development?

Yes.

It is one of the most commonly used PyTest hooks for implementing automatic failure handling mechanisms.


Should screenshots and page source files be combined with logging?

Yes.

Combining:

  • Logging.

  • Screenshots.

  • Page source capture.

  • Browser console logs.

  • Reporting tools.

provides significantly better troubleshooting capabilities.


Key Takeaways

  • Automatic failure handling greatly simplifies Selenium automation troubleshooting.

  • conftest.py centralizes screenshot and page source capture mechanisms.

  • pytest_runtest_makereport() allows PyTest to detect failed test executions automatically.

  • Failure artifacts provide valuable debugging information during failure analysis.

  • Centralized failure handling improves framework maintainability significantly.

  • Automatic screenshot and HTML capture are common practices in large automation frameworks.

  • Combining multiple troubleshooting techniques substantially improves debugging capabilities.

  • Debugging Failed Test Cases is an important Selenium automation and interview topic.