Ставим и запускаем DejaGnu

Этот раздел был написан Никлаусом Гигером (Niklaus Giger, ), потому как он потратил неделю работы на то, чтобы разгадать, как работает DejaGnu и как написать первый тест.

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

Больших проблем с установкой DejaGnu быть не должно. Его можно поставить из используемого пакетного менеджера, или собрать из исходных текстов. Например, в системах Debian/GNU/Linux вы должны выполнить следующие команды (под администратором)

# apt-get install dejagnu

Данные пример работает на основной машине с процессоров AMD K6, и Mac Powerbook G3 в качестве удаленного целевого компьютера.

Тесты под Windows должны быть запущены с использованием последней версии Cygwin. В качестве целевой машины используется PPC с операционной системой vxWorks.

оригинал

Проверяем установку

Создайте нового пользователя с именем "dgt" (DejaGnuTest), который будет использовать bash в качестве оболочки. Переменная окружения PS1 должна быть установлена в '\u:\w\$ ' в файле ~/.bashrc. Войдите под этим пользователем, создайте пустую директорию и зайдите в нее, т. е. выполните:

dgt:~$ mkdir ~/dejagnu.test
dgt:~$ cd ~/dejagnu.test

Теперь вы готовы запустить runtest, основную программу DejaGnu.Ожидаемый вывод показан ниже:

Example 1. Вывод runtest в пустой директории

dgt:~/dejagnu.test$ runtest
WARNING: Couldn't find the global config file.
WARNING: No tool specified Test
Run By dgt on Sun Nov 25 17:07:03 2001 Native configuration is i586-pc-linux-gnu
=== tests ===
Schedule of variations: unix
Running target unix Using /usr/share/dejagnu/baseboards/unix.exp as board description file for target.
Using /usr/share/dejagnu/config/unix.exp as generic interface file for target.
ERROR: Couldn't find tool config file for unix.
=== Summary ===

О том, как избавиться от этих WARNING и ERROR сообщениях мы скажем позже. В результате запуска были созданы файлы testrun.sum и testrun.log, но сейчас они не содержат ничего интересного. Поэтому удалим их:

dgt:~/dejagnu.test$ rm testrun.sum testrun.log

Windows

Под операционной системой Windows фреймворк DejaGnu является частью Cygwin -- порта большого количества различных утилит под OS Windows. Cygwin можно скачать и установить по адресу http://www.cygwin.com/. Все примеры могут быть запущены также и под Windows. Если не оговорено обратное, то мы полагаем, что и под Windows вы должны получить тот же самый вывод, что и под Unix-системами.

Если вы хотите использовать Windows в качестве удаленной целевой машины, то для этого вам нужен демон telnet. Для этой цели подходит бесплатный свободный демон, который можно скачать по адресу http://www.fictional.net/.

Получение исходного кода примера calc

Если вы запускаете тесты в дистрибутиве Debian, то исходный код примера располагается в директории /usr/share/doc/dejagnu/examples. Видимо, указанные примеры отсутствуют в пакетном менеджере Red Hat RPM. в этом случае исходные тексты могут быть скачайте исходный код DejaGnu, и найдите соответствующий путь к директории examples.

оригинал

Создание минимального проекта на примере calc

В этом разделе мы начнем небольшой проект, который будет использовать в качестве примера программу calc, которая является частью дистрибутива DejaGnu.

Простой проект без использования GNU autotools

Программа runtest должна быть автономной. Утилиты autoconf/automake обычно поддерживают другие программы, которые используются в других GNU приложениях. Ключом к автономному запуску runtest служит правильная настройка файла site.exp, которую выполняет automake.

Для этого вы должны сами создать файл site.exp подобный этому:

set tool calc
set srcdir .
set objdir /home/dgt/dejagnu.test

Использование autoconf/autoheader/automake

В начале мы должны подготовить несколько входных файлов для запуска autoconf и automake. Более подробно этот процесс расписан в книге "GNU autoconf, automake and libtool" (Garry V. Vaughan, et al. NewRider, ISBN 1-57870-190-2).

Из пример calc, который входит в состав документации DejaGnu, вам необходимо будет скопировать в рабочий каталог сам исходный текст программы (calc.c) и несколько дополнительных файлов, которые можно рассмотреть чуть более подробно, чтобы понять их назначение.

dgt:~/dejagnu.test$ cp -r /usr/share/doc/dejagnu/examples/calc/\
{configure.in,Makefile.am,calc.c,testsuite} .

Отметим, что в файле Makemake.am располагается строка AUTOMAKE_OPTIONS = dejagnu. Эта опция необходима.

Для создания файл aclocal.m4 запустим aclocal. Этот файл содержит набор макросов, которые будут нужны затем в configure.in

dgt:~/dejagnu.test$ aclocal

autoconf это другая утилита, входящая в состав autotools. Запустим ее для создания файла configure, который основывается на информации, которая содержится в файле configure.in.

dgt:~/dejagnu.test$ autoconf

autoheader это еще одна утилита из auto-tools. Запустим ее для создания файла calc.h.in.

dgt:~/dejagnu.test$ autoheader

Файл Makefile.am этого примера был разработан как часть DejaGnu дистрибутива. Приспособим его для этого теста. Заменим строку "#noinst_PROGRAMS = calc" на "bin_PROGRAMS = calc". Также надо поменять значение RUNTESTDEFAULTFLAGS из "$$srcdir/testsuite" на "./testsuite".

Если сейчас запустить automake, то мы получим серию предупреждений, показанных ниже:

Example 2. Примерный вывод automake с указанием пропущенных файлов

dgt:~/dejagnu.test$ automake --add-missing
automake: configure.in: installing `./install-sh'
automake: configure.in: installing `./mkinstalldirs'
automake: configure.in: installing `./missing'
automake: Makefile.am: installing `./INSTALL'
automake: Makefile.am: required file `./NEWS' not found
automake: Makefile.am: required file `./README' not found
automake: Makefile.am: installing `./COPYING'
automake: Makefile.am: required file `./AUTHORS' not found
automake: Makefile.am: required file `./ChangeLog' not found
configure.in: 4: required file `./calc.h.in' not found
Makefile.am:6: required directory ./doc does not exist

Создаем пустую директорию doc и пустые файлы INSTALL, NEWS, README, AUTHORS, ChangeLog и COPYING. По умолчанию COPYING указывает на GNU Public License (GPL). В реальном проекте эти файлы должны содержать некоторый осмысленный текст в каждом из файлов.

Теперь вызовем configure для того, что настроить программу calc к нашей среде.

Example 3. Примерный вывод configure

dgt:~/dejagnu.test$ ./configure
creating cache ./config.cache
checking whether to enable maintainer-specific portions of Makefiles... no
checking for a BSD compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking whether make sets ${MAKE}... yes
checking for working aclocal... found
checking for working autoconf... found
checking for working automake... found
checking for working autoheader... found
checking for working makeinfo... found
checking for gcc... gcc checking whether the C compiler (gcc ) works... yes
checking whether the C compiler (gcc ) is a cross-compiler... no
checking whether we are using GNU C... yes
checking whether gcc accepts -g... yes
checking for a BSD compatible install... /usr/bin/install -c
checking how to run the C preprocessor... gcc -E
checking for stdlib.h... yes
checking for strcmp... yes
updating cache ./config.cache
creating ./config.status
creating Makefile creating calc.h

Если вы раньше сталкивались с программным обеспечением GNU, то этот вывод не должен стать для вас сюрпризом. Любый ошибки должны быть легко исправлены для такой простой программы как эта.

И, наконец, получаем исполняемый файл calc:

Example 4. Примерный вывод в результате билда calc

dgt:~/dejagnu.test$ make
gcc -DHAVE_CONFIG_H -I. -I. -I. -g -O2 -c calc.c
gcc -g -O2 -o calc calc.o

Итак, мы подготовили несколько файлов и выполнили несколько команд. Правильный порядок выполнения команд гарантирует автоматическую и правильную компиляцию программы calc. Ниже подведем итог правильному порядку вызова:

Example 5. Создание программы calc с использованием GNU autotools

dgt:~/dejagnu.test$ aclocal
dgt:~/dejagnu.test$ autoconf
dgt:~/dejagnu.test$ autoheader
dgt:~/dejagnu.test$ automake --add-missing
dgt:~/dejagnu.test$ ./configure
dgt:~/dejagnu.test$ make

Поиграемся немного с программой calc для проверки корректности ее работы. Примерная сессия работы должны выгрядеть примерно так:

dgt:~/dejagnu.test$ ./calc
calc: version
Version: 1.1
calc: add 3 4
7
calc: multiply 3 4 
12
calc: multiply 2 4 
12
calc: quit

А вот и специальный баг в ней: 2 * 4 = 12.

Все тесты, которые запускает DejaGnu, требуют специальный файл site.exp, который автоматически создается при выполнении команды "make site.exp". Это обеспечивает строка "AUTOMAKE_OPTIONS = dejagnu" в файле Makefile.am.

Example 6. Примерный вывод при создании файла site.exp

dgt: make site.exp
dgt:~/dejagnu.test$ make site.exp
Making a new site.exp file...

оригинал

Первые автоматизированные тесты

Запуск тестов для нашего примера calc

Сейчас мы готовы запустить автоматизированные тесты:

Example 7. Примерный вывод runtest в сконфигурированной директории

dgt:~/dejagnu.test$ make check
make check-DEJAGNU
make[1]: Entering directory `/home/dgt/dejagnu.test' srcdir=`cd . && pwd`; export srcdir; \
EXPECT=expect; export EXPECT; \ runtest=runtest; \
if /bin/sh -c "$runtest --version" > /dev/null 2>&1; then \
$runtest --tool calc CALC=`pwd`/calc --srcdir ./testsuite ; \
else echo "WARNING: could not find \`runtest'" 1>&2; :;\
fi
WARNING: Couldn't find the global config file.
WARNING: Couldn't find tool init file
Test Run By dgt on Sun Nov 25 21:42:21 2001
Native configuration is i586-pc-linux-gnu

       === calc tests ===

Schedule of variations:
   unix

Running target unix
Using /usr/share/dejagnu/baseboards/unix.exp as board description file for target.
Using /usr/share/dejagnu/config/unix.exp as generic interface file for target.
Using ./testsuite/config/unix.exp as tool-and-target-specific interface file.
Running ./testsuite/calc.test/calc.exp ...
FAIL: multiply2 (bad match)

=== calc Summary ===

# of expected passes 5
# of unexpected failures 1
/home/Dgt/dejagnu.test/calc version Version: 1.1
make[1]: *** [check-DEJAGNU] Fehler 1
make[1]: Leaving directory `/home/Dgt/dejagnu.test' make: *** [check-am] Fehler 2

Видели строку "FAIL:"? Контрольный пример обнаружил ошибку в файле calc.c. Мы исправим ошибку в файле calc.c позднее все следующие примеры предполагают, что в файл calc.c не вносилось изменений.

Посмотрим, что записалось в файлы calc.sum и calc.log. Для этого постараемся понять, какие контрольные примеры были записаны в файле ~/dejagnu.test/testsuite/calc.test/calc.exp. Чтобы лучше понять Expect, я советую обратить ваше внимание на книгу "Exploring Expect", которая является превосходным материалом для изучения и использования Expect (Pub: O'Reilly, ISBN 1-56592-090-2). Эта книга содержит тысячи примеров, а также включает руководство по языку Tcl. Всего в книге 602 больших страниц.

Различные конфигурационные файлы, или как избежать предупреждений

DejaGnu легко можно настроить для любого пользователя. Первым происходит поиск файла ~/.dejagnurc. Создайте такой файл и добавьте в него следующую строку:

puts "I am ~/.dejagnurc"

Перезапустите make check. Теперь в выводе теста будет содержаться строка "I am ~/.dejagnurc". А теперь создадим файл ~/my_dejagnu.exp и вставим туда такую строку:

puts "I am ~/my_dejagnu.exp"

И в нашей оболочке bash выполним:

dgt:~/dejagnu.test$ export DEJAGNU=~/my_dejagnu.exp

Запустим наш "make check" снова. Теперь вывод не содержит предупреждения "WARNING: Couldn't find the global config file." Создадим поддиректорию lib и там создадим файл "calc.exp" следующего содержания:

puts "I am lib/calc.exp"

И последнее предупреждение "WARNING: Couldn't find tool init file" также надо удалить из вывода make check. Для этого создадим директорию ~/boards. Создадим файл ~/boards/standard.exp и добавим туда такую строку:

puts "I am boards/standard.exp"

Если переменная DEJAGNU все еще установлена, тогда в сокращенном виде вывод команды "make check" будет таким:

Example 8. Примерный вывод runtest с обычными конфигурационными файлами

dgt:~/dejagnu.test$ make check
<...>
fi
I am ~/.dejagnurc
I am ~/my_dejagnu.exp
I am lib/calc.exp
Test Run By dgt on Sun Nov 25 22:19:14 2001
Native configuration is i586-pc-linux-gnu

     === calc tests ===
Using /home/Dgt/boards/standard.exp as standard board description file for build.
I am ~/boards/standard.exp
Using /home/Dgt/boards/standard.exp as standard board description file for host.
I am ~/boards/standard.exp

Schedule of variations:
  unix

Running target unix
Using /home/Dgt/boards/standard.exp as standard board description file for target.
I am ~/boards/standard.exp
Using /usr/share/dejagnu/baseboards/unix.exp as board description filefor target.
<...>

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

Когда возникают проблемы

Если при вызове runtest указать в качестве флага '-v', то в результате будет выведено информации о том, какие файлы искались и в каком порядке. Передавая этот флаг несколько раз можно получать все более и более детальный вывод.

Example 9. Отображение детального вывода при выполнении runtest

runtest -v -v -v --tool calc CALC=`pwd`/calc --srcdir ./testsuite

Запуск runtest с флагом '--debug' записывает в лог-файл dbg.log много различных деталей, которые вы затем можете проанализировать.

Для того, чтобы временно настроить вывод отладочной информации, вы можете добавить приведенную ниже команду языка Tcl в любой из файлов, который загружается DejaGnu. Например, это может быть ~/.dejagnurc:

set verbose 9

Тестируем "Hello world" локально

Этот тест проверяет работу системной команды echo, в частности сравнивает вывод системной команды "echo Hello world" со строкой "Hello world". Создадим файл ~/dejagnu.test/testsuite/calc.test/local_echo.exp следующего содержания:

Example 10. Первый локальный контрольный пример

set test "Local Hello World" 
send "echo Hello World" 
expect {
   -re "Hello World"  { pass "$test" }
}

Запускам runtest снова и проверяем вывод (calc.log)

оригинал

Первый удаленный тест

не переведено

оригинал