Test Execution Report¶
Generated: October 10, 2026 22:06:00 UTC
📊 Test Suite Summary¶
| Metric | Value |
|---|---|
| Total Tests | 390 |
| Passed | 390 ✅ |
| Failed | 0 ❌ |
| Errors | 0 ⚠️ |
| Skipped | 0 ⏭️ |
| Success Rate | 100.0% |
| Total Duration | 22.38s |
📝 Test Results by Python Version¶
Unit Tests (Python 3.10)¶
Summary: 66/66 passed • Duration: 2.74s
test_api¶
- ✅
test_health_check(0.022s) - ✅
test_liveness_probe(0.006s) - ✅
test_get_weather_success(0.023s) - ✅
test_readiness_probe(0.262s) - ✅
test_get_weather_missing_parameters(0.027s) - ✅
test_post_weather_missing_body(0.011s) - ✅
test_post_weather_client_error(0.030s) - ✅
test_get_weather_client_error(0.011s) - ✅
test_get_weather_missing_city(0.006s) - ✅
test_weather_caching_same_bucket(0.011s) - ✅
test_invalid_endpoint(0.007s) - ✅
test_post_weather_invalid_json(0.006s) - ✅
test_cache_with_different_locations(0.012s) - ✅
test_weather_cache_invalidation(0.013s) - ✅
test_cache_duration_configuration(0.001s) - ✅
test_cache_size_configuration(0.001s) - ✅
test_malformed_json_body(0.007s) - ✅
test_invalid_http_method(0.006s) - ✅
test_invalid_content_type_post(0.008s) - ✅
test_oversized_request_body(0.006s) - ✅
test_x_request_id_header(0.007s) - ✅
test_cache_zero_duration(0.008s) - ✅
test_weather_coordinates_endpoint(0.638s) - ✅
test_weather_coordinates_missing_params(0.010s) - ✅
test_weather_coordinates_invalid_latitude(0.009s) - ✅
test_recent_searches_get(0.005s) - ✅
test_recent_searches_delete(0.007s) - ✅
test_versioned_weather_get(0.561s) - ✅
test_versioned_weather_post(0.007s) - ✅
test_post_weather_missing_fields(0.010s) - ✅
test_post_weather_success(0.006s) - ✅
test_weather_coordinates_invalid_longitude(0.005s)
test_client¶
- ✅
test_extract_humidity(0.023s) - ✅
test_extract_weather_from_json_invalid_json(0.024s) - ✅
test_weather_client_initialization(0.022s) - ✅
test_get_weather_request_exception(0.028s) - ✅
test_extract_weather_from_json_missing_keys(0.023s) - ✅
test_extract_wind_speed(0.022s) - ✅
test_get_weather_with_json_extraction(0.026s) - ✅
test_weather_client_context_manager(0.019s) - ✅
test_extract_temperature(0.043s) - ✅
test_fahrenheit_to_celsius_conversion(0.055s) - ✅
test_extract_weather_from_json_success(0.026s) - ✅
test_extract_weather_from_json_no_script_tag(0.020s) - ✅
test_get_weather_fallback_to_html(0.043s) - ✅
test_extract_condition(0.021s) - ✅
test_extract_temperature_not_found(0.023s) - ✅
test_extract_weather_json_empty_forecast(0.022s) - ✅
test_humidity_extraction_with_parent_element(0.021s) - ✅
test_extract_humidity_not_found(0.022s) - ✅
test_extract_weather_json_no_hourly(0.021s) - ✅
test_extract_condition_not_found(0.025s) - ✅
test_get_weather_by_coordinates_geocode_failure(0.003s) - ✅
test_get_weather_by_coordinates_geocode_exception(0.002s) - ✅
test_extract_weather_json_empty_hourly(0.021s) - ✅
test_async_get_weather_by_coordinates_success(0.066s) - ✅
test_extract_wind_speed_not_found(0.021s) - ✅
test_async_get_weather_by_coordinates_geocode_failure(0.058s) - ✅
test_mph_to_kmh_conversion(0.030s) - ✅
test_extract_weather_json_exception(0.021s) - ✅
test_ms_to_kmh_conversion(0.028s) - ✅
test_async_get_weather_by_coordinates_geocode_exception(0.032s)
test_models¶
- ✅
test_location_with_coordinates(0.001s) - ✅
test_weather_data_creation(0.001s) - ✅
test_weather_data_validation(0.001s) - ✅
test_location_creation(0.001s)
Unit Tests (Python 3.11)¶
Summary: 66/66 passed • Duration: 4.33s
test_api¶
- ✅
test_health_check(0.032s) - ✅
test_liveness_probe(0.021s) - ✅
test_get_weather_success(0.054s) - ✅
test_readiness_probe(0.162s) - ✅
test_get_weather_missing_parameters(0.050s) - ✅
test_post_weather_missing_fields(0.031s) - ✅
test_post_weather_success(0.017s) - ✅
test_get_weather_missing_city(0.011s) - ✅
test_post_weather_missing_body(0.013s) - ✅
test_post_weather_invalid_json(0.014s) - ✅
test_post_weather_client_error(0.021s) - ✅
test_invalid_endpoint(0.011s) - ✅
test_weather_cache_invalidation(0.021s) - ✅
test_cache_with_different_locations(0.027s) - ✅
test_weather_caching_same_bucket(0.017s) - ✅
test_cache_size_configuration(0.001s) - ✅
test_invalid_content_type_post(0.007s) - ✅
test_malformed_json_body(0.010s) - ✅
test_cache_duration_configuration(0.001s) - ✅
test_oversized_request_body(0.011s) - ✅
test_x_request_id_header(0.011s) - ✅
test_invalid_http_method(0.010s) - ✅
test_cache_zero_duration(0.012s) - ✅
test_weather_coordinates_endpoint(0.767s) - ✅
test_weather_coordinates_missing_params(0.021s) - ✅
test_weather_coordinates_invalid_latitude(0.011s) - ✅
test_recent_searches_delete(0.010s) - ✅
test_recent_searches_get(0.017s) - ✅
test_get_weather_client_error(0.026s) - ✅
test_versioned_weather_get(0.650s) - ✅
test_versioned_weather_post(0.015s) - ✅
test_weather_coordinates_invalid_longitude(0.008s)
test_client¶
- ✅
test_extract_humidity(0.043s) - ✅
test_weather_client_initialization(0.041s) - ✅
test_get_weather_request_exception(0.044s) - ✅
test_extract_weather_from_json_invalid_json(0.043s) - ✅
test_extract_weather_from_json_missing_keys(0.039s) - ✅
test_weather_client_context_manager(0.056s) - ✅
test_fahrenheit_to_celsius_conversion(0.069s) - ✅
test_extract_wind_speed(0.038s) - ✅
test_extract_weather_from_json_success(0.042s) - ✅
test_get_weather_with_json_extraction(0.042s) - ✅
test_extract_temperature(0.069s) - ✅
test_extract_temperature_not_found(0.040s) - ✅
test_extract_weather_from_json_no_script_tag(0.036s) - ✅
test_get_weather_fallback_to_html(0.075s) - ✅
test_extract_condition_not_found(0.039s) - ✅
test_extract_humidity_not_found(0.045s) - ✅
test_extract_condition(0.043s) - ✅
test_humidity_extraction_with_parent_element(0.038s) - ✅
test_extract_weather_json_empty_forecast(0.039s) - ✅
test_extract_wind_speed_not_found(0.038s) - ✅
test_async_get_weather_by_coordinates_geocode_failure(0.106s) - ✅
test_get_weather_by_coordinates_geocode_failure(0.004s) - ✅
test_get_weather_by_coordinates_geocode_exception(0.004s) - ✅
test_mph_to_kmh_conversion(0.040s) - ✅
test_extract_weather_json_no_hourly(0.042s) - ✅
test_async_get_weather_by_coordinates_success(0.129s) - ✅
test_ms_to_kmh_conversion(0.040s) - ✅
test_extract_weather_json_empty_hourly(0.037s) - ✅
test_async_get_weather_by_coordinates_geocode_exception(0.044s) - ✅
test_extract_weather_json_exception(0.044s)
test_models¶
- ✅
test_location_creation(0.002s) - ✅
test_location_with_coordinates(0.001s) - ✅
test_weather_data_creation(0.001s) - ✅
test_weather_data_validation(0.001s)
Unit Tests (Python 3.12)¶
Summary: 66/66 passed • Duration: 4.84s
test_api¶
- ✅
test_health_check(0.030s) - ✅
test_liveness_probe(0.007s) - ✅
test_get_weather_success(0.044s) - ✅
test_readiness_probe(0.149s) - ✅
test_post_weather_missing_body(0.007s) - ✅
test_get_weather_client_error(0.011s) - ✅
test_post_weather_client_error(0.012s) - ✅
test_post_weather_invalid_json(0.006s) - ✅
test_invalid_endpoint(0.006s) - ✅
test_weather_caching_same_bucket(0.011s) - ✅
test_weather_cache_invalidation(0.010s) - ✅
test_get_weather_missing_parameters(0.035s) - ✅
test_cache_with_different_locations(0.009s) - ✅
test_cache_size_configuration(0.001s) - ✅
test_cache_duration_configuration(0.001s) - ✅
test_invalid_content_type_post(0.008s) - ✅
test_malformed_json_body(0.040s) - ✅
test_get_weather_missing_city(0.010s) - ✅
test_oversized_request_body(0.010s) - ✅
test_post_weather_missing_fields(0.026s) - ✅
test_x_request_id_header(0.007s) - ✅
test_cache_zero_duration(0.012s) - ✅
test_weather_coordinates_endpoint(1.069s) - ✅
test_weather_coordinates_missing_params(0.011s) - ✅
test_invalid_http_method(0.010s) - ✅
test_post_weather_success(0.015s) - ✅
test_weather_coordinates_invalid_longitude(0.009s) - ✅
test_recent_searches_get(0.009s) - ✅
test_versioned_weather_get(0.470s) - ✅
test_recent_searches_delete(0.009s) - ✅
test_versioned_weather_post(0.009s) - ✅
test_weather_coordinates_invalid_latitude(0.005s)
test_client¶
- ✅
test_extract_humidity(0.031s) - ✅
test_weather_client_initialization(0.028s) - ✅
test_get_weather_request_exception(0.041s) - ✅
test_extract_weather_from_json_invalid_json(0.034s) - ✅
test_extract_weather_from_json_missing_keys(0.035s) - ✅
test_extract_wind_speed(0.028s) - ✅
test_weather_client_context_manager(0.024s) - ✅
test_fahrenheit_to_celsius_conversion(0.124s) - ✅
test_extract_temperature(0.104s) - ✅
test_extract_weather_from_json_success(0.037s) - ✅
test_get_weather_with_json_extraction(0.031s) - ✅
test_extract_weather_from_json_no_script_tag(0.025s) - ✅
test_get_weather_fallback_to_html(0.118s) - ✅
test_extract_weather_json_empty_forecast(0.034s) - ✅
test_extract_condition(0.025s) - ✅
test_extract_weather_json_no_hourly(0.026s) - ✅
test_extract_temperature_not_found(0.035s) - ✅
test_extract_humidity_not_found(0.026s) - ✅
test_extract_weather_json_empty_hourly(0.024s) - ✅
test_extract_condition_not_found(0.030s) - ✅
test_extract_wind_speed_not_found(0.028s) - ✅
test_extract_weather_json_exception(0.024s) - ✅
test_humidity_extraction_with_parent_element(0.027s) - ✅
test_mph_to_kmh_conversion(0.025s) - ✅
test_async_get_weather_by_coordinates_geocode_failure(0.156s) - ✅
test_get_weather_by_coordinates_geocode_failure(0.005s) - ✅
test_get_weather_by_coordinates_geocode_exception(0.003s) - ✅
test_ms_to_kmh_conversion(0.025s) - ✅
test_async_get_weather_by_coordinates_success(0.139s) - ✅
test_async_get_weather_by_coordinates_geocode_exception(0.024s)
test_models¶
- ✅
test_location_with_coordinates(0.001s) - ✅
test_weather_data_creation(0.002s) - ✅
test_weather_data_validation(0.001s) - ✅
test_location_creation(0.001s)
Security Tests (Python 3.10)¶
Summary: 64/64 passed • Duration: 2.69s
TestAPIRateLimiting¶
- ✅
test_multiple_valid_requests(0.020s) - ✅
test_multiple_invalid_requests(0.025s)
TestAPISecurityGET¶
- ✅
test_path_traversal_attempts(0.030s) - ✅
test_empty_parameters(0.029s) - ✅
test_command_injection_attempts(0.013s) - ✅
test_whitespace_only_parameters(0.007s) - ✅
test_null_bytes(0.003s) - ✅
test_oversized_input(0.020s) - ✅
test_sql_injection_attempts(0.018s) - ✅
test_xss_attempts(0.015s)
TestAPISecurityPOST¶
- ✅
test_sql_injection_in_json(0.029s) - ✅
test_xss_in_json(0.007s) - ✅
test_malformed_json(0.014s) - ✅
test_non_dict_json(0.017s) - ✅
test_non_string_types(0.019s) - ✅
test_oversized_json_values(0.008s)
TestCorsConfiguration¶
- ✅
test_explicit_origins_are_normalized(0.001s) - ✅
test_unset_origins_return_empty_list(0.001s) - ✅
test_wildcard_mixed_with_explicit_origins_is_rejected(0.005s) - ✅
test_wildcard_origin_is_rejected(0.002s) - ✅
test_cors_response_requires_an_allowed_origin(0.085s)
TestHTTPErrorHandlers¶
- ✅
test_415_unsupported_media_type(0.008s) - ✅
test_405_method_not_allowed(0.009s) - ✅
test_invalid_json_syntax(0.014s) - ✅
test_413_payload_too_large(0.021s) - ✅
test_content_type_without_charset(0.746s) - ✅
test_null_bytes_in_input(0.005s) - ✅
test_400_bad_request_missing_required_fields(0.015s) - ✅
test_404_not_found(0.006s) - ✅
test_very_long_query_string(0.013s) - ✅
test_multiple_content_types(0.007s) - ✅
test_unicode_normalization_attack(0.007s) - ✅
test_case_sensitive_endpoints(0.008s) - ✅
test_trailing_slash_handling(0.012s) - ✅
test_header_injection_attempts(0.004s) - ✅
test_double_slash_in_path(0.006s) - ✅
test_repeated_parameters(0.549s) - ✅
test_url_encoding_in_parameters(0.537s) - ✅
test_parameter_without_value(0.007s) - ✅
test_response_headers_present(0.004s) - ✅
test_cors_preflight_request(0.005s) - ✅
test_empty_request_body_post(0.005s)
TestInputValidation¶
- ✅
test_whitespace_only(0.002s) - ✅
test_valid_input(0.002s) - ✅
test_whitespace_trimming(0.001s) - ✅
test_empty_string(0.001s) - ✅
test_unicode_cities_allowed(0.002s) - ✅
test_exceeds_max_length(0.001s) - ✅
test_non_string_type(0.001s) - ✅
test_none_value(0.001s) - ✅
test_special_characters_rejected(0.001s)
test_security_reports¶
- ✅
test_clean_reports_pass(0.003s) - ✅
test_high_bandit_finding_fails(0.002s) - ✅
test_lower_bandit_severity_does_not_fail(0.002s) - ✅
test_scanner_error_and_missing_report_fail(0.002s) - ✅
test_missing_required_report_fields_fail[bandit-report.json-results](0.002s) - ✅
test_missing_required_report_fields_fail[semgrep-report.json-results](0.002s) - ✅
test_missing_required_report_fields_fail[pip-audit-report.json-dependencies](0.002s) - ✅
test_required_report_fields_must_be_lists[None-bandit-report.json-results](0.002s) - ✅
test_required_report_fields_must_be_lists[None-semgrep-report.json-results](0.002s) - ✅
test_required_report_fields_must_be_lists[None-pip-audit-report.json-dependencies](0.002s) - ✅
test_required_report_fields_must_be_lists[invalid_value1-bandit-report.json-results](0.002s) - ✅
test_required_report_fields_must_be_lists[invalid_value1-semgrep-report.json-results](0.002s) - ✅
test_required_report_fields_must_be_lists[invalid_value1-pip-audit-report.json-dependencies](0.002s)
Security Tests (Python 3.11)¶
Summary: 64/64 passed • Duration: 3.82s
TestAPIRateLimiting¶
- ✅
test_multiple_valid_requests(0.041s) - ✅
test_multiple_invalid_requests(0.045s)
TestAPISecurityGET¶
- ✅
test_path_traversal_attempts(0.049s) - ✅
test_empty_parameters(0.044s) - ✅
test_sql_injection_attempts(0.029s) - ✅
test_xss_attempts(0.021s) - ✅
test_whitespace_only_parameters(0.011s) - ✅
test_command_injection_attempts(0.024s) - ✅
test_null_bytes(0.006s) - ✅
test_oversized_input(0.038s)
TestAPISecurityPOST¶
- ✅
test_sql_injection_in_json(0.050s) - ✅
test_xss_in_json(0.011s) - ✅
test_non_dict_json(0.028s) - ✅
test_malformed_json(0.026s) - ✅
test_non_string_types(0.029s) - ✅
test_oversized_json_values(0.010s)
TestCorsConfiguration¶
- ✅
test_wildcard_mixed_with_explicit_origins_is_rejected(0.004s) - ✅
test_explicit_origins_are_normalized(0.002s) - ✅
test_unset_origins_return_empty_list(0.002s) - ✅
test_cors_response_requires_an_allowed_origin(0.032s) - ✅
test_wildcard_origin_is_rejected(0.003s)
TestHTTPErrorHandlers¶
- ✅
test_content_type_without_charset(0.479s) - ✅
test_415_unsupported_media_type(0.010s) - ✅
test_405_method_not_allowed(0.014s) - ✅
test_invalid_json_syntax(0.022s) - ✅
test_413_payload_too_large(0.034s) - ✅
test_404_not_found(0.010s) - ✅
test_unicode_normalization_attack(0.011s) - ✅
test_null_bytes_in_input(0.007s) - ✅
test_very_long_query_string(0.029s) - ✅
test_400_bad_request_missing_required_fields(0.021s) - ✅
test_header_injection_attempts(0.010s) - ✅
test_case_sensitive_endpoints(0.058s) - ✅
test_trailing_slash_handling(0.018s) - ✅
test_multiple_content_types(0.009s) - ✅
test_repeated_parameters(0.645s) - ✅
test_url_encoding_in_parameters(0.563s) - ✅
test_double_slash_in_path(0.009s) - ✅
test_response_headers_present(0.011s) - ✅
test_empty_request_body_post(0.007s) - ✅
test_cors_preflight_request(0.007s) - ✅
test_parameter_without_value(0.007s)
TestInputValidation¶
- ✅
test_valid_input(0.004s) - ✅
test_unicode_cities_allowed(0.003s) - ✅
test_whitespace_only(0.006s) - ✅
test_whitespace_trimming(0.001s) - ✅
test_empty_string(0.001s) - ✅
test_exceeds_max_length(0.001s) - ✅
test_non_string_type(0.001s) - ✅
test_none_value(0.002s) - ✅
test_special_characters_rejected(0.002s)
test_security_reports¶
- ✅
test_clean_reports_pass(0.003s) - ✅
test_high_bandit_finding_fails(0.003s) - ✅
test_lower_bandit_severity_does_not_fail(0.003s) - ✅
test_scanner_error_and_missing_report_fail(0.003s) - ✅
test_missing_required_report_fields_fail[bandit-report.json-results](0.003s) - ✅
test_missing_required_report_fields_fail[semgrep-report.json-results](0.003s) - ✅
test_missing_required_report_fields_fail[pip-audit-report.json-dependencies](0.003s) - ✅
test_required_report_fields_must_be_lists[None-bandit-report.json-results](0.003s) - ✅
test_required_report_fields_must_be_lists[None-semgrep-report.json-results](0.003s) - ✅
test_required_report_fields_must_be_lists[None-pip-audit-report.json-dependencies](0.003s) - ✅
test_required_report_fields_must_be_lists[invalid_value1-bandit-report.json-results](0.003s) - ✅
test_required_report_fields_must_be_lists[invalid_value1-semgrep-report.json-results](0.003s) - ✅
test_required_report_fields_must_be_lists[invalid_value1-pip-audit-report.json-dependencies](0.003s)
Security Tests (Python 3.12)¶
Summary: 64/64 passed • Duration: 3.95s
TestAPIRateLimiting¶
- ✅
test_multiple_valid_requests(0.026s) - ✅
test_multiple_invalid_requests(0.033s)
TestAPISecurityGET¶
- ✅
test_path_traversal_attempts(0.044s) - ✅
test_sql_injection_attempts(0.026s) - ✅
test_empty_parameters(0.040s) - ✅
test_xss_attempts(0.016s) - ✅
test_command_injection_attempts(0.016s) - ✅
test_whitespace_only_parameters(0.010s) - ✅
test_null_bytes(0.004s) - ✅
test_oversized_input(0.027s)
TestAPISecurityPOST¶
- ✅
test_sql_injection_in_json(0.041s) - ✅
test_xss_in_json(0.010s) - ✅
test_malformed_json(0.018s) - ✅
test_non_dict_json(0.061s) - ✅
test_non_string_types(0.020s) - ✅
test_oversized_json_values(0.008s)
TestCorsConfiguration¶
- ✅
test_wildcard_mixed_with_explicit_origins_is_rejected(0.005s) - ✅
test_explicit_origins_are_normalized(0.001s) - ✅
test_unset_origins_return_empty_list(0.001s) - ✅
test_cors_response_requires_an_allowed_origin(0.028s) - ✅
test_wildcard_origin_is_rejected(0.003s)
TestHTTPErrorHandlers¶
- ✅
test_405_method_not_allowed(0.009s) - ✅
test_415_unsupported_media_type(0.008s) - ✅
test_413_payload_too_large(0.030s) - ✅
test_invalid_json_syntax(0.065s) - ✅
test_404_not_found(0.006s) - ✅
test_null_bytes_in_input(0.005s) - ✅
test_very_long_query_string(0.018s) - ✅
test_unicode_normalization_attack(0.008s) - ✅
test_400_bad_request_missing_required_fields(0.063s) - ✅
test_header_injection_attempts(0.005s) - ✅
test_trailing_slash_handling(0.013s) - ✅
test_multiple_content_types(0.011s) - ✅
test_url_encoding_in_parameters(0.443s) - ✅
test_double_slash_in_path(0.008s) - ✅
test_repeated_parameters(0.457s) - ✅
test_content_type_without_charset(0.647s) - ✅
test_case_sensitive_endpoints(0.007s) - ✅
test_response_headers_present(0.007s) - ✅
test_parameter_without_value(0.005s) - ✅
test_cors_preflight_request(0.006s) - ✅
test_empty_request_body_post(0.005s)
TestInputValidation¶
- ✅
test_whitespace_only(0.004s) - ✅
test_unicode_cities_allowed(0.003s) - ✅
test_exceeds_max_length(0.001s) - ✅
test_valid_input(0.003s) - ✅
test_whitespace_trimming(0.001s) - ✅
test_non_string_type(0.001s) - ✅
test_special_characters_rejected(0.001s) - ✅
test_empty_string(0.003s) - ✅
test_none_value(0.001s)
test_security_reports¶
- ✅
test_clean_reports_pass(0.003s) - ✅
test_high_bandit_finding_fails(0.003s) - ✅
test_lower_bandit_severity_does_not_fail(0.003s) - ✅
test_scanner_error_and_missing_report_fail(0.002s) - ✅
test_missing_required_report_fields_fail[bandit-report.json-results](0.002s) - ✅
test_missing_required_report_fields_fail[semgrep-report.json-results](0.002s) - ✅
test_missing_required_report_fields_fail[pip-audit-report.json-dependencies](0.002s) - ✅
test_required_report_fields_must_be_lists[None-bandit-report.json-results](0.002s) - ✅
test_required_report_fields_must_be_lists[None-semgrep-report.json-results](0.002s) - ✅
test_required_report_fields_must_be_lists[None-pip-audit-report.json-dependencies](0.002s) - ✅
test_required_report_fields_must_be_lists[invalid_value1-bandit-report.json-results](0.002s) - ✅
test_required_report_fields_must_be_lists[invalid_value1-semgrep-report.json-results](0.002s) - ✅
test_required_report_fields_must_be_lists[invalid_value1-pip-audit-report.json-dependencies](0.002s)
🔗 Related Documentation¶
- Coverage Report - Detailed code coverage analysis
- Security Report - Security scan results
- CI/CD Status - Pipeline execution details
This report is auto-generated from CI/CD pipeline execution.
Generated by scripts/generate_reports.py.