# 多能互补系统储能容量优化计算程序测试用例 # 该文件包含单元测试和验证测试,确保程序在各种场景下的正确性。 # 作者: iFlow CLI # 创建日期: 2025-12-25 import unittest import numpy as np from storage_optimization import ( optimize_storage_capacity, validate_inputs, calculate_energy_balance, check_constraints, SystemParameters ) class TestStorageOptimization(unittest.TestCase): """储能优化程序测试类""" def setUp(self): """测试前的准备工作""" # 基础测试数据 self.solar_output = [0.0] * 6 + [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0, 0.0] + [0.0] * 6 self.wind_output = [2.0, 3.0, 4.0, 3.0, 2.0, 1.0] * 4 self.thermal_output = [5.0] * 24 self.load_demand = [3.0, 4.0, 5.0, 6.0, 8.0, 10.0, 12.0, 14.0, 16.0, 18.0, 20.0, 18.0, 16.0, 14.0, 12.0, 10.0, 8.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0, 2.0] self.params = SystemParameters( max_curtailment_wind=0.1, max_curtailment_solar=0.1, max_grid_ratio=0.2, storage_efficiency=0.9, discharge_rate=1.0, charge_rate=1.0 ) def test_validate_inputs_valid_data(self): """测试有效输入数据的验证""" # 应该不抛出异常 validate_inputs(self.solar_output, self.wind_output, self.thermal_output, self.load_demand, self.params) def test_validate_inputs_invalid_length(self): """测试无效长度的输入数据""" with self.assertRaises(ValueError): validate_inputs([1.0] * 23, self.wind_output, self.thermal_output, self.load_demand, self.params) def test_validate_inputs_negative_values(self): """测试包含负值的输入数据""" with self.assertRaises(ValueError): validate_inputs([-1.0] + self.solar_output[1:], self.wind_output, self.thermal_output, self.load_demand, self.params) def test_validate_inputs_invalid_parameters(self): """测试无效的参数设置""" invalid_params = SystemParameters(max_curtailment_wind=1.5) # 超出范围 with self.assertRaises(ValueError): validate_inputs(self.solar_output, self.wind_output, self.thermal_output, self.load_demand, invalid_params) def test_calculate_energy_balance_basic(self): """测试基本电能平衡计算""" result = calculate_energy_balance( self.solar_output, self.wind_output, self.thermal_output, self.load_demand, self.params, 10.0 ) # 检查返回结果包含所有必要的键 expected_keys = ['storage_profile', 'charge_profile', 'discharge_profile', 'curtailed_wind', 'curtailed_solar', 'grid_feed_in'] for key in expected_keys: self.assertIn(key, result) self.assertEqual(len(result[key]), 24) # 检查储能状态不为负 self.assertTrue(all(soc >= 0 for soc in result['storage_profile'])) def test_check_constraints(self): """测试约束条件检查""" # 先计算平衡结果 balance_result = calculate_energy_balance( self.solar_output, self.wind_output, self.thermal_output, self.load_demand, self.params, 10.0 ) # 检查约束 constraint_results = check_constraints( self.solar_output, self.wind_output, self.thermal_output, balance_result, self.params ) # 检查返回结果 expected_keys = ['total_curtailment_wind_ratio', 'total_curtailment_solar_ratio', 'total_grid_feed_in_ratio'] for key in expected_keys: self.assertIn(key, constraint_results) self.assertGreaterEqual(constraint_results[key], 0) self.assertLessEqual(constraint_results[key], 1.0) def test_optimize_storage_capacity_basic(self): """测试基本储能容量优化""" result = optimize_storage_capacity( self.solar_output, self.wind_output, self.thermal_output, self.load_demand, self.params ) # 检查返回结果结构 expected_keys = [ 'required_storage_capacity', 'storage_profile', 'charge_profile', 'discharge_profile', 'curtailed_wind', 'curtailed_solar', 'grid_feed_in', 'total_curtailment_wind_ratio', 'total_curtailment_solar_ratio', 'total_grid_feed_in_ratio', 'energy_balance_check' ] for key in expected_keys: self.assertIn(key, result) # 检查数值合理性 self.assertGreaterEqual(result['required_storage_capacity'], 0) self.assertTrue(result['energy_balance_check']) def test_zero_curtailment_scenario(self): """测试零弃风弃光场景""" zero_curtail_params = SystemParameters( max_curtailment_wind=0.0, max_curtailment_solar=0.0, max_grid_ratio=0.2, storage_efficiency=0.9 ) result = optimize_storage_capacity( self.solar_output, self.wind_output, self.thermal_output, self.load_demand, zero_curtail_params ) # 检查弃风弃光率是否为0 self.assertEqual(result['total_curtailment_wind_ratio'], 0.0) self.assertEqual(result['total_curtailment_solar_ratio'], 0.0) def test_high_grid_ratio_scenario(self): """测试高上网电量比例场景""" high_grid_params = SystemParameters( max_curtailment_wind=0.1, max_curtailment_solar=0.1, max_grid_ratio=0.5, # 高上网电量比例 storage_efficiency=0.9 ) result = optimize_storage_capacity( self.solar_output, self.wind_output, self.thermal_output, self.load_demand, high_grid_params ) # 检查上网电量比例是否在约束范围内 self.assertLessEqual(result['total_grid_feed_in_ratio'], 0.5) def test_energy_balance_verification(self): """测试能量平衡验证""" result = optimize_storage_capacity( self.solar_output, self.wind_output, self.thermal_output, self.load_demand, self.params ) # 手动验证能量平衡(使用新的计算方法) total_generation = sum(self.thermal_output) + sum(self.wind_output) + sum(self.solar_output) total_consumption = sum(self.load_demand) total_curtailed = sum(result['curtailed_wind']) + sum(result['curtailed_solar']) total_grid = sum(result['grid_feed_in']) total_charge = sum(result['charge_profile']) total_discharge = sum(result['discharge_profile']) # 新的能量平衡计算:考虑储能效率 energy_from_storage = total_discharge / self.params.storage_efficiency energy_to_storage = total_charge * self.params.storage_efficiency energy_balance = total_generation + energy_from_storage - total_consumption - energy_to_storage - total_curtailed - total_grid # 能量平衡误差应该在合理范围内(考虑储能效率损失) tolerance = max(10.0, total_generation * 0.15) self.assertLessEqual(abs(energy_balance), tolerance) def test_extreme_high_load_scenario(self): """测试极高负荷场景""" high_load = [50.0] * 24 # 极高负荷 result = optimize_storage_capacity( self.solar_output, self.wind_output, self.thermal_output, high_load, self.params ) # 应该返回一个结果,即使系统可能不平衡 self.assertIsNotNone(result) self.assertGreater(result['required_storage_capacity'], 0) def test_extreme_low_load_scenario(self): """测试极低负荷场景""" low_load = [0.1] * 24 # 极低负荷 result = optimize_storage_capacity( self.solar_output, self.wind_output, self.thermal_output, low_load, self.params ) # 应该返回一个结果,可能有大量弃风弃光 self.assertIsNotNone(result) self.assertGreaterEqual(result['total_curtailment_wind_ratio'], 0) self.assertGreaterEqual(result['total_curtailment_solar_ratio'], 0) class TestKnownScenarios(unittest.TestCase): """已知场景测试类""" def test_perfect_balance_scenario(self): """测试完美平衡场景""" # 设计一个完美平衡的场景 solar = [2.0] * 6 + [4.0] * 6 + [2.0] * 6 + [0.0] * 6 # 48 MW wind = [3.0] * 12 + [1.0] * 12 # 48 MW thermal = [6.0] * 24 # 144 MW (增加了1 MW每小时) load = [10.0] * 24 # 恒定负荷 240 MW # 总发电量: 48 + 48 + 144 = 240 MW,与负荷平衡 params = SystemParameters( max_curtailment_wind=0.1, max_curtailment_solar=0.1, max_grid_ratio=0.2, storage_efficiency=0.9 ) result = optimize_storage_capacity(solar, wind, thermal, load, params) # 验证结果 self.assertTrue(result['energy_balance_check']) self.assertLessEqual(result['total_curtailment_wind_ratio'], params.max_curtailment_wind) self.assertLessEqual(result['total_curtailment_solar_ratio'], params.max_curtailment_solar) self.assertLessEqual(result['total_grid_feed_in_ratio'], params.max_grid_ratio) def test_no_renewable_scenario(self): """测试无可再生能源场景""" solar = [0.0] * 24 wind = [0.0] * 24 thermal = [10.0] * 24 load = [8.0] * 24 params = SystemParameters( max_curtailment_wind=0.1, max_curtailment_solar=0.1, max_grid_ratio=0.2, storage_efficiency=0.9 ) result = optimize_storage_capacity(solar, wind, thermal, load, params) # 验证结果 self.assertTrue(result['energy_balance_check']) self.assertEqual(result['total_curtailment_wind_ratio'], 0.0) self.assertEqual(result['total_curtailment_solar_ratio'], 0.0) self.assertGreaterEqual(result['total_grid_feed_in_ratio'], 0) def run_performance_test(): """运行性能测试""" print("\n=== 性能测试 ===") # 生成随机测试数据 np.random.seed(42) solar = np.random.exponential(3, 24).tolist() wind = np.random.exponential(2, 24).tolist() thermal = np.random.uniform(3, 8, 24).tolist() load = np.random.uniform(5, 15, 24).tolist() params = SystemParameters() import time start_time = time.time() result = optimize_storage_capacity(solar, wind, thermal, load, params) end_time = time.time() execution_time = end_time - start_time print(f"执行时间: {execution_time:.4f} 秒") print(f"所需储能容量: {result['required_storage_capacity']:.2f} MWh") print(f"能量平衡校验: {'通过' if result['energy_balance_check'] else '未通过'}") class TestYearlyData(unittest.TestCase): """8760小时数据测试类""" def setUp(self): """测试前的准备工作""" # 生成简化的8760小时测试数据(每小时的重复模式) daily_pattern = [3.0, 4.0, 5.0, 6.0, 8.0, 10.0, 12.0, 14.0, 16.0, 18.0, 20.0, 18.0, 16.0, 14.0, 12.0, 10.0, 8.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0, 2.0] self.yearly_load = daily_pattern * 365 # 24 * 365 = 8760 # 简化的发电数据 daily_solar = [0.0] * 6 + [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0, 0.0] + [0.0] * 6 daily_wind = [2.0, 3.0, 4.0, 3.0, 2.0, 1.0] * 4 daily_thermal = [5.0] * 24 self.yearly_solar = daily_solar * 365 self.yearly_wind = daily_wind * 365 self.yearly_thermal = daily_thermal * 365 self.params = SystemParameters( max_curtailment_wind=0.1, max_curtailment_solar=0.1, max_grid_ratio=0.2, storage_efficiency=0.9, discharge_rate=1.0, charge_rate=1.0 ) def test_yearly_data_validation(self): """测试8760小时数据验证""" # 验证数据长度 self.assertEqual(len(self.yearly_solar), 8760) self.assertEqual(len(self.yearly_wind), 8760) self.assertEqual(len(self.yearly_thermal), 8760) self.assertEqual(len(self.yearly_load), 8760) # 验证不会抛出异常 validate_inputs(self.yearly_solar, self.yearly_wind, self.yearly_thermal, self.yearly_load, self.params) def test_yearly_basic_optimization(self): """测试8760小时基本优化""" # 使用较小的迭代次数以加快测试 result = optimize_storage_capacity( self.yearly_solar, self.yearly_wind, self.yearly_thermal, self.yearly_load, self.params, max_iterations=50 ) # 检查返回结果结构 expected_keys = [ 'required_storage_capacity', 'storage_profile', 'charge_profile', 'discharge_profile', 'curtailed_wind', 'curtailed_solar', 'grid_feed_in', 'total_curtailment_wind_ratio', 'total_curtailment_solar_ratio', 'total_grid_feed_in_ratio', 'energy_balance_check' ] for key in expected_keys: self.assertIn(key, result) # 检查数据长度 self.assertEqual(len(result['storage_profile']), 8760) self.assertEqual(len(result['charge_profile']), 8760) self.assertEqual(len(result['discharge_profile']), 8760) # 检查数值合理性 self.assertGreaterEqual(result['required_storage_capacity'], 0) if __name__ == "__main__": print("运行多能互补系统储能容量优化程序测试...") # 运行单元测试 unittest.main(argv=[''], exit=False, verbosity=2) # 运行性能测试 run_performance_test()