
Цел
Необходимостта се състоеше в провеждането на ефективни, ефикасни и повторяеми тестове на софтуера за вграден контролер на двигател, с достатъчна задълбоченост, за да може двигателят да се използва в приложения, свързани с безопасността. Кодът вече беше написан и беше стабилен. Нашите цели бяха да осигурим солидна основа в подкрепа на тезата, че софтуерът е подходящ за използване в контексти, свързани с безопасността, както и да предоставим основа за тестване при непрекъсната интеграция.
Фактори, които трябва да се вземат предвид
Проверката дали сложните алгоритми за управление на тока са правилно реализирани единствено чрез изпълнението им на крайния целеви хардуер не е ефективен подход. Трудно е софтуерът да бъде тестван в целия си работен диапазон на хардуерна тестова система. Поради това е необходимо софтуерът да бъде подложен и на единични/модулни тестове, за да се докаже, че зададените алгоритми са правилно реализирани, тъй като дори малка грешка в реализацията на тези алгоритми може да окаже значително влияние върху работата на двигателя, а в най-лошия случай може да доведе до последствия, свързани с безопасността, като например внезапна загуба на въртящ момент.
За провеждането на единични или модулни тестове на софтуер е необходимо да се познават очакваните резултати за всеки тестов случай. При сложен софтуер за контролни вериги в реално време, при който текущият резултат зависи както от предишните резултати, така и от текущите входни данни, изчисляването на очакваните резултати за всички тестови случаи може да се окаже изключително трудоемка задача. За да постигнем нивото на увереност, необходимо за използването на софтуера в приложения, свързани с безопасността, трябва да проведем голям брой тестове. Бихме искали да тестваме поведението при множество изпълнения на веригата, затова трябва да знаем какви са очакваните изходни данни във времето за даден набор от входни данни, които също могат да се променят във времето.
Подход
Беше разработен метод за тестване, при който софтуерът се тестваше на нивото на цялостни регулаторни вериги. Това се считаше за по-ефективно от тестването само на нивото на отделни софтуерни функции, поради високата степен на взаимозависимост между функциите. Освен това, чрез тестването на цялостната интегрирана регулаторна верига се намалява броят на тестовете, които трябва да се изпълняват и поддържат. Вътрешният дизайн на софтуера на веригата може да бъде преработен, например за оптимизиране на скоростта на изпълнение, без да е необходимо променяне на тестовете.
Беше взето решение да се проведе тестване чрез многократно изпълнение на управляващите цикли. Алгоритмите за управление включват интегрални членове, които се запазват между отделните изпълнения на цикъла. Тестването чрез многократно изпълнение на цикъла ни позволява да проверим правилното функциониране на тези интегратори.
Беше взето решение да се използва изпълним математически модел за генериране на очакваните резултати от тестовете. Това намали обема на необходимите ръчни изчисления, а благодарение на това, че нашите модели се основаваха на модели, разработени по-рано от инженерите по управление, ни позволи да проверим софтуера в сравнение с тези модели.
Процесът

Създаване на изпълними математически модели
Първият етап беше създаването на изпълними математически модели, които щяха да ни служат като „оракул“ за генериране на очакваните резултати от нашите тестове.
Беше избран инструментът за моделиране с отворен код Scicos. Той предлага графична нотация, подходяща за описание на алгоритми за управление. По-долу е показан пример за пропорционално-интегрален алгоритъм със защита срещу „претоварване“ на интегратора и ограничаване на изходния сигнал.

Моделите бяха създадени въз основа на съществуващи Simulink модели на системата за управление. След това те бяха усъвършенствани, за да се осигури точно съответствие с очакваните резултати от софтуера. Това беше необходимо, първо, защото моделите в Simulink са аналогови, докато части от софтуерната реализация са изпълнени в режим с фиксирана запетая, за да се намали времето за изпълнение, и, второ, защото някои характеристики на реализираните контури за управление, които са необходими в реална система, като защита срещу претоварване и защита срещу претоварване по ток, не бяха налице в моделите в Simulink.
Създаване на тестовата среда
Подходът към тестването изискваше няколко неща, които надхвърляха обичайните единични тестове:
- Тествайте набор от взаимосвързани софтуерни функции заедно, като „симулирате“ други
- Изпълнете тестваните софтуерни функции няколко пъти и проверете резултатите при всяка итерация
- Лесно импортирайте резултатите от изпълнението на математическите модели в тестовата среда като очаквани резултати
За да се постигнат тези цели, като се осигури максимален контрол върху изпълнението на тестовете (и се спестят разходи за тестови инструменти), беше написана специално разработена тестова среда на езика „C“ (който беше езикът на тествания софтуер). Тестването се управляваше от структури от данни, създадени въз основа на резултатите от изпълнението на математическия модел. Тези данни определяха колко пъти трябваше да се изпълни контролната верига, както и очакваните резултати за всяка от „симулираните“ функции при всяка итерация. За проверка на покритието се използваше GNU gcov, като при ниско покритие се отчитаха неуспешни тестове. Системата изчисляваше също цикломатичната сложност и други метрики за тествания код, като при метрики извън допустимия диапазон се отчитаха неуспешни тестове. Резултатите от тестовете бяха в XML формат, който можеше да бъде прочетен от Jenkins.
Проектиране на тестове
Проектът на тестовете се основаваше на изискванията на международния стандарт за функционална безопасност IEC 61508. Основното изискване за тестване беше извършването на пълно тестване по метода „черна кутия“. Освен това бяха проведени анализ на граничните стойности и анализ на класовете на еквивалентност, като въз основа на тях бяха добавени допълнителни тестови случаи.
Изпълнение на тестовите случаи в моделите
След като тестовите случаи бяха дефинирани, за тях бяха създадени набори от входни данни за математическите модели, а моделите бяха изпълнени, за да генерират очакваните резултати за всеки тестов случай в текстови файлове.
Създаване на тестовите програми
Изходните текстови файлове, получени при изпълнението на математическите модели, бяха преобразувани в структури от данни на езика „C“. След това тестовата среда, тестваният код и тези структури от данни бяха обединени в тестови програми, които обхващаха пълния набор от тестови случаи.
Тестовите програми бяха съхранени в същото хранилище в Git, както и тестваният софтуер.
Изпълнение на тестовете
Jenkins се използваше за нощното компилиране и изпълнение на тестовите програми. Всички неуспешни тестове се докладваха автоматично с цел предприемане на коригиращи мерки. Това беше част от цялостното нощно компилиране на пълната версия на софтуера на продукта.
Резултатите
Чрез използването на изпълними математически модели и специално разработена тестова среда беше възможно софтуерът на контура за управление на двигателя да бъде тестван по-ефективно и ефикасно, отколкото би било възможно при използване на конвенционални подходи за единично тестване. Беше възможно да се изпълнят голям брой тестове върху пълни контури за управление през множество цикли на изпълнение, което осигури нивото на верификация, подходящо за софтуер в приложения, свързани с безопасността.
По-голямата част от създадения тестов код беше универсален и подходящ за многократна употреба. Беше избегната необходимостта от писане и поддържане на голям брой индивидуални, специално създадени тестови скриптове.
Тестването беше изцяло от типа „черна кутия“. Достъп до вътрешни променливи не беше необходим. Това ще намали разходите за поддръжка на тези тестове, когато се правят промени в реализацията.
Тестовете бяха лесно интегрирани в система за непрекъсната интеграция, базирана на Jenkins.
Нямаше нужда от закупуване на скъп софтуер, за да се постигне това.
