Тестирование консольной программы с помощью bat файла 2

Продолжаем наш разговор о тестировании приложений с помощью bat файлов. В прошлой статье мы рассмотрели, как провести однократный тест. Но что если тестов несколько?

Эталонный файл

Первый, и наиболее простой вариант решения задачи — подготовить эталонный файл, содержащий «правильный» вывод программы для всех наших тестов. Ниже приводится пример такого bat файла.

@echo off
rem Набор входных данных для тестирования
set in_data=1 4 17 23 46 98

del out.txt
rem Записываем реальный вывод тестируемой программмы
for %%i in (%in_data%) do (
  echo %%i | double | find "Result" >> out.txt	
)

rem Сравниваем реальный вывод с ожидаемым 
comp out.txt true_out.txt /M | find "Различия не найдены." >nul

if ERRORLEVEL 1 (
  echo Ошибка: тесты не пройдены
) else (
  echo Тесты успешно пройдены
)

В переменной in_data хранится набор входных данных по которым осуществляется тестирование. В цикле на строках 7-8 осуществляется прогон программы по этим данным. Весь ее вывод записывается в файл out.txt. Для уменьшения объема, вывод предварительно прогоняется через фильтр командой find. Чтобы не допустить смешения новых выходных данных с данными, оставшимися в файле от прошлых тестов, файл предварительно удаляется (строка 5).

Заранее подготовленный файл true_out.txt содержит «правильный», ожидаемый вывод тестируемой программы. Его содержимое приведено ниже

Result = 2
Result = 8
Result = 34
Result = 46
Result = 92
Result = 196

В строке 12 вызывается программа comp, которая сравнивает файл out.txt (реальный вывод программы) с файлом true_out.txt (ожидаемый вывод программы). Ключ /M в ее запуске нужен для того, чтобы comp не предлагала сравнить еще файлы, как она это делает по умолчанию. В случае совпадения файлов comp выводит на экран сообщение «Различия не найдены.». Именно так, русскими буквами.

Помните: командный интерпретатор не выполняет никакого конвертирования строк. Поэтому для того, чтобы данный сценарий работал, он должен быть сохранен в кодировке OEM866. Именно ее использует командный интерпретатор на русскоязычной версии Windows.

Если это условие не выполнено, команда find не сможет найти нужную нам строку.

Недостатком этого подхода является необходимость предварительной подготовки эталонного файла. Можно ли как-то обойтись без него?

Эталонная строка

Если мы можем составить эталонный файл, содержащий правильный вывод программы для наших тестов, то почему бы не оформить его в виде одной строки? К сожалению, для реализации такого сценария придется использовать не один, а два пакетных файла.

Первый назовем run_double, он будет отвечать за запуск тестируемой программы. Ниже приводится его исходный код:

@echo off

for %%i in (%*) do (
  echo %%i | double | find "Result"
)

Он проходит по списку полученных параметров и для каждого из них запускает тестируемую программу double. Ее результаты после фильтрации командой find выводятся на экран. Ничего сложного.

Второй пакетный файл осуществляет само тестирование. Его код посложнее и приведен ниже.

@echo off
setlocal enabledelayedexpansion

rem Набор входных данных для тестирования
set in_data=1 4 17 23 46 98

rem Набор ожидаемых данных
set true_out= 2 8 34 46 92 196

rem Записываем реальный вывод тестируемой программы
set res=
for /F "tokens=3" %%i in ('run_double %in_data%') do (
    set res=!res! %%i
)

rem Сравниваем реальный вывод с ожидаемым 
if "!res!"=="%true_out%" (
  echo Тесты успешно пройдены
) else ( 
  echo Ошибка: тесты не пройдены
)

В переменной in_data хранится набор входных данных, по которым осуществляется тестирование. В переменной true_out — ожидаемый, правильный вывод тестируемой программы для входных данных in_data.

В цикле в строках 12-14 накапливается реальный вывод тестируемой программы. Точнее говоря, в нем перебирается вывод пакетного файла run_double, который и запускает нашу программу. Весь вывод собирается в переменной res.

И наконец, в строках 17-21 полученный вывод сравнивается с ожидаемым. Если они совпадают, то тесты пройдены.

Для чего нужен пакетный файл run_double? Неужели нельзя обойтись без него? Он нужен для того, чтобы обойти неприятное ограничение в генерируемом диапазоне для цикла for: в нем нельзя использовать каналы. Если бы мы могли использовать конструкцию вида:

for /F %%i in ('echo %a% | double') do (
    set res=!res! %%i
)

то пакетный файл run_double нам был бы не нужен. Но, как говорилось ранее, каналы здесь использовать нельзя.

Команда call также не помогает. При попытке ее использования возникает ошибка с текстом: «Недопустимая попытка перехода на метку пакетного файла извне этого файла». Поэтому приходится использовать второй пакетный файл.

Заключение

Мы рассмотрели два способа тестирования консольного приложения с помощью пакетных файлов. Первый подразумевает создание эталонного файла с правильными результатами. Второй способ позволяет обойтись без эталонного файла, но нуждается в еще одном пакетном файле. Какой способ выбрать — решать вам.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *