В двух предыдущих статьях мы рассмотрели как тестировать программу с помощью пакетных файлов Windows. Сегодня поговорим о том, как сделать то же самое с помощью сценариев оболочки Linux.
Простейший случай
Предположим тестируемая программа имеет вид:
#include <stdio.h> #include <stdlib.h> int main(int argc, char* argv[]) { if(argc < 2) { printf("error\r\n"); return -1; } int val = atoi(argv[1]); return 2*val; }
В этом случае тестирующий ее сценарий будет иметь вид (здесь и далее double — имя тестируемой программы):
#!/bin/sh ./double 56 if [ $? != 112 ]; then echo Ошибка: тест не пройден exit 1 else echo Успех: тест пройден exit 0 fi
Однократное тестирование
Разумеется, так, как показано выше программы никто не пишет. Переменная $? (код возврата приложения) содержит либо ноль (в случае успеха), либо код ошибки. Обычный вид тестируемой программы показан ниже.
#include <stdio.h> int main() { printf("Enter number\r\n"); int a = 0; scanf("%d",&a); printf("result = %d\r\n",2*a); return 0; }
В этом случае мы вновь вынуждены использовать каналы для имитирования ввода в программу double и анализа возвращаемого ею значения. Ниже приводится код сценария, тестирующего нашу программу.
#!/bin/sh echo 56 | ./double | grep "result = 112" >/dev/null if [ $? != 0 ]; then echo Ошибка: тест не пройден exit 1 else echo Успех: тест пройден exit 0 fi
Основное действо осуществляется в строке 3. Здесь запускается программа double, на ее вход подается число 56, а вывод направляется в grep. Последний ищет в выводе строку с правильным ответом. Если она найдена, то тест пройден. Утилита grep выводит на экран найденную строку и устанавливает код возврата равный нулю (он попадает в $?). Поскольку вывод найденной строки нам не нужен, мы перенаправляем его в фиктивное устройство /dev/null, т.е. попросту выбрасываем. Если «правильная» строка не найдена, то переменная $? будет содержать единицу. По значению $? впоследствии и определяется: пройден тест или нет.
Многократное тестирование
Приведенные выше примеры осуществляют однократное тестирование программы. Но что если мы хотим провести серию тестов? В этом случае сценарий нужно переписать, например так, как показано ниже.
#!/bin/sh #Набор входных данных для тестирования in_data="1 4 17 23 46 98" #Набор ожидаемых данных true_out=" 2 8 34 46 92 196" #Записываем реальный вывод тестируемой программы res="" for it in $in_data; do value=`echo $it | ./double | grep "result" | cut -d= -f2` res="$res $((value))" done #Сравниваем реальный вывод с ожидаемым if [ "$res" = "$true_out" ]; then echo Успех: тест пройден exit 0 else echo Ошибка: тест не пройден exit 1 fi
В переменной in_data хранится набор входных данных, по которым осуществляется тестирование. В переменной true_out — ожидаемый, «правильный» вывод тестируемой программы для входных данных in_data.
В цикле, в строках 11-14 накапливается реальный вывод тестируемой программы. Для уменьшения объема он дополнительно прогоняется через утилиту cut, которая оставляет в найденной строке только результат расчета (без «result =» в ее начале). Весь вывод собирается в переменной res.
И наконец, в строках 17-23 полученный вывод сравнивается с ожидаемым. Если они совпадают, то тесты пройдены.
Заключение
Мы рассмотрели организацию тестирования консольного приложения с помощью сценариев оболочки Linux. В отличие от пакетных файлов Windows мы не рассматривали использование эталонных файлов, но в нем нет ничего сложного.