The testing system for Boost.Build is derived from the TestCmd Python module used for testing the Scons build tools. The changes are very few, and I hope that some of them may be adopted by TestCmd in future.
Unfortunately, there are not documentation for TestCmd, apart from the comments in code, so the most essential base methods will be described here.
The basic steps of testing a build system behaviour are:
For example, suppose that the current working directory contains the a file test1.py and a subdirectory test1 with files foo.cpp, Jamfile and Jamrules. A definition of function main is the only content of foo.cpp, Jamfile builds an executable foo from foo.cpp and Jamrules is empty. Finally, test1.py contains:
import BoostBuild
# Create a temporary working directory
t = BoostBuild.Tester()
# Make content of the working directory equal to the content of the 'test1' directory.
t.copy_tree('test1')
# Invoke the build system and record which changes were made
t.run_build_system("-sTOOLS=borland")
# First, create a list of three filenames with t.mul
# Second, check if those files were added as result of the last build system invocation.
t.expect_addition(t.mul("bin/foo/borland/debug/runtime-link-dynamic/foo", [".exe", ".obj", ".tds"]))
# Invoke the build system once again
t.run_build_system("clean")
# Check if the files added previously were removed.
t.expect_removal(t.mul("bin/foo/borland/debug/runtime-link-dynamic/foo", [".exe", ".obj", ".tds"]))
This is all needed for a minimal test (and to find a bug in the borland toolset!). Running the test1.py gives the following output:
File bin/foo/borland/debug/runtime-link-dynamic/foo.tds not removed as expected
FAILED test of D:\MyDocu~1\Work\build\boost-build\boost-build -d0
at line 144 of TestBoostBuild.py (expect_removal)
from line 12 of test1.py
Overview of the most important methods of class TestBoostBuild follows.
The class TestBoostBuild creates a temporary directory in its constructor and changes to that directory. It can be modified by calling these methods:
The method read, inherited from the TestCmd class, can be used to read any file in the working directory and check its content. TestBoostBuild adds another method for tracking changes. Whenever build system is run (via run_build_system), the state of working dir before and after running is recorded. In addition, difference between the two states -- i.e. lists of files that were added, removed, modified or touched -- is stored in two member variables, tree_difference and unexpected_difference.
After than, the test author may specify that some change is expected, for example, by calling expect_addition("foo"). This call will check if the file was indeed added, and if so, will remove its name from the list of added files in unexpected_difference.Likewise, it's possible to specify that some changes are not interesting, for example a call ignore("*.obj") will just remove every files with ".obj" extension from unexpected_difference.
When test has finished with expectations and ingoring, the member unexpected_difference will contain the list of all changes not yet accounted for. It is possible to assure that this list is empty by calling expect_nothing_more member function.
The entire test system is composed of single class BoostBuild.Tester, derived form TestCmd.TestCmd. The methods defined in BoostBuild.Tester are described below.
Effects:
Effects:
Replaces the current working dir with content of directory at tree_location. If tree_location is not absolute pathname, it will be treated as relative to self.original_workdir.
Effects:
Sets the access and modification times for all files in names to the current time. All the elements names should be relative paths.
Effects:
Stores the new state of the working directory in self.tree. Computes the difference between previous and current trees and store them in variables self.tree_difference and self.unexpected_difference.
Both variables are instances of class tree.Trees_different, which have four attributes: added_files, removed_files, modified_files and touched_files. Each is a list of strings.
Accordingly to the number of changes kinds that are detected, there are four methods that specify that test author expects a specific change to occur. They check self.unexpected_difference, and if the change is present there, it is removed. Otherwise, test fails.
Each method accepts a list of names. Those names are always unix-style, even on other systems.
Note:The mul member might be usefull to create lists of names.
Note:The file content can be examined using TestCmd.read function.
The members are:
There's also a member expect_nothing_more, which checks that all the changes are either expected or ignored, in other words that unexpected_difference is empty by now.
There are five methods which ignore changes made to the working tree. They silently remove elements from self.unexpected_difference, and don't generate error if element is not found. They accept shell style wildcard.
The following methods correspond to four kinds of changes:
The method ignore(self, wildcard) ingores all the changes made to files that match a wildcard.
Precondition:Each passed arguments must be either string or a list of strings.
Effects:Returns a list of strings which are formed by taking one string from each passed argument and joining them. The order of strings corresponds to lexicagraphical ordering of sequences of indices.
Example:
mul("/home/ghost", [".bashrc", ".bash_profile"])
will return
["/home/ghost/.bashrc", "/home/ghost/.bash_profile"]
Last modified: April 4, 2002
© Copyright Vladimir Prus 2002. Permission to copy, use, modify, sell and distribute this document is granted provided this copyright notice appears in all copies. This document is provided ``as is'' without express or implied warranty, and with no claim as to its suitability for any purpose.