tcltest Part 2 – Multi-Module Test Suite

The Problem

Now that I created my first tcltest module, I want to break up my tests into several modules. I also want to separate my tests from my source code.

The Solution

In this tutorial, I will pick up from the last time. Recall that in the previous post, I created the first test module, but both the source code (sum.tcl) and the tests are in the same directory. While this arrangement is fine for small projects, as they grow, I will want to separate the source code from the test code to improve code management.

From the previous tutorial, the directory contains 3 files:

  • sum.tcl – The software under test (SUT)
  • all.tcl – The “main” test script
  • sum.test – The test module which tests function sum

To separate the source code from the tests, we start by creating two sub directories: src and tests and move the files to these directories according to their roles:

mkdir src tests
mv sum.tcl src
mv all.tcl sum.test tests

Next, we go into the tests directory and attempt to run the tests again:

cd tests
tclsh all.tcl

This time, we ran into a error because the file sum.tcl is no longer in the same directory with the test module:

Test file error: couldn't read file "sum.tcl": no such file or directory
    while executing
"source sum.tcl"
    (file "/home/haiv/src/tcl/tcltest_part2/tests/sum.test" line 7)

To fix it, modify line 7 of sum.test so it reads:

source ../src/sum.tcl

Now, run the tests again and everything should work as before. At this point, we successfully separate the tests from the source code. From now on, our test modules will go into the tests directory and the source code will go into the src directory.

Next, we are adding a new function: square, which returns the square of a number. The new function resides in src/square.tcl:

proc square {x} {
    expr {$x * $x} 

Our next step is to add the tests for function square. Again, for the sake of brevity, i will ommit the test descriptions, but encourage you to add them to enhance test readablity.

# square.test

package require tcltest
namespace import ::tcltest::*

# Software under test
source ../src/square.tcl

test square_ofZeroExpectsZero {
    Test: [square 0] == 0
} -body {
    square 0
} -result 0

test square_ofNegativeExpectsPositive {} -body {
    square -9
} -result 81

test square_ofPositiveExpectsPositive {} -body {
    square 19
} -result 361


Notes: This test module is very similar to the sum.test module so it is tempting to copy and paste. Please keep in mind that when you copy and paste, be sure to check the code. Here is the tests output:

Tests running in interp:  /usr/bin/tclsh
Tests located in:  /home/haiv/src/tcl/tcltest_part2/tests
Tests running in:  /home/haiv/src/tcl/tcltest_part2/tests
Temporary files stored in /home/haiv/src/tcl/tcltest_part2/tests
Test files run in separate interpreters
Running tests that match:  *
Skipping test files that match:  l.*.test
Only running test files that match:  *.test
Tests began at Mon Mar 28 07:13:18 PM PDT 2011

Tests ended at Mon Mar 28 07:13:18 PM PDT 2011
all.tcl:	Total	6	Passed	6	Skipped	0	Failed	0
Sourced 2 Test Files.

Note that the output now shows 2 files: square.test and sum.test. Also note that square.test precedes sum.test: tcltest run them in alphabetical order of file names. However, do not assume that order: in general, unit test cases should be independent of each other.


This tutorial shows you how to separate the tests from the source code for better code management. It also demonstrate a multi-module test suite. In the next installment, I am going to go into test filters.


One thought on “tcltest Part 2 – Multi-Module Test Suite

  1. Pingback: tcltest Part 3 – Include and Exclude Tests « Hai’s Blog

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s