Skip to content

Review testing routines #32

@maxnutz

Description

@maxnutz

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

  1. 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)
  2. Config file loading errors

    • YAML parsing errors in _read_config()
    • Missing mapping file in _read_mappings()
    • YAML parsing errors in _get_network_config()
  3. _aggregate_to_country() with different country configurations

    • Country == "all" with multi-country locations
    • Single country filtering logic
  4. calculate_variables_values() with edge cases

    • Zero investment years
    • Single investment year with multiple variables
    • Multiple investment years with merging
  5. structure_pyam_from_pandas() branches

    • Region-level aggregation (aggregation_level == "region")
    • Country == "all" with country code mapping
  6. 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:

  1. Test __init__() with invalid/missing configuration values
  2. Test calculate_variables_values() with multiple investment years and different aggregation modes
  3. Test _aggregate_to_country() with both country=="all" and single-country scenarios
  4. Add direct unit tests for _get_network_config() error handling

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions