diff --git a/tests/e2e/features/steps/common_http.py b/tests/e2e/features/steps/common_http.py index b462f7df..8e995178 100644 --- a/tests/e2e/features/steps/common_http.py +++ b/tests/e2e/features/steps/common_http.py @@ -3,7 +3,7 @@ import json import requests -from behave import given, then, when +from behave import given, then, when # pyright: ignore[reportAttributeAccessIssue] from behave.runner import Context from tests.e2e.utils.utils import normalize_endpoint, validate_json @@ -33,10 +33,16 @@ def request_endpoint_with_body( def request_endpoint_with_json( context: Context, endpoint: str, hostname: str, port: int ) -> None: - """Perform a request to the local server with a given JSON in the request.""" + """ + Sends an HTTP GET request with a JSON payload to the specified endpoint and stores the response in the context. + + The JSON payload is parsed from `context.text`, which must not be None. The response is saved to `context.response`. + """ # initial value context.response = None + assert context.text is not None, "Payload needs to be specified" + # perform REST API call context.response = requests.get( f"http://{hostname}:{port}/{endpoint}", @@ -51,9 +57,15 @@ def request_endpoint_with_json( def request_endpoint_with_url_params( context: Context, endpoint: str, hostname: str, port: int ) -> None: - """Perform a request to the server defined by URL to a given endpoint.""" + """ + Send an HTTP GET request to the specified endpoint with URL query parameters extracted from the context table. + + The function asserts that `context.table` is provided and uses its rows to build the query parameters for the request. The HTTP response is stored in `context.response`. + """ params = {} + assert context.table is not None, "Request parameters needs to be specified" + for row in context.table: name = row["param"] value = row["value"] @@ -118,8 +130,13 @@ def check_content_type(context: Context, content_type: str) -> None: @then("The body of the response has the following schema") def check_response_body_schema(context: Context) -> None: - """Check that response body is compliant with a given schema.""" + """ + Validates that the JSON response body matches a schema provided in the test context. + + Asserts that a response has been received and that a schema is present in `context.text`. Loads the schema from `context.text` and validates the response body against it using the `validate_json` utility. + """ assert context.response is not None, "Request needs to be performed first" + assert context.text is not None, "Response does not contain any payload" schema = json.loads(context.text) body = context.response.json() @@ -137,8 +154,13 @@ def check_response_body_contains(context: Context, substring: str) -> None: @then("The body of the response is the following") def check_prediction_result(context: Context) -> None: - """Check the content of the response to be exactly the same.""" + """ + Asserts that the JSON response body matches exactly the expected JSON payload provided in the test context. + + Raises an assertion error if the response is missing, the expected payload is not provided, or if the actual and expected JSON objects differ. + """ assert context.response is not None, "Request needs to be performed first" + assert context.text is not None, "Response does not contain any payload" expected_body = json.loads(context.text) result = context.response.json() @@ -148,8 +170,14 @@ def check_prediction_result(context: Context) -> None: @then('The body of the response, ignoring the "{field}" field, is the following') def check_prediction_result_ignoring_field(context: Context, field: str) -> None: - """Check the content of the response to be exactly the same.""" + """ + Asserts that the JSON response body matches the expected JSON payload, ignoring a specified field. + + Parameters: + field (str): The name of the field to exclude from both the actual and expected JSON objects during comparison. + """ assert context.response is not None, "Request needs to be performed first" + assert context.text is not None, "Response does not contain any payload" expected_body = json.loads(context.text).copy() result = context.response.json().copy() @@ -212,11 +240,16 @@ def access_rest_api_endpoint_get(context: Context, endpoint: str) -> None: @when("I access endpoint {endpoint:w} using HTTP POST method") def access_rest_api_endpoint_post(context: Context, endpoint: str) -> None: - """Send GET HTTP request to tested service.""" + """ + Send a POST HTTP request with a JSON payload to a REST API endpoint constructed from the given context and endpoint. + + The JSON payload is loaded from `context.text`, which must not be None. The response is stored in `context.response`. + """ base = f"http://{context.hostname}:{context.port}" path = f"{context.api_prefix}/{endpoint}".replace("//", "/") url = base + path + assert context.text is not None, "Payload needs to be specified" data = json.loads(context.text) # initial value context.response = None diff --git a/tests/e2e/features/steps/llm_query_response.py b/tests/e2e/features/steps/llm_query_response.py index 10f0cf84..f4e31a79 100644 --- a/tests/e2e/features/steps/llm_query_response.py +++ b/tests/e2e/features/steps/llm_query_response.py @@ -1,7 +1,7 @@ """LLM query and response steps.""" import requests -from behave import then, when +from behave import then, when # pyright: ignore[reportAttributeAccessIssue] from behave.runner import Context DEFAULT_LLM_TIMEOUT = 60 @@ -36,11 +36,17 @@ def check_llm_response_not_truncated(context: Context) -> None: @then("The response should contain following fragments") def check_fragments_in_response(context: Context) -> None: - """Check if the LLM response contain list of fragments.""" + """ + Validate that all specified fragments are present in the LLM response. + + Checks that the HTTP response exists and contains a "response" field. For each fragment listed in the scenario's table under "Fragments in LLM response", asserts that it appears as a substring in the LLM's response. Raises an assertion error if any fragment is missing or if the fragments table is not provided. + """ assert context.response is not None response_json = context.response.json() response = response_json["response"] + assert context.table is not None, "Fragments are not specified in table" + for fragment in context.table: expected = fragment["Fragments in LLM response"] assert (