Skip to content

feat: Add unit tests for JSONSummaryReporter#152

Open
Ayush-Patel-56 wants to merge 1 commit intokrkn-chaos:mainfrom
Ayush-Patel-56:fix/issue-149-json-reporter-tests
Open

feat: Add unit tests for JSONSummaryReporter#152
Ayush-Patel-56 wants to merge 1 commit intokrkn-chaos:mainfrom
Ayush-Patel-56:fix/issue-149-json-reporter-tests

Conversation

@Ayush-Patel-56
Copy link

@Ayush-Patel-56 Ayush-Patel-56 commented Feb 8, 2026

User description

Closes #149


PR Type

Tests, Bug Fixes


Description

Added unit test coverage for JSONSummaryReporter and addressed a few reporting bugs found during development.

The changes provide 100% coverage for the reporter logic, including ranking and fitness progression. I also updated GeneticAlgorithm to correctly populate end_time and completed_generations in the final output, as these were previously remaining at their default/empty values. Finally, I standardized all timestamps to UTC across the algorithm and runner to avoid TypeError risks with naive/aware datetime mixing.


Diagram Walkthrough

graph TD
    A[GeneticAlgorithm] -->|updates| B[Metadata]
    B -->|reports| C[JSONSummaryReporter]
    C -->|generates| D[results.json]
    E[KrknRunner] -->|calculates| F[Fitness UTC]
    F -->|stores| B
Loading

File Walkthrough

Relevant files
test_json_summary_reporter.pyAdd unit tests for JSONSummaryReporter

tests/unit/reporter/test_json_summary_reporter.py
  • Added comprehensive unit tests for the JSONSummaryReporter class.
  • Verified accuracy of run metadata, duration total, and fitness statistics.
  • Validated generation-wise fitness progression and top-10 ranking logic.
  • Confirmed correct scenario parameter extraction and results.json persistence.
Tests

Testing

  • All unit tests passed: python -m pytest tests/unit/reporter/test_json_summary_reporter.py
  • Verified 100% code coverage for the reporter class.
  • Confirmed linting passes with ruff and mypy.

@qodo-code-review
Copy link

ⓘ You are approaching your monthly quota for Qodo. Upgrade your plan

Review Summary by Qodo

Add unit tests for JSONSummaryReporter class

🧪 Tests

Grey Divider

Walkthroughs

Description
• Added comprehensive unit tests for JSONSummaryReporter class
• Validates run metadata, duration, and fitness statistics accuracy
• Tests generation-wise fitness progression and top-10 ranking logic
• Verifies results.json file persistence and content correctness
Diagram
flowchart LR
  A["Test Setup<br/>Population & Results"] -->|validates| B["JSONSummaryReporter"]
  B -->|generates| C["Summary Data"]
  C -->|checks| D["Metadata & Stats"]
  C -->|checks| E["Fitness Progression"]
  C -->|checks| F["Best Scenarios Ranking"]
  B -->|saves| G["results.json File"]
Loading

Grey Divider

File Changes

1. tests/unit/reporter/test_json_summary_reporter.py 🧪 Tests +111/-0

Unit tests for JSONSummaryReporter class

• Added 4 comprehensive test methods covering JSONSummaryReporter functionality
• Tests validate run metadata, duration calculation, and fitness statistics
• Verifies generation-wise fitness progression with average and best scores
• Tests top-10 best scenarios ranking and results.json file persistence
• Includes edge case testing for empty population scenarios

tests/unit/reporter/test_json_summary_reporter.py


Grey Divider

Qodo Logo

@Ayush-Patel-56 Ayush-Patel-56 force-pushed the fix/issue-149-json-reporter-tests branch from f6313ba to 18f88df Compare February 8, 2026 13:54
@qodo-code-review
Copy link

ⓘ You are approaching your monthly quota for Qodo. Upgrade your plan

Code Review by Qodo

🐞 Bugs (2) 📘 Rule violations (0) 📎 Requirement gaps (4)

Grey Divider


Action required

1. generate_summary assertions incomplete 📎 Requirement gap ✓ Correctness
Description
• The test_generate_summary_content test asserts only a small subset of the required
  generate_summary() output (e.g., run_id, duration_seconds, a couple summary stats, and a few
  progression values).
• This does not validate required run metadata (e.g., seed, timestamps), config summary, and the
  broader statistics/schema expectations, so regressions to results.json structure or key computed
  fields could still pass CI.
• As written, the test suite does not meet the checklist’s requirement to assert the unified summary
  dictionary’s required keys and correct values.
Code

tests/unit/reporter/test_json_summary_reporter.py[R56-66]

+        summary = reporter.generate_summary()
+
+        assert summary["run_id"] == "test-run"
+        assert summary["duration_seconds"] == 100.0
+        assert summary["summary"]["total_scenarios_executed"] == 6
+        assert summary["summary"]["best_fitness_score"] == 60.0
+        
+        assert summary["fitness_progression"][0]["average"] == 10.0
+        assert summary["fitness_progression"][1]["average"] == 50.0
+        assert summary["fitness_progression"][1]["best"] == 60.0
+
Evidence
PR Compliance ID 8 requires tests to assert the generate_summary() schema and key computed fields
(metadata/config/statistics/best_scenarios/fitness_progression). The added test only asserts a few
fields and does not validate the broader required structure and values.

Unit tests validate JSONSummaryReporter.generate_summary() output structure and key values
tests/unit/reporter/test_json_summary_reporter.py[56-66]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`generate_summary()` unit tests do not validate the required output schema and key computed fields described in the compliance checklist.

## Issue Context
Downstream consumers rely on `results.json` schema stability. Partial assertions (only a few keys) can allow breaking changes to pass CI.

## Fix Focus Areas
- tests/unit/reporter/test_json_summary_reporter.py[34-66]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Top-10 ranking checks partial 📎 Requirement gap ✓ Correctness
Description
• The best-scenarios test checks only the list length and the first entry’s rank/fitness, but it
  does not validate full sorting, rank increments, truncation correctness across all returned entries,
  or required fields for each item.
• This leaves gaps where incorrect ordering, missing fields, or wrong ranks for entries 2–10 would
  not be caught.
Code

tests/unit/reporter/test_json_summary_reporter.py[R81-86]

+        best = reporter.generate_summary()["best_scenarios"]
+        assert len(best) == 10
+        assert best[0]["rank"] == 1
+        assert best[0]["fitness_score"] == 140.0
+        assert best[0]["parameters"]["end"] == 10
+
Evidence
PR Compliance ID 10 requires verifying sorting, ranking, top-10 truncation, and required fields for
each entry. The test only checks len(best), and a few fields on best[0].

Unit tests cover _build_best_scenarios() sorting, ranking, and top-10 truncation
tests/unit/reporter/test_json_summary_reporter.py[81-86]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`_build_best_scenarios()` behavior (sorting/ranking/truncation and required fields) is only partially validated.

## Issue Context
Incorrect ordering or missing fields in `best_scenarios` can break downstream consumers even if the top item looks correct.

## Fix Focus Areas
- tests/unit/reporter/test_json_summary_reporter.py[67-86]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Missing minimal/zero-fitness edge cases 📎 Requirement gap ⛯ Reliability
Description
• The tests include an empty population case, but do not cover the other required edge cases:
  single-generation best_of_generation and explicit zero-fitness scenarios.
• Without these cases, failures or malformed output in minimal/degenerate runs can slip through CI.
Code

tests/unit/reporter/test_json_summary_reporter.py[R87-97]

+    def test_empty_population(self, minimal_config):
+        reporter = JSONSummaryReporter(
+            run_uuid="empty",
+            config=minimal_config,
+            seen_population={},
+            best_of_generation=[],
+        )
+        summary = reporter.generate_summary()
+        assert summary["summary"]["total_scenarios_executed"] == 0
+        assert summary["best_scenarios"] == []
+
Evidence
PR Compliance ID 11 requires edge-case tests for empty population, single-generation
best-of-generation, and zero fitness scores. The added tests only cover the empty population case.

Unit tests include edge cases for empty or minimal inputs
tests/unit/reporter/test_json_summary_reporter.py[87-97]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Required edge cases (single generation and zero fitness) are not covered.

## Issue Context
Minimal or degenerate runs are common in testing and early stopping; output must remain stable and error-free.

## Fix Focus Areas
- tests/unit/reporter/test_json_summary_reporter.py[87-97]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


View more (2)
4. save() test not consistency-checking 📎 Requirement gap ✓ Correctness
Description
• The save() test verifies results.json exists and is parseable, but it does not assert the file
  content matches (or is consistent with) generate_summary() for the same inputs.
• This can miss regressions where save() writes a different structure/content than
  generate_summary() returns.
Code

tests/unit/reporter/test_json_summary_reporter.py[R98-111]

+    def test_save_json_file(self, minimal_config, temp_output_dir):
+        reporter = JSONSummaryReporter(
+            run_uuid="save-test",
+            config=minimal_config,
+            seen_population={},
+            best_of_generation=[],
+        )
+        reporter.save(temp_output_dir)
+        
+        path = os.path.join(temp_output_dir, "results.json")
+        assert os.path.exists(path)
+        with open(path, "r") as f:
+            content = json.load(f)
+            assert content["run_id"] == "save-test"
Evidence
PR Compliance ID 12 requires verifying save() writes valid JSON to results.json and that the
content matches/aligns with generate_summary() output for the same inputs. The test only checks
existence, JSON parsing, and run_id.

Unit tests verify save() writes valid JSON to results.json in the output directory
tests/unit/reporter/test_json_summary_reporter.py[98-111]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`save()` test does not verify that the written `results.json` content matches `generate_summary()` output.

## Issue Context
`save()` is the persistence path; mismatches between in-memory summary and serialized file can break pipelines.

## Fix Focus Areas
- tests/unit/reporter/test_json_summary_reporter.py[98-111]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


5. GA metadata always empty 🐞 Bug ✓ Correctness
Description
• The new unit tests pass end_time and completed_generations into JSONSummaryReporter, so
  duration/generation metadata looks correct in tests.
• In the real code path (GeneticAlgorithm.save()), end_time remains None and
  completed_generations remains 0 because they are initialized but never updated in the generation
  loop or stop logic.
• As a result, results.json will report duration_seconds=0.0 and generations_completed=0 for
  real runs, which breaks correctness of run reporting/analytics.
Code

tests/unit/reporter/test_json_summary_reporter.py[R45-54]

+        reporter = JSONSummaryReporter(
+            run_uuid="test-run",
+            config=minimal_config,
+            seen_population=pop,
+            best_of_generation=best,
+            start_time=now,
+            end_time=now + datetime.timedelta(seconds=100),
+            completed_generations=2,
+            seed=123
+        )
Evidence
The tests supply run metadata explicitly, but GeneticAlgorithm initializes these fields and never
updates them during stopping/generation progression; it then passes the still-default values into
JSONSummaryReporter, which only computes duration when both start_time and end_time are set.

tests/unit/reporter/test_json_summary_reporter.py[45-54]
krkn_ai/algorithm/genetic.py[95-100]
krkn_ai/algorithm/genetic.py[125-127]
krkn_ai/algorithm/genetic.py[152-180]
krkn_ai/algorithm/genetic.py[260-280]
krkn_ai/algorithm/genetic.py[682-700]
krkn_ai/reporter/json_summary_reporter.py[66-70]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`GeneticAlgorithm` passes `end_time` and `completed_generations` into `JSONSummaryReporter`, but these fields are never updated during the algorithm run. This causes `results.json` to report incorrect run metadata (duration stays 0, generations_completed stays 0) in real executions.

## Issue Context
The new unit tests for `JSONSummaryReporter` pass explicit `start_time/end_time/completed_generations`, so they don’t exercise the real producer of these values (`GeneticAlgorithm`).

## Fix Focus Areas
- krkn_ai/algorithm/genetic.py[120-190]
- krkn_ai/algorithm/genetic.py[260-280]
- krkn_ai/algorithm/genetic.py[682-700]
- krkn_ai/reporter/json_summary_reporter.py[66-70]

## Implementation notes
- Set `self.completed_generations` when a generation completes (e.g., after evaluation, or when stopping).
- Set `self.end_time` when stopping is triggered (ideally timezone-aware and consistent with `self.start_time`).
- Consider setting `self.seed = self.config.seed` (or pass `config.seed`) so seed is recorded.
- Add an integration-style test that runs a minimal/mocked `GeneticAlgorithm.simulate()` then `save()` and asserts `results.json` has non-zero duration and correct generations_completed.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

6. Datetime timezone mismatch risk 🐞 Bug ⛯ Reliability
Description
• The new tests use naive datetimes for reporter metadata (datetime.datetime(...) /
  datetime.datetime.now()), while production code mixes timezone-aware
  (GeneticAlgorithm.start_time uses UTC tzinfo) and naive (KrknRunner uses
  datetime.datetime.now()).
• This inconsistency can easily lead to a TypeError if JSONSummaryReporter is ever given
  mixed-aware/naive start_time/end_time values (Python disallows subtracting them), and the tests
  won’t catch it because they don’t use timezone-aware values.
Code

tests/unit/reporter/test_json_summary_reporter.py[35]

+        now = datetime.datetime(2023, 1, 1, 12, 0, 0)
Evidence
Tests demonstrate naive datetime usage. Production code shows timezone-aware GA start_time and naive
KrknRunner timestamps, and JSONSummaryReporter subtracts end-start when both present—this will raise
if mixed.

tests/unit/reporter/test_json_summary_reporter.py[35-35]
krkn_ai/algorithm/genetic.py[125-125]
krkn_ai/chaos_engines/krkn_runner.py[93-94]
krkn_ai/chaos_engines/krkn_runner.py[130-131]
krkn_ai/reporter/json_summary_reporter.py[68-70]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The codebase mixes timezone-aware and naive `datetime` values (GA uses UTC-aware, KrknRunner uses naive). If `JSONSummaryReporter` receives one aware and one naive datetime, duration calculation will throw a `TypeError`.

## Issue Context
Current unit tests for `JSONSummaryReporter` only use naive datetimes, so they won’t catch timezone-mismatch regressions.

## Fix Focus Areas
- tests/unit/reporter/test_json_summary_reporter.py[35-35]
- krkn_ai/algorithm/genetic.py[125-125]
- krkn_ai/chaos_engines/krkn_runner.py[93-94]
- krkn_ai/chaos_engines/krkn_runner.py[130-131]
- krkn_ai/reporter/json_summary_reporter.py[68-70]

## Implementation notes
- Prefer `datetime.datetime.now(datetime.timezone.utc)` in KrknRunner (start_time/end_time).
- Optionally, defensively normalize in JSONSummaryReporter (e.g., treat naive as UTC) before subtracting.
- Update/add a unit test that uses tz-aware datetimes and asserts duration_seconds is computed correctly.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

Comment on lines 56 to 66
summary = reporter.generate_summary()

assert summary["run_id"] == "test-run"
assert summary["duration_seconds"] == 100.0
assert summary["summary"]["total_scenarios_executed"] == 6
assert summary["summary"]["best_fitness_score"] == 60.0

assert summary["fitness_progression"][0]["average"] == 10.0
assert summary["fitness_progression"][1]["average"] == 50.0
assert summary["fitness_progression"][1]["best"] == 60.0

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

1. generate_summary assertions incomplete 📎 Requirement gap ✓ Correctness

• The test_generate_summary_content test asserts only a small subset of the required
  generate_summary() output (e.g., run_id, duration_seconds, a couple summary stats, and a few
  progression values).
• This does not validate required run metadata (e.g., seed, timestamps), config summary, and the
  broader statistics/schema expectations, so regressions to results.json structure or key computed
  fields could still pass CI.
• As written, the test suite does not meet the checklist’s requirement to assert the unified summary
  dictionary’s required keys and correct values.
Agent Prompt
## Issue description
`generate_summary()` unit tests do not validate the required output schema and key computed fields described in the compliance checklist.

## Issue Context
Downstream consumers rely on `results.json` schema stability. Partial assertions (only a few keys) can allow breaking changes to pass CI.

## Fix Focus Areas
- tests/unit/reporter/test_json_summary_reporter.py[34-66]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines 81 to 86
best = reporter.generate_summary()["best_scenarios"]
assert len(best) == 10
assert best[0]["rank"] == 1
assert best[0]["fitness_score"] == 140.0
assert best[0]["parameters"]["end"] == 10

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

2. Top-10 ranking checks partial 📎 Requirement gap ✓ Correctness

• The best-scenarios test checks only the list length and the first entry’s rank/fitness, but it
  does not validate full sorting, rank increments, truncation correctness across all returned entries,
  or required fields for each item.
• This leaves gaps where incorrect ordering, missing fields, or wrong ranks for entries 2–10 would
  not be caught.
Agent Prompt
## Issue description
`_build_best_scenarios()` behavior (sorting/ranking/truncation and required fields) is only partially validated.

## Issue Context
Incorrect ordering or missing fields in `best_scenarios` can break downstream consumers even if the top item looks correct.

## Fix Focus Areas
- tests/unit/reporter/test_json_summary_reporter.py[67-86]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines 87 to 97
def test_empty_population(self, minimal_config):
reporter = JSONSummaryReporter(
run_uuid="empty",
config=minimal_config,
seen_population={},
best_of_generation=[],
)
summary = reporter.generate_summary()
assert summary["summary"]["total_scenarios_executed"] == 0
assert summary["best_scenarios"] == []

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

3. Missing minimal/zero-fitness edge cases 📎 Requirement gap ⛯ Reliability

• The tests include an empty population case, but do not cover the other required edge cases:
  single-generation best_of_generation and explicit zero-fitness scenarios.
• Without these cases, failures or malformed output in minimal/degenerate runs can slip through CI.
Agent Prompt
## Issue description
Required edge cases (single generation and zero fitness) are not covered.

## Issue Context
Minimal or degenerate runs are common in testing and early stopping; output must remain stable and error-free.

## Fix Focus Areas
- tests/unit/reporter/test_json_summary_reporter.py[87-97]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines 98 to 111
def test_save_json_file(self, minimal_config, temp_output_dir):
reporter = JSONSummaryReporter(
run_uuid="save-test",
config=minimal_config,
seen_population={},
best_of_generation=[],
)
reporter.save(temp_output_dir)

path = os.path.join(temp_output_dir, "results.json")
assert os.path.exists(path)
with open(path, "r") as f:
content = json.load(f)
assert content["run_id"] == "save-test"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

4. save() test not consistency-checking 📎 Requirement gap ✓ Correctness

• The save() test verifies results.json exists and is parseable, but it does not assert the file
  content matches (or is consistent with) generate_summary() for the same inputs.
• This can miss regressions where save() writes a different structure/content than
  generate_summary() returns.
Agent Prompt
## Issue description
`save()` test does not verify that the written `results.json` content matches `generate_summary()` output.

## Issue Context
`save()` is the persistence path; mismatches between in-memory summary and serialized file can break pipelines.

## Fix Focus Areas
- tests/unit/reporter/test_json_summary_reporter.py[98-111]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +45 to +54
reporter = JSONSummaryReporter(
run_uuid="test-run",
config=minimal_config,
seen_population=pop,
best_of_generation=best,
start_time=now,
end_time=now + datetime.timedelta(seconds=100),
completed_generations=2,
seed=123
)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

5. Ga metadata always empty 🐞 Bug ✓ Correctness

• The new unit tests pass end_time and completed_generations into JSONSummaryReporter, so
  duration/generation metadata looks correct in tests.
• In the real code path (GeneticAlgorithm.save()), end_time remains None and
  completed_generations remains 0 because they are initialized but never updated in the generation
  loop or stop logic.
• As a result, results.json will report duration_seconds=0.0 and generations_completed=0 for
  real runs, which breaks correctness of run reporting/analytics.
Agent Prompt
## Issue description
`GeneticAlgorithm` passes `end_time` and `completed_generations` into `JSONSummaryReporter`, but these fields are never updated during the algorithm run. This causes `results.json` to report incorrect run metadata (duration stays 0, generations_completed stays 0) in real executions.

## Issue Context
The new unit tests for `JSONSummaryReporter` pass explicit `start_time/end_time/completed_generations`, so they don’t exercise the real producer of these values (`GeneticAlgorithm`).

## Fix Focus Areas
- krkn_ai/algorithm/genetic.py[120-190]
- krkn_ai/algorithm/genetic.py[260-280]
- krkn_ai/algorithm/genetic.py[682-700]
- krkn_ai/reporter/json_summary_reporter.py[66-70]

## Implementation notes
- Set `self.completed_generations` when a generation completes (e.g., after evaluation, or when stopping).
- Set `self.end_time` when stopping is triggered (ideally timezone-aware and consistent with `self.start_time`).
- Consider setting `self.seed = self.config.seed` (or pass `config.seed`) so seed is recorded.
- Add an integration-style test that runs a minimal/mocked `GeneticAlgorithm.simulate()` then `save()` and asserts `results.json` has non-zero duration and correct generations_completed.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

@Ayush-Patel-56 Ayush-Patel-56 force-pushed the fix/issue-149-json-reporter-tests branch 2 times, most recently from e4f4083 to ae5eacc Compare February 8, 2026 14:18
Signed-off-by: Ayush-Patel-56 <ayushpatel2731@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Add unit tests for JSONSummaryReporter

1 participant