diff --git a/codecov.yml b/codecov.yml index cf1d832..d4ed5a1 100644 --- a/codecov.yml +++ b/codecov.yml @@ -9,6 +9,14 @@ coverage: threshold: 5% # Allow 5% drop without failing if_no_uploads: error # Fail if no coverage data only_pulls: false # Check coverage on all commits + # Custom group for tests module with higher threshold + tests: + target: 99% # Very high threshold for test files + threshold: 1% # Allow only 1% drop + paths: + - "tests/**" # Coverage for all test files + if_no_uploads: error + only_pulls: false patch: default: target: 85% # Lower threshold for new code diff --git a/tests/benchmark/test_slow_benchmarks.py b/tests/benchmark/test_slow_benchmarks.py index ab2059f..4cf2ad1 100644 --- a/tests/benchmark/test_slow_benchmarks.py +++ b/tests/benchmark/test_slow_benchmarks.py @@ -46,6 +46,12 @@ def _make_packet_list(generator): # Make sure the result actually makes sense assert len(packet_list) == 7200 + + # Also verify the helper functions work correctly for coverage + packet_fh.seek(0) + test_gen = generators.ccsds_generator(packet_fh) + test_list = _make_packet_list(test_gen) + assert len(test_list) == 7200 finally: # Ensure filehandler is closed packet_fh.close() @@ -79,6 +85,12 @@ def _make_packet_list(generator): # Make sure the result actually makes sense assert len(packet_list) == 78 + + # Also verify the helper functions work correctly for coverage + packet_fh.seek(0) + test_gen = generators.ccsds_generator(packet_fh, show_progress=True) + test_list = _make_packet_list(test_gen) + assert len(test_list) == 78 finally: # Ensure filehandler is closed packet_fh.close() diff --git a/tests/conftest.py b/tests/conftest.py index 37f6384..4efc465 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -47,12 +47,6 @@ def jpss_test_data_dir(test_data_dir): return test_data_dir / "jpss" -@pytest.fixture -def clarreo_test_data_dir(test_data_dir): - """CLARREO test data directory""" - return test_data_dir / "clarreo" - - @pytest.fixture def suda_test_data_dir(test_data_dir): """SUDA test data directory""" diff --git a/tests/unit/test_common.py b/tests/unit/test_common.py index 07b1fc3..199a6fd 100644 --- a/tests/unit/test_common.py +++ b/tests/unit/test_common.py @@ -32,6 +32,8 @@ def ignored(self, x): a.public += 1 # Change an attribute that _does_ get compared with pytest.raises(AssertionError): assert a == b + # Test that the ignored method works (even though it's ignored in comparison) + assert a.ignored(5) == 10 @pytest.mark.parametrize( diff --git a/tests/unit/test_xtce/test_calibrators.py b/tests/unit/test_xtce/test_calibrators.py index 8564821..04ac9a2 100644 --- a/tests/unit/test_xtce/test_calibrators.py +++ b/tests/unit/test_xtce/test_calibrators.py @@ -327,6 +327,15 @@ def test_context_calibrator_calibrate(context_calibrator, parsed_data, parsed_va ], ), ), + # Error case: invalid spline point value + ( + f""" + + + +""", + ValueError("could not convert string to float"), + ), ], ) def test_spline_calibrator(elmaker, xtce_parser, xml_string: str, expectation): @@ -406,6 +415,15 @@ def test_spline_calibrator_calibrate(xq, order, extrapolate, expectation): ] ), ), + # Error case: invalid coefficient value + ( + f""" + + + +""", + ValueError("could not convert string to float"), + ), ], ) def test_polynomial_calibrator(elmaker, xtce_parser, xml_string: str, expectation): diff --git a/tests/unit/test_xtce/test_comparisons.py b/tests/unit/test_xtce/test_comparisons.py index fcb696a..153452c 100644 --- a/tests/unit/test_xtce/test_comparisons.py +++ b/tests/unit/test_xtce/test_comparisons.py @@ -394,6 +394,16 @@ def test_condition_validity_check(args, kwargs, expected_error, expected_error_m ), True, ), + # Error case: invalid XML structure (missing ComparisonOperator) + ( + f""" + + + +""", + SpacePacket(**{"P": common.IntParameter(100, 4)}), + AttributeError("'NoneType' object has no attribute 'text'"), + ), ], ) def test_boolean_expression(elmaker, xtce_parser, xml_string, test_parsed_data, expected_result): diff --git a/tests/unit/test_xtce/test_encodings.py b/tests/unit/test_xtce/test_encodings.py index b4a7c1f..2d8d5ac 100644 --- a/tests/unit/test_xtce/test_encodings.py +++ b/tests/unit/test_xtce/test_encodings.py @@ -294,6 +294,13 @@ def test_string_data_encoding_validation(args, kwargs, expected_error, expected_ ], ), ), + # Error case: invalid sizeInBits value + ( + f""" + +""", + ValueError("invalid literal for int()"), + ), ], ) def test_integer_data_encoding(elmaker, xtce_parser, xml_string: str, expectation): @@ -520,6 +527,19 @@ def test_float_data_encoding_validation(args, kwargs, expected_error, expected_e ] ), ), + # Error case: invalid fixed size value + ( + f""" + + + + invalid + + + +""", + ValueError("invalid literal for int()"), + ), ], ) def test_binary_data_encoding(elmaker, xtce_parser, xml_string: str, expectation): diff --git a/tests/unit/test_xtce/test_parameter_types.py b/tests/unit/test_xtce/test_parameter_types.py index 842197c..8f681cd 100644 --- a/tests/unit/test_xtce/test_parameter_types.py +++ b/tests/unit/test_xtce/test_parameter_types.py @@ -62,6 +62,21 @@ encoding=encodings.StringDataEncoding(fixed_raw_length=40, termination_character="00"), ), ), + # Error case: missing name attribute + ( + f""" + + + + + 40 + + + + +""", + ValueError("Parameter Type name attribute is required"), + ), ], ) def test_string_parameter_type(elmaker, xtce_parser, xml_string: str, expectation): @@ -168,6 +183,15 @@ def test_string_parameter_type(elmaker, xtce_parser, xml_string: str, expectatio ), ), ), + # Error case: missing name attribute + ( + f""" + + + +""", + ValueError("Parameter Type name attribute is required"), + ), ], ) def test_integer_parameter_type(elmaker, xtce_parser, xml_string: str, expectation): @@ -289,6 +313,15 @@ def test_integer_parameter_type(elmaker, xtce_parser, xml_string: str, expectati ), ), ), + # Error case: missing name attribute + ( + f""" + + + +""", + ValueError("Parameter Type name attribute is required"), + ), ], ) def test_float_parameter_type(elmaker, xtce_parser, xml_string: str, expectation): @@ -420,6 +453,18 @@ def test_float_parameter_type(elmaker, xtce_parser, xml_string: str, expectation }, ), ), + # Error case: missing name attribute + ( + f""" + + + + + + +""", + KeyError("name"), + ), ], ) def test_enumerated_parameter_type(elmaker, xtce_parser, xml_string: str, expectation): @@ -517,6 +562,21 @@ def test_enumerated_parameter_type(elmaker, xtce_parser, xml_string: str, expect encoding=encodings.BinaryDataEncoding(size_reference_parameter="SizeFromThisParameter"), ), ), + # Error case: missing name attribute + ( + f""" + + + + + 8 + + + + +""", + ValueError("Parameter Type name attribute is required"), + ), ], ) def test_binary_parameter_type(elmaker, xtce_parser, xml_string: str, expectation): @@ -594,6 +654,15 @@ def test_binary_parameter_type(elmaker, xtce_parser, xml_string: str, expectatio encoding=encodings.StringDataEncoding(fixed_raw_length=40, termination_character="00"), ), ), + # Error case: missing name attribute + ( + f""" + + + +""", + ValueError("Parameter Type name attribute is required"), + ), ], ) def test_boolean_parameter_type(elmaker, xtce_parser, xml_string, expectation): @@ -732,6 +801,17 @@ def test_boolean_parameter_type(elmaker, xtce_parser, xml_string, expectation): ), ), ), + # Error case: missing name attribute + ( + f""" + + + + + +""", + KeyError("name"), + ), ], ) def test_absolute_time_parameter_type(elmaker, xtce_parser, xml_string, expectation):