Skip to main content

Pytest web fixtures for the Klab Pytest Toolkit

Project description

Klab Pytest Toolkit - Web Fixtures

Custom pytest fixtures for web testing. The goal is to allow testers to easily test web applications (html/json/rest api) with reusable components.

At the moment the package provides the following fixtures:

  • response_validator_factory: Factory for create JSON response validator instances with custom configurations.
  • api_client_factory: Factory for create different API client instances.
    • REST API client for making HTTP requests to RESTful services.
  • web_client_factory: Factory to create web client instances for browser automation
    • Playwright-based web client for end-to-end testing of web applications.

Installation

pip install klab-pytest-toolkit-web

Usage

JSON Response Validator

Create the fixture

The factory class ResponseValidatorFactory is already provided as a pytest fixture response_validator_factory.

@pytest.fixture
def json_validator_user_schema(response_validator_factory) -> JsonResponseValidator:
    """Fixture to provide a JSON response validator for user schema."""
    user_schema = {
        "type": "object",
        "properties": {
            "id": {"type": "integer"},
            "name": {"type": "string"},
        },
        "required": ["id", "name"]
    }
    return response_validator_factory.create_json_validator(schema=user_schema)

Functions

The validator contains one main function to validate a response against the schema. Below is an example of how to use the validator in a test.

def test_user_api(json_validator_user_schema):
    """Test user API response validation."""
    response_data = {
        "id": 1,
        "name": "John Doe"
    }
    assert json_validator_user_schema.validate_response(response_data)

REST API Client

Create the fixture

The factory class ApiClientFactory is already provided as a pytest fixture api_client_factory. To pass the url or other header information, you can pass this as environment variables or configure directly in the fixture. Below is an example of creating a REST API client fixture from a testcontainer url.

@pytest.fixture(scope="session")
def httpbin_container():
    """Fixture to provide an HTTPBin container for testing."""

    with DockerContainer("kennethreitz/httpbin:latest") as httpbin:
        httpbin.with_exposed_ports(80)
        httpbin.waiting_for(HttpWaitStrategy(path="/get", port=80).for_status_code(200))
        httpbin.start()
        port = httpbin.get_exposed_port(80)
        base_url = f"http://localhost:{port}"
        yield base_url

@pytest.fixture
def rest_api_client(api_client_factory, httpbin_container) -> RestApiClient:
    """Fixture to provide a REST API client."""
    return api_client_factory.create_rest_client(base_url=httpbin_container)

Functions

The REST API client provides functions to make HTTP requests. These are some examples:

def test_get_request(rest_api_client: RestApiClient):
    """Test basic GET request with query parameters."""
    response = rest_api_client.get("/get", params={"test": "value"})

    assert response.status_code == 200
    json_data = response.json()
    assert json_data["args"]["test"] == "value"

def test_post_request(rest_api_client: RestApiClient):
    """Test basic POST request with JSON body."""
    response = rest_api_client.post("/post", payload={"key": "value"})

    assert response.status_code == 200
    json_data = response.json()
    assert json_data["json"]["key"] == "value"

def test_update_request(rest_api_client: RestApiClient):
    """Test basic PUT request with JSON body."""
    response = rest_api_client.put("/put", payload={"update": "data"})

    assert response.status_code == 200
    json_data = response.json()
    assert json_data["json"]["update"] == "data"

def test_delete_request(rest_api_client: RestApiClient):
    """Test basic DELETE request."""
    response = rest_api_client.delete("/delete")

    assert response.status_code == 200
    json_data = response.json()
    assert json_data["url"].endswith("/delete")

gRPC Client

Create the fixture

The factory class ApiClientFactory is already provided as a pytest fixture api_client_factory. You can create a gRPC client fixture as shown below:

@pytest.fixture
def grpc_client(api_client_factory) -> GrpcClient:
    """Fixture to provide a gRPC client."""
    return api_client_factory.create_grpc_client(
        target="localhost:50051",
        proto_file="path/to/your/service.proto"
    )

Functions

The GrpcClient provides gRPC call functionality by dynamically invoking methods defined in the provided proto file. It is imported the that the proto file defines a service with methods like GetUser. You will not get any code completion in your IDE since the methods are dynamically resolved at runtime, but you get error handling if the method does not exist.

def test_grpc_get_user(grpc_client: GrpcClient):
    """Test gRPC GetUser call."""
    response = grpc_client.GetUser(id=123)

    assert response.id == 123
    assert response.name == "John Doe"

Playwright Web Client

Create the fixture

The factory class WebClientFactory is already provided as a pytest fixture web_client_factory. For playwright, you might install the browsers first by running playwright install in your environment. You can create a Playwright web client fixture as shown below:

@pytest.fixture
def web_client(web_client_factory) -> PlaywrightWebClient:
    """Fixture to provide a Playwright web client."""
     with web_client_factory.create_client(client_type="playwright", headless=True) as client:
        yield client

Functions

The WebClient provides a variety of functions for browser automation. Refer to the api of the instance. Here are some examples of common operations:

def test_navigate_and_click(web_client):
    """Test navigation and clicking a button."""
    web_client.navigate_to("https://example.com")
    web_client.click("#start-button")
    assert web_client.get_text("#result") == "Started"

def test_form_submission(web_client):
    """Test form submission."""
    web_client.navigate_to("https://example.com/form")
    web_client.fill_input("#name", "Test User")
    web_client.fill_input("#email", "max@muster.com")
    web_client.click("#submit-button")
    assert web_client.get_text("#confirmation") == "Thank you for your submission!"

def test_wait_for_element(web_client):
    """Test waiting for an element to appear."""
    web_client.navigate_to("https://example.com/dynamic")
    web_client.wait_for_element("#dynamic-content", timeout=10)
    assert web_client.get_text("#dynamic-content") == "Loaded Content"

Examples

See the test files for comprehensive examples:

  • tests/test_jsonvalidator.py - JSON validation examples covering basic validation, type checking, nested objects, constraints, and error handling
  • tests/test_restapiclient.py - REST API client examples with testcontainers integration
  • tests/test_playwrightclient.py - Playwright web client examples for browser automation with testcontainers

Best Practices

Use Testcontainers for Isolated Environments

When testing web applications, it's recommended to use testcontainers to create isolated environments for your services. This ensures that your tests are reproducible and do not interfere with each other.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

klab_pytest_toolkit_web-0.0.0.tar.gz (11.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

klab_pytest_toolkit_web-0.0.0-py3-none-any.whl (13.6 kB view details)

Uploaded Python 3

File details

Details for the file klab_pytest_toolkit_web-0.0.0.tar.gz.

File metadata

  • Download URL: klab_pytest_toolkit_web-0.0.0.tar.gz
  • Upload date:
  • Size: 11.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.18 {"installer":{"name":"uv","version":"0.9.18","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"13","id":"trixie","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for klab_pytest_toolkit_web-0.0.0.tar.gz
Algorithm Hash digest
SHA256 f816ee671edeb97f58eaadc6cd8fba024554468b889c77f17963f930bbcafda5
MD5 bee096aad6cbaeee0de1845581be3c54
BLAKE2b-256 d1953181a1dfc5b0381d2fb27ab23687cc43e64192cd98c3e3b47eda00f74c14

See more details on using hashes here.

File details

Details for the file klab_pytest_toolkit_web-0.0.0-py3-none-any.whl.

File metadata

  • Download URL: klab_pytest_toolkit_web-0.0.0-py3-none-any.whl
  • Upload date:
  • Size: 13.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.18 {"installer":{"name":"uv","version":"0.9.18","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"13","id":"trixie","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for klab_pytest_toolkit_web-0.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a8ea3aee7a2414532ce3f387002d397b8b7988e7a387e118226e590a7c6d3f25
MD5 68c2af0a5ec190f0581dc6e1a7993b87
BLAKE2b-256 202d9b566d30e43c80840f9b3a469e7fdef2dad738312bb22a14467f9d9c70e3

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page