testgen - a tool to generate test cases

Table of Content



A tool to generate test cases.


testgen [-Ipath] [-Xextension] [-M] [-M] inputfile.tst

generates a series of .mms files from an input file.


  • -Ipath add path to the list of directories searched for include files.
  • -Xextension set the extension for the output files. Default: mms
  • -M (can be used twice) generate rules for a Makefile (see below).

Input files

The initial input file must be given on the command line. Other input files must be on the search path (see below).

An input file contains:

  • specials and
  • plain text.

Plain text is just copied to the output file (if an output file is open). At program start, no output file is open. An output file is opened and closed with a test declaration (see below).

Specials are:

  • Comments,
  • Variable Definitions,
  • Variables,
  • Include Files, and
  • Test Declarations.

All specials start with [[ and end with ]].


Test Declaration

A Test Declaration has two parts:
[[TEST number]]
then some text 
[[END number]]
The number in the TEST and in the END special must be the same. If there are (as usual) multiple test declarations in the input file, they must not overlap and the numbers must be in increasing order.

The [[TEST number]] opens the output file, the [[END number]] closes the output file. The name of the output file is formed by the number given in the TEST special, followed by '-', followed by the name of the initial input file, followed by '.', followed by the output file extension. The output file extension is mms by default and can be changed with the -X option (see above).

As said before, the text between the TEST and END special is copied written to the output file.


A Comment has the form
[[COMMENT  some text]]
[[space some text]]
The text inside the comment special is just ignored. The text inside the comment may contain other specials.

Include Files

The special
[[INCLUDE filename optionalArguments]]
opens the named file. Using the following search procedure: First the program tries to open the file using the filename as given. If that is not successful, the directory names from the search path are prepended to the filename, and an attempt is made to open the file. The search path contains the following entries:
  • the "lib" subdirectory of the current directory,
  • the current directory,
  • the "lib" subdirectory of the directory where the program testgen is located (you can download the lib directory used for the MMIX supplement here:,
  • the directory where the program testgen is located,
  • and any directories given on the command line with the -I option (see above).

If the program could be opened for reading its contents replaces the special [[INCLUDE ...]] and reading continues with the first character of the file just opened. At the end of the file, reading will continue with the first character after the INCLUDE special.

An explanation of the optional Arguments follows below. A collection of useful include files is found in the lib directory. It contains the includ files I used when writing tests for the MMIX Supplement.

Variable Definitions

The specials
[[SET name some text]]
[[GLOBAL name some text]]
define a new variable with the given name and assign it the given text as value. The name may consists of upper- and lower-case letters and the decimal digits from 0 to 9. It must not be one of the special names SET, GLOBAL, COMMENT, TEST, END, or INCLUDE.

The value of a variable can be any text. It may contain properly nested '[[' and ']]' pairs. So the value may contain specials.

The SET special defines a local variable, the GLOBAL special defines a global variable.


The special
[[name OptionalArguments]]
requires the name of a previously defined variable. The special [[name ...]] is then replaced by the value of that variable and reading continues with the first character of that value.

An explanation of the optional arguments follows below.


Variables are defined within a scope and are deleted, when the scope ends. Scopes can be nested. Variables in outer scopes can be used in inner scopes, but they can also be shadowed by variables of the same name in inner scopes.
  • The outermost scope starts with the initial input file and ends with this file. All global variables are defined in this scope.
  • Every Test has its own scope. It starts with the "[[TEST ...]]" special and ends with the "[[END ...]]" special.
  • Every include file has its own scope. It starts with the "[[INCLUDE ..." special and ends with the end of the include file.
  • Every value of a variable has its own scope, it starts with "[[SET name" or "[[GLOBAL name" and ends with the end of the value of the variable.
Include files as well as variables can be arbitrarily mixed and nested.

Optional Arguments

Variable values and include files can have parameters. These are bound to local variables with the names 1, 2, 3, ... If an include or variable special has optional arguments, first the new scope for the file or the value is created and then the optional arguments are assigned to the variables 1, 2, 3, ... in the order in which they are listed. Inside the file or the value, they can be used as [[1]], [[2]], ...

The values of optional arguments are just text. The text may contain properly nested '[[' and ']]' pairs. Multiple arguments are separated by white space outside of '[[' and ']]' pairs.


Suppose we have a simple file called "set17.mms" as follows:
	SET $1,17
and we want to test this code. We can use the following file "set17.tst":
	LOC	#100
Main	SET	$3,123

	[[INCLUDE set17.mms]]

	CMP	$0,[[register]],[[number]]
	BNZ	$0,Error
	SET	$255,0; TRAP 0,Halt,0
Error	SET	$255,1; TRAP 0,Halt,0

[[SET register $1]]

[[TEST 1]]
[[COMMENT first test: 
     set variable number 
     and expand DRIVER into 1-set17.tst.mms]]
[[SET number 17]]
[[END  1]]

[[TEST 2]]
[[COMMENT second test: 
     shadow register, set number 
     and expand DRIVER into 2-set17.tst.mms]]
[[SET register $3]]
[[SET number 123]]
[[END  2]]
testgen set17.tst
will generate two files: 1-set17.tst.mms and 2-set17.tst.mms


        LOC     #100
Main    SET     $3,123

        SET $1,17

        CMP     $0,$1,17
        BNZ     $0,Error
        SET     $255,0; TRAP 0,Halt,0
Error   SET     $255,1; TRAP 0,Halt,0
        LOC     #100
Main    SET     $3,123

        SET $1,17

        CMP     $0,$3,123
        BNZ     $0,Error
        SET     $255,0; TRAP 0,Halt,0
Error   SET     $255,1; TRAP 0,Halt,0

Example 2

The following file bubble.tst tests bubble.mms containing the procedure BubbleSort. After specifying the Driver code that includes the Program fragment under test and the predefined code OctaEqual to test two OCTA Arrays for equality, there are 6 tests, that use the variables In, Out and n to specify several test parameters.
[[SET Driver

		LOC	Data_Segment
		GREG	@
Data		[[In]]
Size		IS	[[n]]		
Sorted		[[Out]]

		LOC	#100
Main		LDA	$1,Data
		SET	$2,Size
		PUSHJ	$0,BubbleSort

		[[INCLUDE OctaEqual.mms Data Sorted Size]] 

		SET	$255,$0 
		TRAP 0,Halt,0

[[INCLUDE bubble.mms]]


[[TEST 1]]
	[[SET In  OCTA 5,0]]
	[[SET n     1]]
	[[SET Out OCTA 5,0]]

[[END 1]]

[[TEST 2]]
[[SET In OCTA 5,2,0]]
[[SET n  2]]
[[SET Out OCTA 2,5,0]]
[[END 2]]

[[TEST 3]]

[[SET In OCTA 2,5,0]]
[[SET n  2]]
[[SET Out OCTA 2,5,0]]

[[END 3]]

[[TEST 4]]
  [[SET In OCTA 3,2,5,0]] 
  [[SET n  3]] 
  [[SET Out OCTA 2,3,5,0]]
[[END 4]]

[[TEST 5]]

[[SET In OCTA 5,3,2,5,0]]
[[SET n  4]]
[[SET Out OCTA 2,3,5,5,0]]


[[END 5]]

[[TEST 6]]

[[SET In OCTA 5,3,2,5,7,11,-3,2,99,5,0]]
[[SET n  10]]
[[SET Out OCTA -3,2,2,3,5,5,5,7,11,99,0]]


[[END 6]]


testgen is written as a short lex file testgen.l.

Building testgen

Under Linux, to build testgen from the source file, you need to generate testgen.c using flex, then compile it together with symtab.c, and link it with the flex library. Both c files will need the include file symtab.h.
flex -o testgen.c  testgen.l
gcc testgen.c symtab.c -lfl -o testgen


You can download an executable for 32-Bit Linux here: testgen, for 32-Bit Windows here: testgen.exe, and for OSX you find it here: testgen.

Please help to keep this site up to date! If you want to point out important material or projects that are not listed here, if you find errors or want to suggest improvements, please send email to email