Tests Module

Test Data & Schema Files

The test suite uses the following data and schema files:

  • tests/data/test_data.yaml - Test cases for Movies API

  • tests/schemas/movie_schema.json - JSON schema for response validation

  • tests/schemas/popular_movies_schema.json - JSON schema for popular movies response validation

  • tests/schemas/add_delete_rating_schema.json - JSON schema for adding and deleting movie rating response validation

  • tests/schemas/person_details_schema.json - JSON schema for person details response validation

Movies Test Data

test_data.yaml
defaults:
  exp_max_elp_secs: 4 # Applied to ALL valid AND invalid test cases
  exp_content_type: 'application/json'
  exp_get_req_method: 'GET'
  exp_post_req_method: 'POST'
  exp_del_req_method: 'DELETE'
  exp_put_req_method: 'PUT'

get_movie_details:
  defaults:
    valid:
        status_code: 200  # Only applied to valid cases
        reason: 'OK'
    invalid:
        status_code: 404  # Only applied to invalid cases
        reason: 'Not Found'
  valid:
    - movie_id: "$random_movie_id" # First list item (index 0)
    - movie_id: "$random_movie_id" # Second list item (index 1)
    - movie_id: "$random_movie_id"
  invalid:
    - movie_id: 0
      expected_message: "Invalid id: The pre-requisite id is invalid or not found."
    - movie_id: -1
      expected_message: "Invalid id: The pre-requisite id is invalid or not found."
    - movie_id: 9999999999
      expected_message: "The resource you requested could not be found."

popular_movies:
  defaults:
    valid:
      status_code: 200
      reason: 'OK'
    invalid:
      status_code: 400
      reason: 'Bad Request'
  valid:
    - query_param: { "language": "en-US" }
    - query_param: { "page": 2 }
  invalid:
    - query_param: { "page": -1 }
      expected_message: "Invalid page: Pages start at 1 and max at 500. They are expected to be an integer."

add_rating:
  defaults:
    valid:
      status_code: 201
      reason: 'Created'
    invalid:
      status_code_bad_req: 400
      reason: 'Bad Request'
  valid:
    - rating_payload: { "value": "$random_rating" }
    - rating_payload: { "value": "$random_rating" }
  invalid:
    - movie_id: 550
      rating_payload: { "value": "$random_invalid_rating" }
      expected_message: ['Value too high: Value must be less than, or equal to 10.0.',
                         'Value too low: Value must be greater than 0.0.',
                         'Value invalid: Value must be a multiple of 0.50.']
    - movie_id: 680
      rating_payload: { "value": "$random_invalid_rating" }
      expected_message: ['Value too high: Value must be less than, or equal to 10.0.',
                         'Value too low: Value must be greater than 0.0.',
                         'Value invalid: Value must be a multiple of 0.50.']

delete_rating:
  defaults:
    valid:
      status_code: 200
      reason: 'OK'
    invalid:
      status_code: 404
      reason: 'Not Found'
  valid:
    - expected_message: "The item/record was deleted successfully."
  invalid:
    - movie_id: 9999999999
      expected_message: "The resource you requested could not be found."
    - movie_id: 0
      session_id: "$invalid_session_id"
      expected_message: "Invalid id: The pre-requisite id is invalid or not found."

get_person_details:
  defaults:
    valid:
      status_code: 200
      reason: 'OK'
    invalid:
      status_code: 404
      reason: 'Not Found'
  valid:
    - person_id: "$random_person_id"
  invalid:
    - person_id: 0
      expected_message: "Invalid id: The pre-requisite id is invalid or not found."
    - person_id: -1
      expected_message: "Invalid id: The pre-requisite id is invalid or not found."
    - person_id: 9999999999
      expected_message: "The resource you requested could not be found."

update_list:
  defaults:
    valid:
      status_code: 201
      reason: 'Created'
    invalid:
      status_code: 404
      reason: 'Not Found'
  valid:
      - list_id: 8637178
        payload: { "name": 'French', "description": "$current_timestamp", "public": true }
        expected_message: "The item/record was updated successfully."
      - list_id: 8637178
        payload: { "name": 'Hollywood', "description": "$current_timestamp", "public": true }
        expected_message: "The item/record was updated successfully."
  invalid:
      - list_id: 9999999999
        payload: { "name": 'Indian', "description": "$current_timestamp", "public": false }
        expected_message: "The resource you requested could not be found."
      - list_id: 0
        payload: { "name": 'Hollywood', "description": "Some random Description", "public": true }
        expected_message: "Invalid id: The pre-requisite id is invalid or not found."

Movie Schema

movie_schema.json
{
  "type": "object",
  "required": ["adult", "id", "origin_country", "original_language", "title", "original_title", "production_companies"],
  "properties": {
    "adult": {"type": "boolean"},
    "id": {"type": "integer"},
    "origin_country": {
      "type": "array",
      "items": {"type": "string"}
    },
    "original_language": {"type": "string"},
    "original_title": {"type": "string"},
    "production_companies": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "id": { "type": "integer" },
          "logo_path": { "type": ["string", "null"] },
          "name": { "type": "string" }
        },
        "required": ["id", "name"]
      }
    },
    "release_date": {"type": "string", "format": "date", "nullable": true},
    "title": {"type": "string"}
  }
}

Add Rating Schema

person_details_schema.json
{
  "type": "object",
  "properties": {
    "adult": { "type": "boolean" },
    "also_known_as": {
      "type": "array",
      "items": { "type": "string" }, "nullable": true
    },
    "biography": { "type": "string" },
    "birthday": { "type": "string" },
    "deathday": { "type": ["string", "null"] },
    "gender": { "type": "integer" },
    "homepage": { "type": ["string", "null"] },
    "id": { "type": "integer" },
    "imdb_id": { "type": "string" },
    "known_for_department": { "type": "string" },
    "name": { "type": "string" },
    "place_of_birth": { "type": ["string", "null"] },
    "popularity": { "type": "number" },
    "profile_path": { "type": ["string", "null"] }
  },
  "required": [
    "adult",
    "biography",
    "birthday",
    "gender",
    "id",
    "imdb_id",
    "known_for_department",
    "name",
    "popularity"
  ]
}

Person Details Schema

add_delete_rating_schema.json
{
  "type": "object",
  "properties": {
    "success": {
      "type": "boolean"
    },
    "status_code": {
      "type": "integer"
    },
    "status_message": {
      "type": "string"
    }
  },
  "required": ["success", "status_code", "status_message"],
  "additionalProperties": false
}

Contracts

Contract tests for the Movies Details API. Module demonstrates consumer-driven contract (CDC) testing.

class tests.contracts.test_movie_details.TestMovieDetails

Bases: object

Contract tests for Movies Details API endpoint. Define what consumer (test client) expects from the provider, in our case Devs/PO.

pact()

Create a Pact instance for contract testing. Fixture creates a fresh Pact per test because once pact.serve() runs and the context manager exits, the Pact handle is finalized and no new interactions can be added to it. The consumer name identifies client service, and the provider name identifies the API being consumed (TMDB).

Yields:

Pact: Configured Pact instance ready for interaction definition.

pact_movies_api()

Create a MoviesAPI instance pointing to the Pact mock server.

Override base URL to use the Pact mock server instead of the real TMDB API and test against expected responses.

test_get_invalid_movie_details(pact, pact_movies_api)

Verify 404 error response for non-existent movie to test the client correctly handles error responses when requesting invalid movie ID.

test_get_movie_details(pact, pact_movies_api)

Verify movie details response structure. Defines expectations for the GET /movie/{id} endpoint. Using matchers to allows flexible type-based matching rather than exact value comparison. match.like() = “match by type, not exact value”

Contract tests for popular Movies API using Pact.

class tests.contracts.test_popular_movies.TestPopularMovies

Bases: object

Contract tests for Popular Movies API endpoints.

pact()

Create a Pact instance for contract testing.

This fixture: - Sets up a mock server that simulates the TMDB API - Captures request/response expectations - Generates contract files in PACT_DIR

The consumer name identifies client service, and the provider name identifies the API being consumed (TMDB).

pact_movies_api()

Create a MoviesAPI instance pointing to the Pact mock server.

Override base URL to use the Pact mock server instead of the real TMDB API and test against expected responses.

test_get_popular_movies(pact, pact_movies_api)

Verify popular movies list response structure.

Tests the GET /movie/popular endpoint with pagination. Verifies the response contains proper pagination and movie array.

test_get_popular_movies_invalid_page(pact, pact_movies_api)

Verify error response for invalid page parameter.

Tests the GET /movie/popular endpoint with an invalid page number. Verifies the API returns a 400 Bad Request with appropriate error message.

Data

tests.data.data_loader.load_test_data(file_name: str) dict

Load test data from a YAML file and apply default values.

Reads a YAML file from the same directory as this module and applies any defined defaults to test case entries. Also processes dynamic placeholders like ‘$random_rating’ by calling the mapped generator functions.

Parameters:

file_name – Name of the YAML file containing test data.

Returns:

Parsed data from the YAML file with defaults applied.

Raises:
  • FileNotFoundError – If the specified file does not exist.

  • yaml.YAMLError – If the file contains invalid YAML.

Helpers

tests.helpers.response_assertions.assert_http_response(response, exp_val)

Assert common HTTP response properties.

Parameters:
  • response – The HTTP response object to validate.

  • exp_val – A dictionary containing expected values: - ‘exp_req_method’: Expected HTTP method (e.g., ‘GET’). - ‘exp_status_code’: Expected HTTP status code (e.g., 200). - ‘exp_content_type’: Expected content type substring (e.g., ‘application/json’). - ‘exp_max_elp_seconds’: Maximum allowed response time in seconds (e.g., 2). - ‘exp_url_contains’: Substring that should be present in the response URL (e.g., movie ID).

Raises:

AssertionError – If any validation fails.

Field assertion helpers for test validation.

class tests.helpers.field_assertions.FieldAssertions

Bases: object

Mixin class providing field validation assertion methods.

assert_bool_field(data, field, index=None)

Assert that a field value is a boolean.

Parameters:
  • data – Dictionary containing the field to validate.

  • field – Name of the field to check.

  • index – Optional array index for contextual error messages.

Raises:

AssertionError – If the field is not a boolean.

assert_float_field(data, field, index=None)

Assert that a field value is a positive float.

For ‘vote_average’ fields, validates range is 0.0-10.0.

Parameters:
  • data – Dictionary containing the field to validate.

  • field – Name of the field to check.

  • index – Optional array index for contextual error messages.

Raises:

AssertionError – If the field is not a float or out of range.

assert_int_field(data, field, index=None, id_val=None)

Assert that a field value is a positive integer.

Parameters:
  • data – Dictionary containing the field to validate.

  • field – Name of the field to check.

  • index – Optional array index for contextual error messages.

  • id_val – Optional expected value for ‘id’ fields.

Raises:

AssertionError – If the field is not an integer or not positive.

assert_list_field(data, field, index=None)

Assert that a field value is a non-empty list.

Parameters:
  • data – Dictionary containing the field to validate.

  • field – Name of the field to check.

  • index – Optional array index for contextual error messages.

Raises:

AssertionError – If the field is not a list or is empty.

assert_path_field(data, field, index=None)

Assert that a field is a valid image path or null.

Validates that the path ends with ‘.png’ or ‘.jpg’ if not null.

Parameters:
  • data – Dictionary containing the field to validate.

  • field – Name of the field to check.

  • index – Optional array index for contextual error messages.

Raises:

AssertionError – If field is missing or has invalid format.

assert_str_field(data, field, index=None)

Assert that a field value is a non-empty string.

For ‘original_language’ fields, validates 2-character ISO code length.

Parameters:
  • data – Dictionary containing the field to validate.

  • field – Name of the field to check.

  • index – Optional array index for contextual error messages.

Raises:

AssertionError – If the field is not a string or is empty.

Test data generators for dynamic test values.

tests.helpers.test_data_generators.pick_random_movie_id() int

Reads numbers from a tests/data/movie_ids.txt file and returns a random one. Assumes one number per line.

Returns:

Random movie ID

Raises:
  • FileNotFoundError – If movie_ids.txt doesn’t exist

  • ValueError – If file is empty or contains invalid data

tests.helpers.test_data_generators.pick_random_rated_movie_id(acc_id, session_id) int

Fetches rated movies from the account and returns a random movie ID.

Returns:

Random rated movie ID

Raises:

ValueError – If no rated movies are found

tests.helpers.test_data_generators.random_invalid_rating() float

Generate a random invalid movie rating (outside 0.5-10.0 range).

Returns:

Random invalid rating

tests.helpers.test_data_generators.random_rating(min_val: float = 0.5, max_val: float = 10.0) float

Generate a random valid movie rating in 0.5 increments.

Parameters:
  • min_val – Minimum rating value (default: 0.5)

  • max_val – Maximum rating value (default: 10.0)

Returns:

Random rating rounded to 1 decimal place

Pacts

test_movie_details-api_pvd.json
{
  "consumer": {
    "name": "test_movie_details"
  },
  "interactions": [
    {
      "description": "a request for movie details for movie ID 550",
      "pending": false,
      "providerStates": [
        {
          "name": "a movie with ID 550 exists"
        }
      ],
      "request": {
        "headers": {
          "Authorization": [
            "Bearer token"
          ]
        },
        "matchingRules": {
          "header": {
            "Authorization": {
              "combine": "AND",
              "matchers": [
                {
                  "match": "type"
                }
              ]
            }
          }
        },
        "method": "GET",
        "path": "/3/movie/550"
      },
      "response": {
        "body": {
          "content": {
            "adult": false,
            "genres": [
              {
                "id": 18,
                "name": "Drama"
              }
            ],
            "id": 550,
            "origin_country": [
              "US"
            ],
            "original_language": "en",
            "original_title": "Fight Club",
            "overview": "A ticking-Loss...",
            "popularity": 61.416,
            "production_companies": [
              {
                "id": 508,
                "logo_path": "/7PzJdsLGlR7oW4J0J5Xcd0pHGRg.png",
                "name": "Regency Enterprises",
                "origin_country": "US"
              }
            ],
            "release_date": "1999-10-15",
            "runtime": 139,
            "status": "Released",
            "tagline": "Mischief. Mayhem. Soap.",
            "title": "Fight Club",
            "vote_average": 8.4,
            "vote_count": 26280
          },
          "contentType": "application/json",
          "encoded": false
        },
        "headers": {
          "Content-Type": [
            "application/json;charset=utf-8"
          ]
        },
        "matchingRules": {
          "body": {
            "$.adult": {
              "combine": "AND",
              "matchers": [
                {
                  "match": "type"
                }
              ]
            },
            "$.genres": {
              "combine": "AND",
              "matchers": [
                {
                  "match": "type"
                }
              ]
            },
            "$.genres[*].id": {
              "combine": "AND",
              "matchers": [
                {
                  "match": "integer"
                }
              ]
            },
            "$.genres[*].name": {
              "combine": "AND",
              "matchers": [
                {
                  "match": "type"
                }
              ]
            },
            "$.id": {
              "combine": "AND",
              "matchers": [
                {
                  "match": "integer"
                }
              ]
            },
            "$.origin_country": {
              "combine": "AND",
              "matchers": [
                {
                  "match": "type"
                }
              ]
            },
            "$.original_language": {
              "combine": "AND",
              "matchers": [
                {
                  "match": "type"
                }
              ]
            },
            "$.original_title": {
              "combine": "AND",
              "matchers": [
                {
                  "match": "type"
                }
              ]
            },
            "$.overview": {
              "combine": "AND",
              "matchers": [
                {
                  "match": "type"
                }
              ]
            },
            "$.popularity": {
              "combine": "AND",
              "matchers": [
                {
                  "match": "type"
                }
              ]
            },
            "$.production_companies": {
              "combine": "AND",
              "matchers": [
                {
                  "match": "type"
                }
              ]
            },
            "$.production_companies[*].id": {
              "combine": "AND",
              "matchers": [
                {
                  "match": "integer"
                }
              ]
            },
            "$.production_companies[*].logo_path": {
              "combine": "AND",
              "matchers": [
                {
                  "match": "type"
                }
              ]
            },
            "$.production_companies[*].name": {
              "combine": "AND",
              "matchers": [
                {
                  "match": "type"
                }
              ]
            },
            "$.production_companies[*].origin_country": {
              "combine": "AND",
              "matchers": [
                {
                  "match": "type"
                }
              ]
            },
            "$.release_date": {
              "combine": "AND",
              "matchers": [
                {
                  "match": "regex",
                  "regex": "^\\d{4}-\\d{2}-\\d{2}$"
                }
              ]
            },
            "$.runtime": {
              "combine": "AND",
              "matchers": [
                {
                  "match": "integer"
                }
              ]
            },
            "$.status": {
              "combine": "AND",
              "matchers": [
                {
                  "match": "type"
                }
              ]
            },
            "$.tagline": {
              "combine": "AND",
              "matchers": [
                {
                  "match": "type"
                }
              ]
            },
            "$.title": {
              "combine": "AND",
              "matchers": [
                {
                  "match": "type"
                }
              ]
            },
            "$.vote_average": {
              "combine": "AND",
              "matchers": [
                {
                  "match": "type"
                }
              ]
            },
            "$.vote_count": {
              "combine": "AND",
              "matchers": [
                {
                  "match": "integer"
                }
              ]
            }
          }
        },
        "status": 200
      },
      "type": "Synchronous/HTTP"
    },
    {
      "description": "a request for non-existent movie ID 99999999",
      "pending": false,
      "providerStates": [
        {
          "name": "movie with ID 99999999 does not exist"
        }
      ],
      "request": {
        "headers": {
          "Authorization": [
            "Bearer token"
          ]
        },
        "matchingRules": {
          "header": {
            "Authorization": {
              "combine": "AND",
              "matchers": [
                {
                  "match": "type"
                }
              ]
            }
          }
        },
        "method": "GET",
        "path": "/3/movie/99999999"
      },
      "response": {
        "body": {
          "content": {
            "status_code": 34,
            "status_message": "The resource you requested could not be found.",
            "success": false
          },
          "contentType": "application/json",
          "encoded": false
        },
        "headers": {
          "Content-Type": [
            "application/json;charset=utf-8"
          ]
        },
        "matchingRules": {
          "body": {
            "$.status_code": {
              "combine": "AND",
              "matchers": [
                {
                  "match": "integer"
                }
              ]
            },
            "$.status_message": {
              "combine": "AND",
              "matchers": [
                {
                  "match": "type"
                }
              ]
            },
            "$.success": {
              "combine": "AND",
              "matchers": [
                {
                  "match": "type"
                }
              ]
            }
          }
        },
        "status": 404
      },
      "type": "Synchronous/HTTP"
    }
  ],
  "metadata": {
    "pactRust": {
      "ffi": "0.4.28",
      "models": "1.3.5"
    },
    "pactSpecification": {
      "version": "4.0"
    }
  },
  "provider": {
    "name": "api_pvd"
  }
}
test_popular_movies-api_pvd.json
{
  "consumer": {
    "name": "test_popular_movies"
  },
  "interactions": [
    {
      "description": "a request for popular movies in page 1",
      "pending": false,
      "providerStates": [
        {
          "name": "popular movies exist"
        }
      ],
      "request": {
        "headers": {
          "Authorization": [
            "Bearer token"
          ]
        },
        "matchingRules": {
          "header": {
            "Authorization": {
              "combine": "AND",
              "matchers": [
                {
                  "match": "type"
                }
              ]
            }
          }
        },
        "method": "GET",
        "path": "/3/movie/popular",
        "query": {
          "page": [
            "1"
          ]
        }
      },
      "response": {
        "body": {
          "content": {
            "page": 1,
            "results": [
              {
                "adult": false,
                "backdrop_path": "/path.jpg",
                "genre_ids": 28,
                "id": 123,
                "original_language": "en",
                "original_title": "Movie Title",
                "overview": "Description...",
                "popularity": 100.5,
                "poster_path": "/poster.jpg",
                "release_date": "2024-01-15",
                "title": "Movie Title",
                "video": false,
                "vote_average": 7.5,
                "vote_count": 1000
              }
            ],
            "total_pages": 500,
            "total_results": 10000
          },
          "contentType": "application/json",
          "encoded": false
        },
        "headers": {
          "Content-Type": [
            "application/json;charset=utf-8"
          ]
        },
        "matchingRules": {
          "body": {
            "$.page": {
              "combine": "AND",
              "matchers": [
                {
                  "match": "integer"
                }
              ]
            },
            "$.results": {
              "combine": "AND",
              "matchers": [
                {
                  "match": "type"
                }
              ]
            },
            "$.results[*].adult": {
              "combine": "AND",
              "matchers": [
                {
                  "match": "type"
                }
              ]
            },
            "$.results[*].backdrop_path": {
              "combine": "AND",
              "matchers": [
                {
                  "match": "type"
                }
              ]
            },
            "$.results[*].genre_ids": {
              "combine": "AND",
              "matchers": [
                {
                  "match": "integer"
                }
              ]
            },
            "$.results[*].id": {
              "combine": "AND",
              "matchers": [
                {
                  "match": "integer"
                }
              ]
            },
            "$.results[*].original_language": {
              "combine": "AND",
              "matchers": [
                {
                  "match": "type"
                }
              ]
            },
            "$.results[*].original_title": {
              "combine": "AND",
              "matchers": [
                {
                  "match": "type"
                }
              ]
            },
            "$.results[*].overview": {
              "combine": "AND",
              "matchers": [
                {
                  "match": "type"
                }
              ]
            },
            "$.results[*].popularity": {
              "combine": "AND",
              "matchers": [
                {
                  "match": "type"
                }
              ]
            },
            "$.results[*].poster_path": {
              "combine": "AND",
              "matchers": [
                {
                  "match": "type"
                }
              ]
            },
            "$.results[*].release_date": {
              "combine": "AND",
              "matchers": [
                {
                  "match": "regex",
                  "regex": "^\\d{4}-\\d{2}-\\d{2}$"
                }
              ]
            },
            "$.results[*].title": {
              "combine": "AND",
              "matchers": [
                {
                  "match": "type"
                }
              ]
            },
            "$.results[*].video": {
              "combine": "AND",
              "matchers": [
                {
                  "match": "type"
                }
              ]
            },
            "$.results[*].vote_average": {
              "combine": "AND",
              "matchers": [
                {
                  "match": "type"
                }
              ]
            },
            "$.results[*].vote_count": {
              "combine": "AND",
              "matchers": [
                {
                  "match": "integer"
                }
              ]
            },
            "$.total_pages": {
              "combine": "AND",
              "matchers": [
                {
                  "match": "integer"
                }
              ]
            },
            "$.total_results": {
              "combine": "AND",
              "matchers": [
                {
                  "match": "integer"
                }
              ]
            }
          }
        },
        "status": 200
      },
      "type": "Synchronous/HTTP"
    },
    {
      "description": "a request for popular movies with invalid page",
      "pending": false,
      "providerStates": [
        {
          "name": "invalid page parameter"
        }
      ],
      "request": {
        "headers": {
          "Authorization": [
            "Bearer token"
          ]
        },
        "matchingRules": {
          "header": {
            "Authorization": {
              "combine": "AND",
              "matchers": [
                {
                  "match": "type"
                }
              ]
            }
          }
        },
        "method": "GET",
        "path": "/3/movie/popular",
        "query": {
          "page": [
            "-1"
          ]
        }
      },
      "response": {
        "body": {
          "content": {
            "status_code": 34,
            "status_message": "The resource you requested could not be found.",
            "success": false
          },
          "contentType": "application/json",
          "encoded": false
        },
        "headers": {
          "Content-Type": [
            "application/json;charset=utf-8"
          ]
        },
        "matchingRules": {
          "body": {
            "$.status_code": {
              "combine": "AND",
              "matchers": [
                {
                  "match": "integer"
                }
              ]
            },
            "$.status_message": {
              "combine": "AND",
              "matchers": [
                {
                  "match": "type"
                }
              ]
            },
            "$.success": {
              "combine": "AND",
              "matchers": [
                {
                  "match": "type"
                }
              ]
            }
          }
        },
        "status": 400
      },
      "type": "Synchronous/HTTP"
    }
  ],
  "metadata": {
    "pactRust": {
      "ffi": "0.4.28",
      "models": "1.3.5"
    },
    "pactSpecification": {
      "version": "4.0"
    }
  },
  "provider": {
    "name": "api_pvd"
  }
}

Conftest

tests.conftest.get_api_instance()

Fixture that provides a generic API client instance for each test.

Creates a fresh API client before each test and yields it for use. This fixture can be used when the specific API type is not important for the test, allowing for more flexible test design.

Yields:

Configured BaseAPI instance.

tests.conftest.load_schema()

Fixture that provides a Pydantic model loader for response validation.

Returns a callable that maps schema names to Pydantic model classes.

tests.conftest.movies_test_data()

Session-scoped fixture that loads movies API test data from YAML.

Loads test data once per test session and shares it across all tests, improving performance by avoiding repeated file reads.

Note: This fixture is currently unused. The test module uses a module-level constant with @pytest.mark.parametrize instead, which is required because parametrize decorators are evaluated at collection time before fixtures are available.

Returns:

Dictionary containing test data with defaults applied.

tests.conftest.pytest_addoption(parser)

Register custom command-line options for pytest.

Adds –loguru-log-level option to control application logging verbosity during test runs. This hook runs during pytest’s startup phase before any tests are collected.

Parameters:

parser – Pytest’s argument parser instance.

Usage:

poetry run pytest tests/* –loguru-log-level=DEBUG poetry run pytest tests/* –loguru-log-level=WARNING poetry run pytest tests/* –log-to-file

Available log levels:

DEBUG, INFO (default), WARNING, ERROR, CRITICAL

tests.conftest.pytest_configure(config)

Configure the test environment before test collection begins.

Sets the LOG_LEVEL environment variable based on the –loguru-log-level CLI option, then reconfigures loguru to use the new level. This ensures logging is properly configured before any test modules are imported.

Parameters:

config – Pytest’s Config object containing parsed CLI options.

Note:

This hook runs after pytest_addoption but before test collection. The configure_logging() call is necessary because loguru may have already been initialized with default settings at module import time.

tests.conftest.pytest_html_report_title(report)

Customize the title of the HTML test report. :param report: :return:

tests.conftest.pytest_html_results_summary(prefix, summary, postfix)

Test Movies

Test People

class tests.people.test_details.TestDetails

Bases: FieldAssertions

test_get_person_details(get_api_instance, load_schema, person_details)

Test fetching person details with valid data.

Validates that the response contains expected fields and matches the defined JSON schema for person details.

Parameters:

person_details – Dictionary containing test parameters for a valid case.

test_get_person_details_invalid(get_api_instance, load_schema, invalid_person_details)

Test fetching person details with valid data.

Validates that the response contains expected fields and matches the defined JSON schema for person details.

Parameters:

invalid_person_details – Dictionary containing test parameters for invalid case.