### 5.2 Adding a new tool ¶

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 testsuites. Unfortunately, well-established testsuites 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 testsuites may make the prospect of creating an entirely new testsuite appear overwhelming. Nevertheless, it is straightforward to start a new testsuite.

To help orient you further in this task, here is an outline of the steps to begin building a testsuite for a program example.

Create or select a directory to contain your new collection of tests. Change into that directory (shown here as `testsuite`):

Create a `configure.in` 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 `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.ac` for use with GNU Autoconf.

#### 5.2.1 Sample Makefile.in Fragment ¶

Create `Makefile.in` (if using Autoconf), or `Makefile.am` (if using Automake), the source file used by configure to build your `Makefile`. If you are using GNU Automake.just add the keyword dejagnu to the AUTOMAKE_OPTIONS variable in your `Makefile.am` file. This will add all the `Makefile` support needed to run DejaGnu, and support the make check target.

You 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. This is called the Local configuration file The check target must invoke the `runtest` program to run the tests.

The site.exp 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 `runtest` on the command line.

    # 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`

    # Flags to pass to runtest
    RUNTESTFLAGS =

    # Execute the tests
    check: site.exp all
            $(RUNTEST) $(RUNTESTFLAGS) --tool ${example} --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 ${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?

#### 5.2.2 Simple tool init file for batch programs ¶

The tool init file may be placed in `testsuite/lib` or in `testsuite/lib/tool` and must be named `tool.exp`, where tool is the name of the tool to be tested. For this example, we will use the name ‘`example`’ for the tool name, which means that the tool init file must be named `example.exp`. If the program being tested is not interactive, you can get away with this minimal tool init file to begin with:

    proc example_exit {} {}
    proc example_version {} {}

By convention, the file name for the executable for a tool should be stored in a global variable with the same name as the tool, but in all uppercase. For our example program ‘`example`’, the name of the program under test should be stored in ‘`EXAMPLE`’.

#### 5.2.3 Simple tool init file for interactive programs ¶

If the program being tested is interactive, however, you might as well define a start routine and invoke it by using a tool init file like this:

    proc example_exit {} {}
    proc example_version {} {}

    proc example_start {} {
         global EXAMPLE
         spawn $EXAMPLE
         expect {
            -re "" {}
         }
    }

    # Start the program running we want to test
    example_start

Create a directory whose name begins with your tool’s name, to contain tests. For example, if the tool name is ‘`example`’, then the directories all need to start with ‘`example.`’. Create a sample test file ending in `.exp`. You can name the file `first-try.exp`. To begin with, just write one line of Tcl code to issue a message:

    send_user "Testing: one, two...\n"

#### 5.2.4 Testing A New Tool Config ¶

Back in the `testsuite` (top level) directory, run `configure`. Typically you do this while in the build directory. You are now ready to type `make check` or `runtest`. You should see something like this:

    Test Run By bje on Sat Nov 14 15:08:54 AEDT 2015

                    === 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 report a test outcome.

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.