In general, the best way to learn how to write (code or even prose) is
to read something similar. This principle applies to test cases and to
test suites. Unfortunately, well-established test suites have a way of
developing their own conventions: as test writers become more
experienced with DejaGnu and with Tcl, they accumulate more utilities,
and take advantage of more and more features of expect
and Tcl in
general.
Inspecting such established test suites may make the prospect of creating an entirely new test suite appear overwhelming. Nevertheless, it is quite straightforward to get a new test suite going.
There is one test suite that is guaranteed not to grow more elaborate
over time: both it and the tool it tests were created expressly to
illustrate what it takes to get started with DejaGnu. The
`example/' directory of the DejaGnu distribution contains both an
interactive tool called calc
, and a test suite for it. Reading
this test suite, and experimenting with it, is a good way to supplement
the information in this section. (Thanks to Robert Lupton for creating
calc
and its test suite--and also the first version of this
section of the manual!)
To help orient you further in this task, here is an outline of the steps to begin building a test suite for a program example.
testsuite
):
eg$ cd testsuite/
target_abbrev
; this value is the link to the init file you will
write soon. (For simplicity, we assume the environment is Unix, and use
`unix' as the value.)
What else is needed in `configure.in' depends on the requirements
of your tool, your intended test environments, and which
configure
system you use. This example is a minimal
configure.in
for use with Cygnus Configure. (For an alternative
based on the FSF autoconf
system, see the calc
example
distributed with DejaGnu.) Replace example with the name of your
program:
# This file is a shell script fragment # for use with Cygnus configure. srctrigger="example.0" srcname="The DejaGnu example tests" # per-host: # per-target: # everything defaults to unix for a target target_abbrev=unix # post-target:
configure
to
build your `Makefile'. Its leading section should as usual contain
the values that configure
may override:
srcdir = . prefix = /usr/local exec_prefix = $(prefix) bindir = $(exec_prefix)/bin libdir = $(exec_prefix)/lib tooldir = $(libdir)/$(target_alias) datadir = $(exec_prefix)/lib/dejagnu RUNTEST = runtest RUNTESTFLAGS = FLAGS_TO_PASS = #### host, target, site specific Makefile frags come in here.This should be followed by the standard targets at your site. To begin with, they need not do anything--for example, these definitions will do:
all: info: install-info: install: uninstall: clean: -rm -f *~ core *.info*It is also a good idea to make sure your `Makefile' can rebuild itself if `Makefile.in' changes, with a target like this (which works for either Cygnus or FSF Configure):
Makefile : $(srcdir)/Makefile.in $(host_makefile_frag) \ $(target_makefile_frag) $(SHELL) ./config.statusYou also need to include two targets important to DejaGnu:
check
,
to run the tests, and site.exp
, to set up the Tcl copies of
configuration-dependent values. The check
target must run
`runtest --tool example':
check: site.exp all $(RUNTEST) $(RUNTESTFLAGS) $(FLAGS_TO_PASS) \ --tool example --srcdir $(srcdir)The
site.exp
target should usually set up (among other things!) a
Tcl variable for the name of your program:
site.exp: ./config.status Makefile @echo "Making a new config file..." -@rm -f ./tmp? @touch site.exp -@mv site.exp site.bak @echo "## these variables are automatically\ generated by make ##" > ./tmp0 @echo "# Do not edit here. If you wish to\ override these values" >> ./tmp0 @echo "# add them to the last section" >> ./tmp0 @echo "set host_os ${host_os}" >> ./tmp0 @echo "set host_alias ${host_alias}" >> ./tmp0 @echo "set host_cpu ${host_cpu}" >> ./tmp0 @echo "set host_vendor ${host_vendor}" >> ./tmp0 @echo "set target_os ${target_os}" >> ./tmp0 @echo "set target_alias ${target_alias}" >> ./tmp0 @echo "set target_cpu ${target_cpu}" >> ./tmp0 @echo "set target_vendor ${target_vendor}" >> ./tmp0 @echo "set host_triplet ${host_canonical}" >> ./tmp0 @echo "set target_triplet ${target_canonical}">>./tmp0 @echo "set tool binutils" >> ./tmp0 @echo "set srcdir ${srcdir}" >> ./tmp0 @echo "set objdir `pwd`" >> ./tmp0 @echo "set examplename example" >> ./tmp0 @echo "## All variables above are generated by\ configure. Do Not Edit ##" >> ./tmp0 @cat ./tmp0 > site.exp @sed < site.bak \ -e '1,/^## All variables above are.*##/ d' \ >> site.exp -@rm -f ./tmp?
eg$ mkdir config
target_abbrev
value, so call it `config/unix.exp'.
This is the file that contains the target-dependent procedures;
fortunately, most of them do not have to do very much in order for
runtest
to run.
If example is not interactive, you can get away with this minimal
`unix.exp' to begin with:
proc foo_exit {} {} proc foo_version {} {}If example is interactive, however, you might as well define a start routine and invoke it by using an init file like this:
proc foo_exit {} {} proc foo_version {} {} proc foo_start {} { global examplename spawn $examplename expect { -re "" {} } } foo_start
eg$ mkdir example.0
send_user "Testing: one, two...\n"
eg$ configure(You may have to specify more of a path, if a suitable
configure
is not available in your execution path.)
Test Run By rhl on Fri Jan 29 16:25:44 EST 1993 === example tests === Running ./example.0/first-try.exp ... Testing: one, two... === example Summary ===There is no output in the summary, because so far the example does not call any of the procedures that establish a test outcome.
Go to the first, previous, next, last section, table of contents.