Тема оформления
Модульное и интеграционное тестирование
1. Архитектура и принципы тестирования платформы
В программном комплексе «UrFU HeatBalance» система автоматизированного тестирования выполняет критическую функцию обеспечения метрологической точности, термодинамической корректности и математической сходимости уравнений теплового и материального балансов.
Тестовый контур решает три ключевые инженерные задачи:
- Верификация законов сохранения энергии и массы: строгий контроль соблюдения балансового равенства:
- Контроль допустимой невязки: подтверждение того, что численная невязка баланса не превышает регламентный порог .
- Quality Gate в конвейере CI/CD: автоматическая блокировка компиляции и выкатки контейнеров при выявлении регрессии в расчётных модулях.
2. Спецификация модульных тестов (HeatBalance.Math.Tests)
Все базовые физико-химические и теплотехнические алгоритмы изолированы в разделяемой библиотеке HeatBalance.Math и верифицируются набором тестов в проекте HeatBalance.Math.Tests/UnitTest1.cs на базе тестового фреймворка xUnit.
2.1. Сводная матрица модульных тестов
Имя теста в UnitTest1.cs | Тип агрегата | Проверяемый физический сценарий | Ключевые критерии приемки |
|---|---|---|---|
ConveyorKiln_SampleCase_IsStable | Конвейерная печь | Базовый экспресс-расчёт по удельным долям и низшей теплоте сгорания | Фиксация подвода ( кДж/ч), диапазон полезного тепла ( кДж/ч), неотрицательная невязка. |
ConveyorKiln_DetailedCase_PrintValues | Конвейерная печь | Полный детальный технологический расчёт с учётом футеровки и транспорта | Формирование таблиц без рециркуляции и с рециркуляцией, КПД , валидность структуры FuelCombustion. |
ChamberKiln_SampleCase_IsStable | Камерная печь | Экспресс-расчёт камерной печи периодического действия | Стабильность подвода тепла, проверка потерь кДж/ч. |
ChamberKiln_DetailedCase_PrintValues | Камерная печь | Детальный нестационарный теплообмен: нагрев садки, аккумуляция тепла кладкой, ступенчатый график температур | Положительная полезная мощность, сходимость теплового баланса, расчёт нестационарных периодов (разогрев, выдержка, охлаждение). |
ElectricKiln_SampleCase_IsStable | Электрическая печь | Экспресс-расчёт электрической сушилки при заданной мощности ТЭНов (233.33 кВт) | Эквивалентность подвода электрической энергии тепловому эквиваленту ( кДж/ч, ). |
ElectricKiln_DetailedCase_IsStable | Электрическая печь | Детальный расчёт электропечи с конвективной вентиляцией и ограждающими конструкциями | Расчёт расхода вентиляционного воздуха (), теплопередача через свод и стены, КПД . |
DrumDryer_SampleCase_IsStable | Сушильный барабан | Базовый тепловой баланс вращающегося барабанного сушильного агрегата | Стабильность балансовых уравнений, расчёт потерь через вращающийся корпус ( кДж/ч). |
3. Детальный анализ тестовых сценариев
3.1. Тест конвейерной печи: верификация базового случая
В тесте ConveyorKiln_SampleCase_IsStable проверяется согласованность модели при типовом расходе влажного материала и снижении влажности с до :
csharp
[Fact]
public void ConveyorKiln_SampleCase_IsStable()
{
var input = new ConveyorKilnInput
{
WetMaterialMassFlowKgPerHour = 1000,
MoistureInMassFraction = 0.30,
MoistureOutMassFraction = 0.10,
MaterialTempInC = 20,
MaterialTempOutC = 80,
FuelLowerHeatingValueKJPerKg = 42000,
FuelMassFlowKgPerHour = 20,
HeatLossFraction = 0.15
};
var result = HeatBalanceCalculations.Calculate(input);
Assert.Equal(DryerUnitType.ConveyorKiln, result.UnitType);
Assert.InRange(result.TotalInputKJPerHour, 839_999.9, 840_000.1);
Assert.InRange(result.UsefulHeatKJPerHour, 630_000, 632_000);
Assert.InRange(result.LossesKJPerHour, 125_999.9, 126_000.1);
Assert.True(result.UnaccountedKJPerHour > 0);
}3.2. Тест электрической печи: конвертация электрической мощности
Тест ElectricKiln_SampleCase_IsStable валидирует физическую корректность перевода мощности нагревателей из киловатт в килоджоули в час:
csharp
[Fact]
public void ElectricKiln_SampleCase_IsStable()
{
var input = new ElectricKilnInput
{
WetMaterialMassFlowKgPerHour = 1000,
MoistureInMassFraction = 0.30,
MoistureOutMassFraction = 0.10,
MaterialTempInC = 20,
MaterialTempOutC = 80,
ElectricPowerKw = 233.3333333333, // 233.333.. * 3600 = 840000 кДж/ч
HeatLossFraction = 0.10
};
var result = HeatBalanceCalculations.Calculate(input);
Assert.Equal(DryerUnitType.ElectricKiln, result.UnitType);
Assert.InRange(result.TotalInputKJPerHour, 839_999.0, 840_001.0);
Assert.InRange(result.LossesKJPerHour, 83_999.0, 84_001.0);
Assert.True(result.UnaccountedKJPerHour > 0);
}4. Регламент запуска тестов через интерфейс командной строки (CLI)
4.1. Запуск полного набора тестов
Для прогона всех тестов решения выполните команду из каталога backend/HeatBalanceSystem2:
bash
cd backend/HeatBalanceSystem2
dotnet test HeatBalance.Math.Tests/HeatBalance.Math.Tests.csproj --configuration Release4.2. Фильтрация и селективный запуск тестов
Для ускоренной отладки конкретного модуля используйте параметр --filter:
bash
# Запуск только тестов камерной сушильной печи
dotnet test --filter "FullyQualifiedName~ChamberKiln"
# Запуск только тестов электрической печи с подробным логированием каждого ассерта
dotnet test --filter "FullyQualifiedName~ElectricKiln" --logger "console;verbosity=detailed"4.3. Оценка покрытия кода тестами (Code Coverage)
Для генерации отчёта о покрытии кода тестами используется встроенный сборщик Coverlet:
bash
dotnet test --collect:"XPlat Code Coverage"Отчёт в формате Cobertura XML сохраняется в каталоге TestResults/ и анализируется инструментами статического контроля качества.
5. Методология разработки новых тестов (Best Practices)
При добавлении новых физических моделей или модификации существующих алгоритмов разработчик обязан руководствоваться следующими стандартами:
5.1. Паттерн Arrange-Act-Assert (AAA)
Каждый тест должен чётко разделяться на три фазы:
- Arrange: формирование объекта входных параметров с реалистичными физическими величинами.
- Act: вызов статического метода расчёта
HeatBalanceCalculations.Calculate(input). - Assert: верификация инвариантов, балансовых равенств и полей сводной таблицы.
5.2. Параметризованные тесты ([Theory] и [InlineData])
Для проверки поведения модели на различных диапазонах влажности и температур применяются параметризованные тесты:
csharp
[Theory]
[InlineData(0.20, 0.05, 750_000)]
[InlineData(0.35, 0.08, 920_000)]
[InlineData(0.15, 0.02, 610_000)]
public void ConveyorKiln_MoistureVariations_UsefulHeatWithinBounds(
double moistureIn, double moistureOut, double expectedUsefulHeatMin)
{
// Arrange
var input = new ConveyorKilnInput
{
WetMaterialMassFlowKgPerHour = 1200,
MoistureInMassFraction = moistureIn,
MoistureOutMassFraction = moistureOut,
FuelLowerHeatingValueKJPerKg = 41800,
FuelMassFlowKgPerHour = 25
};
// Act
var result = HeatBalanceCalculations.Calculate(input);
// Assert
Assert.True(result.UsefulHeatKJPerHour >= expectedUsefulHeatMin);
Assert.True(result.Efficiency > 0.0 && result.Efficiency < 1.0);
}5.3. Негативное тестирование и проверка исключений (Edge Cases)
Тестовый набор должен гарантировать, что некорректные физические параметры вызывают прогнозируемые исключения ArgumentException:
csharp
[Fact]
public void Calculate_FinalMoistureGreaterThanInitial_ThrowsArgumentException()
{
// Попытка задать конечную влажность выше начальной (абсурдный процесс сушки)
var invalidInput = new ConveyorKilnInput
{
MoistureInMassFraction = 0.05,
MoistureOutMassFraction = 0.30
};
Assert.Throws<ArgumentException>(() => HeatBalanceCalculations.Calculate(invalidInput));
}