On 12/30/24 14:17, Eduardo Costa wrote:
Hi!,

I'm new to dejagnu and would like to know, as I see the `debug.exp'
file under `/usr/share/dejagnu', what is the 'tcl debugger' mentioned
in this file that we can use to debug the scripts? Is it referring to
`tkcon', `tcl-pro-debug', or other I don't know about?

There is some kind of ancient debugging support in Expect that I do not yet fully understand that `debugger.exp' extends.

I have so far always used "printf debugging" with DejaGnu, but I do have updating lib/debugger.exp on my TODO list, as it uses an old API for watchpoints that was deprecated in Tcl 8.4 and removed in Tcl 8.5.(Tcl still has watchpoints, just with a slightly different interface now.)

Also, if I want to test a C program, I understand I can use `expect'
functions (maybe together with utility functions declared in, say,
`dg.exp') to compile and examine it's output, but what about testing
it at API level (the internal functions it's made of)?

The `dg.exp' module is intended for testing compilers and interpreters.  (DejaGnu was originally written to test the GNU toolchain:  GCC, GDB, GNU binutils, etc.)  That module is useful for testing programs that take input and produce output or additional programs.

I've had some success including `dejagnu.h' in a test file, moving all
my code into a convenience library I now link this test file against,
and using `dejagnu.h' functions from within such test-file to somewhat
get to see the expected output when I run `make check'.

This is how unit testing with DejaGnu is supposed to work:  you write unit test programs that emit DejaGnu's unit test protocol and use the "host_execute" procedure in lib/dejagnu.exp in your testsuite code to run the unit test programs and collect the results.

The `dejagnu.h' header (the entirety of "libdejagnu" currently) provides an interface for C and C++ programs to produce DejaGnu unit test protocol.  Note that `dejagnu.h' is GPL, but the protocol is simple and documented if you cannot use the GPL for your program and thus need to write your own support module.

The GNU Coding Standards recommend providing library interfaces when practical. (<URL:https://www.gnu.org/prep/standards/standards.html#Standards-for-Graphical-Interfaces>) Organizing your code as a frontend to a library also allows you to easily add other frontends in the future.

You have already taken the first steps on this path: consider that you now have one "regular use" frontend and one "unit test" frontend. You can use the Expect facilities in DejaGnu for testing a CLI "regular use" frontend (atop the backend; this is known as "system testing") in addition to using the "unit test" frontend to directly test the backend (known as (of course) "unit testing"). Well-engineered software has both kinds of tests.

I did setup a `Makefile.am' under `testsuite' to compile this test
program and called `host-execute' on it, but I'm now guessing the
"normal" workflow is to compile whatever the test files via
tcl/expect/dejagnu, maybe use `dg.exp' functions to check the result,
and also `framework.exp' functions (i.e: `setup_xfail',
`check-conditional-xfail', etc) to have it automatically responding to
the output? Is this more or less how it works?

Nope!  Look at DejaGnu's own Makefile.am for the unit tests for `dejagnu.h' itself (search for "check_PROGRAMS") for a worked example.  (It is slightly complicated because DejaGnu does not use recursive make, but should give you the basic idea.)

The `dg.exp' functions are only intended for compiling test programs when testing compilers or other toolchain components. Normal unit test programs should be built using make, as dependencies of the "check" target.

There is a sound software engineering basis for this:  tests should have, as much as possible, the same environment as the "serious" code to ensure that bugs cannot be missed in testing due to a different environment.

Note that for now I'm not interested in cross-compilation or remote
debugging, but simply using dejagnu to test my program as thoroughly
as possible, so I'd really appreciate any comments or insights,
because nor I've had much previous experience with tcl/expect, neither
I still fully understand dejagnu's architecture. Also, a comment or
two regarding `config/gdb-comm.exp' and `config/gdb-stub.exp' would be
really appreciated, if only to figure out how these are supposed to be
used.

Those appear to be interface modules for using GDB to load and run programs on embedded targets.  For native unit tests, you will want the "unix" target, which simply runs the test programs on the same host as DejaGnu itself.

If it would be the case that some small c project is known to exist
doing just what I'm trying to, a pointer to it would be really
helpful. I know of gcc, coreutils, and gdb, gnu poke (mostly tests
interactively), and `ctlseqs' found in sourceware's git repository
(doesn't test the API but program's output), but the formers are way
too optimized for a newcomer to understand anyways. Even I get back to
these every now and then as I learn new things about
dejagnu/tcl/expect on their respective manuals/books, I suspect I'm
far from making full sense of it.

The best sources in my experience have been the "n" section manpages for the commands in Tcl and the expect(1) manpage for Expect itself.  The DejaGnu reference manual is still incomplete; improving it remains on my TODO list.

DejaGnu's own testsuite, while not always ideal examples, is also a good place to look.

For `dejagnu.h', the C and C++ programs in testsuite/libdejagnu give simple cases of using the API, although they do not actually perform any tests, instead simply emitting the results requested on their command lines.

However, the `harness.exp' file in that same directory is not a good example for running unit tests.  Instead, look at the tests for the framework side of the unit test protocol to find a better example (in testsuite/runtest.main/nested/testsuite/stat.test/unit-sub.exp) of using host_execute with a fairly complex command.


-- Jacob

Reply via email to