test: consolidate suites and remove redundant cases (#1459)

Regression tests were scattered across feature- and bug-specific files, and some suites repeated the same checks. Group tests by responsibility, isolate feature fixtures in test classes, and remove duplicate or obsolete cases.

The review covered all 127 collected test modules on main. This reduces them and removes or combines definitions:.

 No application code changes.
This commit is contained in:
Normann
2026-10-28 20:15:25 +01:00
committed by GitHub
parent 2863373b17
commit 5d7198d090
31 changed files with 1719 additions and 2159 deletions
+73 -1
View File
@@ -1,9 +1,15 @@
import unittest
import numpy as np
import pytest
from pydantic import ValidationError
from akkudoktoreos.devices.devices import BatteriesCommonSettings
from akkudoktoreos.devices.genetic.battery import Battery, SolarPanelBatteryParameters
from akkudoktoreos.devices.genetic.battery import (
Battery,
ElectricVehicleParameters,
SolarPanelBatteryParameters,
)
@pytest.fixture
@@ -428,3 +434,69 @@ def test_full_target_charges_to_capacity_without_overcharge():
assert battery.current_soc_percentage() <= 100
assert battery.current_soc_percentage() == pytest.approx(100)
assert battery.charge_energy(wh=1000, hour=3) == (0, 0)
_EV_CHARGE_RATES = [0.0] + [amps / 16 for amps in range(6, 17)]
def _minimum_current_battery(kind=ElectricVehicleParameters, soc=99, maximum=100):
parameters = kind(
device_id="ev-test", capacity_wh=60000,
initial_soc_percentage=int(soc), charging_efficiency=0.95,
discharging_efficiency=1.0, max_charge_power_w=11040,
max_soc_percentage=maximum, charge_rates=_EV_CHARGE_RATES,
)
value = Battery(parameters, prediction_hours=4, slot_duration_h=0.25)
value.reset()
value.soc_wh = soc / 100 * value.capacity_wh
value.charge_array = np.full(4, 0.375)
return value
class TestEVMinimumCurrent(unittest.TestCase):
def test_ev_finishes_within_final_slot_at_unchanged_minimum_current(self):
for soc in [98.5, 99.0, 99.9]:
with self.subTest(soc=soc):
value = _minimum_current_battery(soc=soc)
missing = 60000 - value.soc_wh
stored, losses = value.charge_energy(None, 0, charge_factor=0.375)
self.assertAlmostEqual(stored, missing)
self.assertAlmostEqual(value.soc_wh, 60000)
self.assertAlmostEqual(losses, missing / 0.95 - missing)
self.assertEqual(value.charge_array[0], 0.375)
self.assertLessEqual(stored + losses, 4140 * 0.25)
def test_full_ev_has_no_charge_command_or_energy(self):
value = _minimum_current_battery(soc=100)
self.assertEqual(value.charge_energy(None, 0, charge_factor=0.375), (0.0, 0.0))
self.assertEqual(value.charge_array[0], 0)
def test_complete_minimum_current_slot_preserves_watt_hours(self):
value = _minimum_current_battery(soc=80)
stored, losses = value.charge_energy(None, 0, charge_factor=0.375)
self.assertAlmostEqual(stored + losses, 4140 * 0.25)
self.assertAlmostEqual(stored, 4140 * 0.25 * 0.95)
def test_ev_respects_a_lower_configured_maximum(self):
value = _minimum_current_battery(soc=95.9, maximum=96)
value.charge_energy(None, 0, charge_factor=0.375)
self.assertAlmostEqual(value.soc_wh, 60000 * 0.96)
def test_stationary_battery_keeps_discrete_rate_behavior(self):
value = _minimum_current_battery(SolarPanelBatteryParameters, soc=99)
self.assertEqual(value.charge_energy(None, 0, charge_factor=0.375), (0.0, 0.0))
self.assertEqual(value.soc_wh, 59400)
self.assertEqual(value.charge_array[0], 0)
def test_final_slot_preserves_each_configured_current(self):
for amps in range(6, 17):
with self.subTest(amps=amps):
value = _minimum_current_battery(soc=99.9)
factor = amps / 16
value.charge_array[0] = factor
missing = value.max_soc_wh - value.soc_wh
stored, losses = value.charge_energy(None, 0, charge_factor=factor)
self.assertAlmostEqual(stored, missing)
self.assertAlmostEqual(value.soc_wh, value.max_soc_wh)
self.assertAlmostEqual(losses, missing / 0.95 - missing)
self.assertEqual(value.charge_array[0], factor)