<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"> <HTML ><HEAD ><TITLE >Adding A New Tool</TITLE ><META NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.64 "><LINK REL="HOME" TITLE="DejaGnu" HREF="book1.html"><LINK REL="UP" TITLE="Extending DejaGnu" HREF="extending.html"><LINK REL="PREVIOUS" TITLE="Extending DejaGnu" HREF="extending.html"><LINK REL="NEXT" TITLE="Adding A New Target" HREF="addtarget.html"></HEAD ><BODY CLASS="SECT1" BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#840084" ALINK="#0000FF" ><DIV CLASS="NAVHEADER" ><TABLE WIDTH="100%" BORDER="0" CELLPADDING="0" CELLSPACING="0" ><TR ><TH COLSPAN="3" ALIGN="center" >DejaGnu: The GNU Testing Framework</TH ></TR ><TR ><TD WIDTH="10%" ALIGN="left" VALIGN="bottom" ><A HREF="extending.html" ><<< Previous</A ></TD ><TD WIDTH="80%" ALIGN="center" VALIGN="bottom" >Extending DejaGnu</TD ><TD WIDTH="10%" ALIGN="right" VALIGN="bottom" ><A HREF="addtarget.html" >Next >>></A ></TD ></TR ></TABLE ><HR ALIGN="LEFT" WIDTH="100%"></DIV ><DIV CLASS="SECT1" ><H1 CLASS="SECT1" ><A NAME="ADDTOOL" >Adding A New Tool</A ></H1 ><P >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 <SPAN CLASS="PRODUCTNAME" >Expect</SPAN > and <SPAN CLASS="PRODUCTNAME" >Tcl</SPAN > in general.</P ><P >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.</P ><P >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 <TT CLASS="FILENAME" >example/</TT > directory of the DejaGnu distribution contains both an interactive tool called <B CLASS="COMMAND" >calc</B >, 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!)</P ><P >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.</P ><P ></P ><UL ><LI STYLE="list-style-type: disc" ><P >Create or select a directory to contain your new collection of tests. Change into that directory (shown here as <TT CLASS="FILENAME" >testsuite</TT >):</P ><P >Create a <TT CLASS="FILENAME" >configure.in</TT > file in this directory, to control configuration-dependent choices for your tests. So far as DejaGnu is concerned, the important thing is to set a value for the variable <SPAN CLASS="SYMBOL" >target_abbrev</SPAN >; this value is the link to the init file you will write soon. (For simplicity, we assume the environment is Unix, and use <I CLASS="EMPHASIS" >unix</I > as the value.)</P ><P >What else is needed in <TT CLASS="FILENAME" >configure.in</TT > 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 <SPAN CLASS="PRODUCTNAME" >GNU Autoconf</SPAN >. </P ></LI ><LI STYLE="list-style-type: disc" ><P >Create <TT CLASS="FILENAME" >Makefile.in</TT > (if you are using Autoconf), or <TT CLASS="FILENAME" >Makefile.am</TT >(if you are using Automake), the source file used by configure to build your <TT CLASS="FILENAME" >Makefile</TT >. If you are using GNU Automake.just add the keyword <I CLASS="EMPHASIS" >dejagnu</I > to the <I CLASS="EMPHASIS" >AUTOMAKE_OPTIONS</I > variable in your <TT CLASS="FILENAME" >Makefile.am</TT > file. This will add all the Makefile support needed to run DejaGnu, and support the <A HREF="runningtests.html#MAKECHECK" >Make Check</A > target.</P ><P >You also need to include two targets important to DejaGnu: <I CLASS="EMPHASIS" >check</I >, to run the tests, and <I CLASS="EMPHASIS" >site.exp</I >, to set up the Tcl copies of configuration-dependent values. This is called the <A HREF="customizing.html#LOCAL" >Local Config File</A > The check target must run the <B CLASS="COMMAND" >runtest</B > program to execute the tests.</P ><P >The <TT CLASS="FILENAME" >site.exp</TT > target should usually set up (among other things) the $tool variable for the name of your program. If the local site.exp file is setup correctly, it is possible to execute the tests by merely typing <B CLASS="COMMAND" >runtest</B > on the command line.</P ><DIV CLASS="EXAMPLE" ><A NAME="AEN1145" ></A ><P ><B >Example 1. Sample Makefile.in Fragment</B ></P ><TABLE BORDER="0" BGCOLOR="#E0E0E0" WIDTH="90%" ><TR ><TD ><PRE CLASS="PROGRAMLISTING" > # Look for a local version of DejaGnu, otherwise use one in the path RUNTEST = `if test -f $(top_srcdir)/../dejagnu/runtest; then \ echo $(top_srcdir) ../dejagnu/runtest; \ else \ echo runtest; \ fi` # The flags to pass to runtest RUNTESTFLAGS = # Execute the tests check: site.exp all $(RUNTEST) $(RUNTESTFLAGS) \ --tool <SPAN CLASS="SYMBOL" >${example}</SPAN > --srcdir $(srcdir) # Make the local config file 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 <SPAN CLASS="SYMBOL" >${examplename}</SPAN > <SPAN CLASS="SYMBOL" >${example}</SPAN >" >> ./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? </PRE ></TD ></TR ></TABLE ></DIV ></LI ><LI STYLE="list-style-type: disc" ><P >Create a directory (in <TT CLASS="FILENAME" >testsuite</TT >) called <TT CLASS="FILENAME" >config</TT >. Make a <I CLASS="EMPHASIS" >Tool Init File</I > in this directory. Its name must start with the <SPAN CLASS="SYMBOL" >target_abbrev</SPAN > value, or be named <TT CLASS="FILENAME" >default.exp</TT > so call it <TT CLASS="FILENAME" >config/unix.exp</TT > for our Unix based example. This is the file that contains the target-dependent procedures. Fortunately, on Unix, most of them do not have to do very much in order for <B CLASS="COMMAND" >runtest</B > to run.</P ><P >If the program being tested is not interactive, you can get away with this minimal <TT CLASS="FILENAME" >unix.exp</TT > to begin with:</P ><DIV CLASS="EXAMPLE" ><A NAME="AEN1162" ></A ><P ><B >Example 2. Simple Batch Program Tool Init File</B ></P ><TABLE BORDER="0" BGCOLOR="#E0E0E0" WIDTH="90%" ><TR ><TD ><PRE CLASS="PROGRAMLISTING" > proc foo_exit {} {} proc foo_version {} {} </PRE ></TD ></TR ></TABLE ></DIV ><P >If the program being tested is interactive, however, you might as well define a <I CLASS="EMPHASIS" >start</I > routine and invoke it by using an init file like this:</P ><DIV CLASS="EXAMPLE" ><A NAME="AEN1167" ></A ><P ><B >Example 3. Simple Interactive Program Tool Init File</B ></P ><TABLE BORDER="0" BGCOLOR="#E0E0E0" WIDTH="90%" ><TR ><TD ><PRE CLASS="PROGRAMLISTING" > proc foo_exit {} {} proc foo_version {} {} proc foo_start {} { global ${examplename} spawn ${examplename} expect { -re "" {} } } # Start the program running we want to test foo_start </PRE ></TD ></TR ></TABLE ></DIV ></LI ><LI STYLE="list-style-type: disc" ><P >Create a directory whose name begins with your tool's name, to contain tests. For example, if your tool's name is <I CLASS="EMPHASIS" >gcc</I >, then the directories all need to start with <I CLASS="EMPHASIS" >"gcc."</I >.</P ></LI ><LI STYLE="list-style-type: disc" ><P >Create a sample test file. Its name must end with <TT CLASS="FILENAME" >.exp</TT >. You can use <TT CLASS="FILENAME" >first-try.exp</TT >. To begin with, just write there a line of Tcl code to issue a message.</P ><DIV CLASS="EXAMPLE" ><A NAME="AEN1178" ></A ><P ><B >Example 4. Testing A New Tool Config</B ></P ><TABLE BORDER="0" BGCOLOR="#E0E0E0" WIDTH="90%" ><TR ><TD ><PRE CLASS="PROGRAMLISTING" > send_user "Testing: one, two...\n" </PRE ></TD ></TR ></TABLE ></DIV ></LI ><LI STYLE="list-style-type: disc" ><P >Back in the <TT CLASS="FILENAME" >testsuite</TT > (top level) directory, run <B CLASS="COMMAND" >configure</B >. Typically you do this while in the build directory. You may have to specify more of a path, if a suitable configure is not available in your execution path.</P ></LI ><LI STYLE="list-style-type: disc" ><P >e now ready to triumphantly type <B CLASS="COMMAND" >make check</B > or <B CLASS="COMMAND" >runtest</B >. You should see something like this:</P ><DIV CLASS="EXAMPLE" ><A NAME="AEN1189" ></A ><P ><B >Example 5. Example Test Case Run</B ></P ><TABLE BORDER="0" BGCOLOR="#E0E0E0" WIDTH="90%" ><TR ><TD ><PRE CLASS="SCREEN" > 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 === </PRE ></TD ></TR ></TABLE ></DIV ><P >There is no output in the summary, because so far the example does not call any of the procedures that establish a test outcome.</P ></LI ><LI STYLE="list-style-type: disc" ><P >Write some real tests. For an interactive tool, you should probably write a real exit routine in fairly short order. In any case, you should also write a real version routine soon. </P ></LI ></UL ></DIV ><DIV CLASS="NAVFOOTER" ><HR ALIGN="LEFT" WIDTH="100%"><TABLE WIDTH="100%" BORDER="0" CELLPADDING="0" CELLSPACING="0" ><TR ><TD WIDTH="33%" ALIGN="left" VALIGN="top" ><A HREF="extending.html" ><<< Previous</A ></TD ><TD WIDTH="34%" ALIGN="center" VALIGN="top" ><A HREF="book1.html" >Home</A ></TD ><TD WIDTH="33%" ALIGN="right" VALIGN="top" ><A HREF="addtarget.html" >Next >>></A ></TD ></TR ><TR ><TD WIDTH="33%" ALIGN="left" VALIGN="top" >Extending DejaGnu</TD ><TD WIDTH="34%" ALIGN="center" VALIGN="top" ><A HREF="extending.html" >Up</A ></TD ><TD WIDTH="33%" ALIGN="right" VALIGN="top" >Adding A New Target</TD ></TR ></TABLE ></DIV ></BODY ></HTML >