Code Coverage Analysis: class_definitions.py
Total Coverage: ~66% (108 statements, 37 missing)
General Bug
- testing-batch in README does not work
- repair testing-batch in README to show current test-status on main.
Uncovered Methods and Branches
1. ENTIRELY UNCOVERED METHODS
_read_mappings() [Lines 132-140]
- Reason: Called only during
__init__ (which is mocked in tests)
- What's missed:
- Line 136:
if not self.mappings_path.exists() - NEVER TESTED (FileNotFoundError branch)
- The successful file reading path is indirectly tested but not directly verified
_read_pypsa_network_collection() [Lines 142-146]
- Reason: Called only during
__init__ (which is mocked in tests)
- What's missed:
- Line 145: The network file listing and filtering logic
- Error handling when network directory doesn't exist
read_definitions() [Lines 148-162]
- Reason: Called only during
__init__ (which is mocked in tests)
- What's missed:
- Line 159: The actual nomenclature.DataStructureDefinition instantiation
_aggregate_to_country() [Lines 221-252]
- Reason: Only called indirectly through
_select_aggregation_result()
- What's missed:
- Lines 222-248: The logic when
self.country == "all" - extracting 2-letter country codes
- Lines 243-252: The logic when
self.country is NOT "all" - filtering to specific country regions
_filter_to_regions() [Lines 254-297]
- Reason: Only called indirectly through
_select_aggregation_result()
- What's missed:
- Line 256: When
self.country == "all" (returns result unchanged)
- Lines 257-276: Filtering logic for specific country codes
_select_aggregation_result() [Lines 299-304]
- Reason: Called indirectly through
_postprocess_statistics_result() but never directly
- What's missed:
- Both branches:
aggregation_level == "country" and aggregation_level == "region" are not sufficiently tested
_map_unit_level() [Lines 306-318]
- Reason: Called indirectly through
_postprocess_statistics_result()
- What's missed:
- Line 308: The
pd.MultiIndex branch
- Lines 312-314: The single index mapping logic
_postprocess_group_levels() [Lines 320-327]
- Reason: Called indirectly through
_postprocess_statistics_result()
- What's missed:
- All three branches for different aggregation level/country combinations
_postprocess_statistics_result() [Lines 329-370]
- Reason: Called within
calculate_variables_values() but logic is not directly tested
- What's missed:
- The entire method flow for different aggregation scenarios
structure_pyam_from_pandas() [Lines 372-433]
- Reason: Indirectly called, but key branches not exercised
- What's missed:
- Line 381: Column renaming logic
- Lines 386-409: Multi-country (with
country == "all") vs single country branches
- Lines 411-419: Region-level aggregation branch
_get_network_config() [Lines 435-464]
- Reason: Called in
calculate_variables_values() but indirectly
- What's missed:
- Line 439: The
if matching_files: branch
- Lines 440-442: Multiple config files warning path
- Lines 443-453: Try-except block (success and error cases)
- Lines 454-462: No config file warning path
2. PARTIALLY UNCOVERED METHODS
__init__() [Lines 24-113] - ~70% coverage
Missing branches:
- Line 35-40:
if network_results_path is None: - NOT TESTED (ValueError)
- Line 46-50:
if not self.network_results_path.exists(): - NOT TESTED (FileNotFoundError)
- Line 52-56:
if definitions_path is None: - NOT TESTED (ValueError)
- Line 62-66:
if not self.definitions_path.exists(): - NOT TESTED (FileNotFoundError)
- Line 75-79:
if self.model_name == None or self.scenario_name == None: - NOT TESTED (ValueError)
- Line 96-98: The
else branch for if self.country == "all" (default path for specific country)
calculate_variables_values() [Lines 466-535] - ~50% coverage
Missing branches:
- Lines 491-495: Loop logic when
results is empty (no results for a year)
- Lines 516-523: The
if len(container_investment_years) > 0: and merge logic
- Specifically: What happens when container_investment_years has 0 items?
- What happens when container_investment_years has exactly 1 item?
- Lines 525-531: The
else branch when aggregate_per_year == False
- The timestamp year replacement logic
write_output_to_xlsx() [Lines 537-570] - ~70% coverage
Missing branches:
- Line 516: Error path when
self.dsd_with_values is None - TESTED ✓
- Line 528-532: When
self.country == "all" and aggregate_per_year == True
- Lines 534-535: When
self.country == "all" and aggregate_per_year == False
3. EDGE CASES NOT TESTED
-
Error handling in __init__() for missing config keys
network_results_path missing
definitions_path missing
model_name / scenario_name missing
- Invalid
aggregation_level values other than "country" and "region"
- Invalid
aggregate_per_year values (not a boolean)
-
Config file loading errors
- YAML parsing errors in
_read_config()
- Missing mapping file in
_read_mappings()
- YAML parsing errors in
_get_network_config()
-
_aggregate_to_country() with different country configurations
- Country == "all" with multi-country locations
- Single country filtering logic
-
calculate_variables_values() with edge cases
- Zero investment years
- Single investment year with multiple variables
- Multiple investment years with merging
-
structure_pyam_from_pandas() branches
- Region-level aggregation (aggregation_level == "region")
- Country == "all" with country code mapping
-
write_output_to_xlsx() scenarios
- aggregate_per_year == False with country == "all"
- aggregate_per_year == False with specific country
Summary: Top Priorities for Testing
| Priority |
Method |
Lines |
Issue |
| HIGH |
__init__() error branches |
35-79 |
Missing validation error tests |
| HIGH |
calculate_variables_values() |
491-531 |
Missing core calculation scenarios |
| HIGH |
_aggregate_to_country() |
222-252 |
Missing both country branches |
| MEDIUM |
structure_pyam_from_pandas() |
381-419 |
Missing aggregation branches |
| MEDIUM |
_get_network_config() |
439-462 |
Missing config loading branches |
| LOW |
_map_unit_level() |
308-318 |
Indirect coverage exists |
| LOW |
_filter_to_regions() |
256-276 |
Indirect coverage exists |
Key Recommendation
The highest-impact additions would be to:
- Test
__init__() with invalid/missing configuration values
- Test
calculate_variables_values() with multiple investment years and different aggregation modes
- Test
_aggregate_to_country() with both country=="all" and single-country scenarios
- Add direct unit tests for
_get_network_config() error handling
Code Coverage Analysis: class_definitions.py
Total Coverage: ~66% (108 statements, 37 missing)
General Bug
Uncovered Methods and Branches
1. ENTIRELY UNCOVERED METHODS
_read_mappings()[Lines 132-140]__init__(which is mocked in tests)if not self.mappings_path.exists()- NEVER TESTED (FileNotFoundError branch)_read_pypsa_network_collection()[Lines 142-146]__init__(which is mocked in tests)read_definitions()[Lines 148-162]__init__(which is mocked in tests)_aggregate_to_country()[Lines 221-252]_select_aggregation_result()self.country == "all"- extracting 2-letter country codesself.countryis NOT "all" - filtering to specific country regions_filter_to_regions()[Lines 254-297]_select_aggregation_result()self.country == "all"(returns result unchanged)_select_aggregation_result()[Lines 299-304]_postprocess_statistics_result()but never directlyaggregation_level == "country"andaggregation_level == "region"are not sufficiently tested_map_unit_level()[Lines 306-318]_postprocess_statistics_result()pd.MultiIndexbranch_postprocess_group_levels()[Lines 320-327]_postprocess_statistics_result()_postprocess_statistics_result()[Lines 329-370]calculate_variables_values()but logic is not directly testedstructure_pyam_from_pandas()[Lines 372-433]country == "all") vs single country branches_get_network_config()[Lines 435-464]calculate_variables_values()but indirectlyif matching_files:branch2. PARTIALLY UNCOVERED METHODS
__init__()[Lines 24-113] - ~70% coverageMissing branches:
if network_results_path is None:- NOT TESTED (ValueError)if not self.network_results_path.exists():- NOT TESTED (FileNotFoundError)if definitions_path is None:- NOT TESTED (ValueError)if not self.definitions_path.exists():- NOT TESTED (FileNotFoundError)if self.model_name == None or self.scenario_name == None:- NOT TESTED (ValueError)elsebranch forif self.country == "all"(default path for specific country)calculate_variables_values()[Lines 466-535] - ~50% coverageMissing branches:
resultsis empty (no results for a year)if len(container_investment_years) > 0:and merge logicelsebranch whenaggregate_per_year == Falsewrite_output_to_xlsx()[Lines 537-570] - ~70% coverageMissing branches:
self.dsd_with_valuesis None - TESTED ✓self.country == "all"andaggregate_per_year == Trueself.country == "all"andaggregate_per_year == False3. EDGE CASES NOT TESTED
Error handling in
__init__()for missing config keysnetwork_results_pathmissingdefinitions_pathmissingmodel_name/scenario_namemissingaggregation_levelvalues other than "country" and "region"aggregate_per_yearvalues (not a boolean)Config file loading errors
_read_config()_read_mappings()_get_network_config()_aggregate_to_country()with different country configurationscalculate_variables_values()with edge casesstructure_pyam_from_pandas()brancheswrite_output_to_xlsx()scenariosSummary: Top Priorities for Testing
__init__()error branchescalculate_variables_values()_aggregate_to_country()structure_pyam_from_pandas()_get_network_config()_map_unit_level()_filter_to_regions()Key Recommendation
The highest-impact additions would be to:
__init__()with invalid/missing configuration valuescalculate_variables_values()with multiple investment years and different aggregation modes_aggregate_to_country()with both country=="all" and single-country scenarios_get_network_config()error handling