Writing Tests for Autofonce
Though autofonce
was originally developed to run the Autoconf
Testsuite of GnuCOBOL, it provides a convenient way to write tests for
any project, especially as it provides additionnal macros (that have
no equivalent in the Autoconf world). Here is a description of how to
write tests for autofonce
.
Example of a Simple Test
Here is a very simple example of test:
# Start of a test, and the name that will be displayed
AT_SETUP([Example test])
# can be used to select tests to run:
AT_KEYWORDS([example test autofonce])
# create a file `file` with its content
AT_DATA([file], [
content of file
on multiple lines
])
# call some command, check its exit code, stdout, stderr
AT_CHECK([cat file], [0], [stdout of my command], [stderr of my command])
# you can do more, ignore some results, run more tests in case of failure, etc.
# end of the test
AT_CLEANUP
Structure of a Test Suite
A testsuite is usually composed of many tests in different files.
autofonce
has two behavior to handle collections of test:
You can provide the directory containing the tests.
autofonce
will scan the directory and recursively all sub-directories, looking for files ending with .at suffix. It will also consider any file within a test directory as a file that should be copied to run the corresponding tests (AT_COPY_ALL
mode).You can provide a master file, that contains the list of all the tests to include. Such a file would look like this:
AT_INIT([Autofonce tests]) AT_COLOR_TESTS AT_TESTED([autofonce]) AT_BANNER([Simple tests]) m4_include([simple_tests.at]) AT_BANNER([Tests with copies]) m4_include([copy_tests.at])
Notice the use of
m4_include
to include specific files. These files are searched in a path, specified in the configuration file or on the command-line.
Test Format Specification
Autoconf defines all its macros starting with the AT_
prefix,
and expect users to define additional macros with other prefixes. So,
for autofonce
additional macros, the AF_
prefix can be
used. However, autofonce
will always understand both prefixes
for any of its macros, but will use the previous naming scheme during
promotion (i.e. AT_
for Autoconf Standard macros, and
AF_
for its own extension macros).
Escaping within arguments
Arguments can be parsed using two different passes:
Most arguments are converted to strings using the two passes
As an exception, the run-if-fail and run-if-pass arguments of
AT_CHECK()
(4th and 5th arguments) go only through the first pass and then their content is interpreted as a list of macros.
The two passes can be described as follows:
Brackets must always match each-other, i.e. a left bracket must always be matched by a right bracket (
...[...]...
). Quadrigraphs (during the second pass) should be used for isolated brackets.During the first pass:
Spaces before the first non space character of the argument are skipped
Brackets at the first level are removed:
A[B]C[D]E
becomesABCDE
Other levels of brackets are kept until the second pass:
A[B[C]D]E
becomesAB[C]DE
Parentheses outside of the first level of brackets must match each-other. A non-matched left parenthesis fails as the argument never terminates, while a non-matched right parenthesis finishes the last argument of the macro.
#
is interpreted as a simple character and not a comment
During the second pass:
Brackets at the first level are removed:
A[B]C[D]E
becomesABCDE
. Since these brackets were formerly the second level of bracket of the first pass, it means that an initialA[B[C]D]E
argument becomesABCDE
after the two passes.Other levels of brackets are kept
Parenthesis are not interpreted as special characters
The following list of escape sequences (quadrigraphs) are translated:
@<:@
becomes[
@:>@
becomes]
@$|@
becomes$
@%:@
becomes#
@&t@
becomes :code:`` (empty)@{:@
becomes(
(version > 0.8)@:}@
becomes)
(version > 0.8)
Toplevel Macros
These macros should only be used outside of a test.
AT_COPYRIGHT([copyright])
: copyright notice of the testsuiteAT_INIT([testsuite-name])
: name of the testsuiteAT_COLOR_TESTS
: discardedAT_TESTED([executables])
: list of space separated commandsAT_BANNER([banner])
: a banner separating testsm4_include([file.at])
: include macros from a file.autofonce
will try to find the file withing a directorytestsuite.src
in the same directory. Note that behaviors specified in the included file have a scope limited to this included file.
Additionnal macros understood only by autofonce
. These macros
impact tests following them, and have a scope that finishes at the end
of the file containing them:
AF_ENV([shell code])
: this shell code will be included in the script run before running any check in a test;AF_COPY_ALL([true/false])
: if true, copy all files in the directory of the test file in the test directory when they are run;AF_LINK_ALL([true/false])
: if true, link all files in the directory of the test file in the test directory when they are run (i.e. same asAF_COPY_ALL
, but link instead of copy, often to save space);AF_SUBST([env-variables])
: a list of space-separated environment variables inautofonce
environment, that should be substituted back in the stdout and stderr output of commands run in checks.For example,
AF_SUBST([HOME])
would replace/home/user
by${HOME}
in all following commands. It can be used to check the output of a command that could include absolute paths corresponding to environment variables.Use
AF_SUBST([])
to disable any substitution in following commands (can be useful as substitutions are expensive on big outputs).Use the special
AUTOFONCE
name to specify that the run dir, build dir and source dirs should be substituted too, respectively by${AUTOFONCE_RUN_DIR}/${TEST_ID}
,${AUTOFONCE_BUILD_DIR}
and${AUTOFONCE_SOURCE_DIR}
.
Test Macros
Typical Autoconf macros are:
AT_SETUP([test-name])
: beginning of a testAT_KEYWORDS([keywords])
: list of space separating keywords to select the testAT_DATA([file-name], [file-content])
: create the corresponding fileAT_CHECK([shell-command], [retcode], [stdout], [stderr], [run-if-fail], [run-if-pass])
: all arguments are optional except for the first one. run-if-fail and run-if-pass should always be specified within brackets (as otherwise, brackets within them would be removed).[ignore]
can be used in the retcode, stdout or stderr places to ignore any difference there.AT_CLEANUP
: end of testAT_SKIP_IF([shell-condition])
: test should be skipped if shell-condition is trueAT_XFAIL_IF([shell-condition])
: failure of test is expected if shell-condition is trueAT_FAIL_IF([shell-condition])
: make test fail if shell-condition is trueAT_CAPTURE_FILE([file-name])
: capture file in case of failure
Autofonce additional macros are:
AF_ENV([shell])
: shell code to include before running checks (typically to specify environment variables)AF_COPY([files])
: copy this space-separated list of files from the test directory to the directory where the test will be runAF_LINK([files])
: link this space-separated list of files to the test directory to link from the directory where the test will be run
Autoconf Documentation
Read https://www.gnu.org/software/autoconf/manual/autoconf-2.67/html_node/Writing-Testsuites.html for a detailed description of Autoconf test macros.