Jiaxi Liu (Jesse)

Master’s Graduate

Software Engineer | Scalable APIs · Web Scraping · Data Integration · Code Quality & Refactoring

Back to Blog

pytest, Robot Framework, and Playwright: Fixtures, Keyword-Driven Testing, and E2E Tests

These tools solve different testing problems. pytest is a Python testing framework, Robot Framework is keyword-driven automation, and Playwright is modern web E2E testing.

pytest Discovery

pytest discovers:

  • test_*.py
  • *_test.py
  • functions starting with test_
def test_add():
    assert 1 + 2 == 3

Fixtures

Fixtures prepare test state and can clean up afterward.

import pytest
 
@pytest.fixture
def setup_env():
    print("prepare")
    yield
    print("cleanup")

Use a fixture by naming it as a test parameter.

def test_example(setup_env):
    assert True

Fixture Scope

Scope controls lifecycle:

  • function: once per test function
  • class: once per test class
  • module: once per file
  • session: once per test session

In real projects, shared fixtures usually live in conftest.py.

Robot Framework

Robot Framework uses keyword-driven tests that are easier for business stakeholders to read.

*** Test Cases ***
Login With Valid User
    Open Browser To Login Page
    Login With Valid Credentials    ${USERNAME}    ${PASSWORD}
    Page Should Contain Element    id=dashboard

It is useful for acceptance tests and workflow automation.

Playwright

Playwright is suited for modern web E2E.

test("user can login", async ({ page }) => {
  await page.goto("/login");
  await page.getByLabel("Username").fill("jesse");
  await page.getByLabel("Password").fill("password");
  await page.getByRole("button", { name: "Login" }).click();
  await expect(page.getByTestId("dashboard")).toBeVisible();
});

Reducing Flaky Tests

Avoid fixed sleeps as a universal solution.

Better options:

  • Wait for elements to be visible
  • Wait for buttons to be clickable
  • Wait for requests
  • Wait for URL changes
  • Prepare data through API or database
  • Keep UI tests focused on core paths

Stable tests wait for explicit conditions, not arbitrary time.

Deeper Notes

When reviewing this topic, do not memorize names only. Focus on pytest fixtures, Robot Framework, Playwright, end-to-end testing, and flaky test control. If this stays at the definition level, it becomes hard to explain in interviews or apply in projects. A stronger way to study it is to place it in a concrete scenario: who calls it, where the input comes from, what happens on failure, and whether data or state can be processed twice.

  • Testing is not about chasing coverage numbers; it is about locking down important behavior and risk boundaries cheaply.
  • Unit, integration, and E2E tests should have clear roles; UI-level tests should be fewer but critical.
  • Robust tests avoid real time, random data, network instability, and external service state.

In a real project, use it as a decision framework: identify inputs, constraints, failure modes, and observability before choosing a specific tool or pattern. If a solution looks simple, keep asking whether it still works when scale grows, permissions change, recovery matters, and more people collaborate on it.

Practical Checklist

  • Identify where this concept sits in the system: development-time constraint, runtime behavior, infrastructure capability, or collaboration workflow.
  • Write one minimal working example and one failure example; only knowing the happy path is usually not enough.
  • Record common misuses: edge cases, permission assumptions, performance assumptions, sync/async differences, or environment differences.
  • Connect the concept to a project experience so that an interview answer can be grounded in real tradeoffs.
  • End with one sentence about tradeoff: what it gives up and what it buys.

Self-Check Questions

  1. What core problem does this topic solve?
  2. What alternatives exist, and what are their costs?
  3. Where are the most likely edge cases?
  4. How would code, tests, or monitoring prove that it is reliable?

Applied Scenario

A login or order endpoint is a useful example. Unit tests verify pure functions and edge cases, integration tests verify API/database behavior, and E2E tests verify the critical user path. Mocks should isolate external dependencies, not hide real behavior. The closer a test is to the UI, the slower and more expensive it usually is, so UI-level tests should cover the most important paths.

Common Pitfalls:

  • Testing only the successful path.
  • Mocking so much that tests no longer reflect the real system.
  • Letting E2E tests depend on real time or unstable external services.