waf_unit_test

Unit testing system for C/C++/D providing test execution:

  • in parallel, by using waf -j
  • partial (only the tests that have changed) or full (by using waf --alltests)

The tests are declared by adding the test feature to programs:

def options(opt):
        opt.load('compiler_cxx waf_unit_test')
def configure(conf):
        conf.load('compiler_cxx waf_unit_test')
def build(bld):
        bld(features='cxx cxxprogram test', source='main.cpp', target='app')
        # or
        bld.program(features='test', source='main2.cpp', target='app2')

When the build is executed, the program ‘test’ will be built and executed without arguments. The success/failure is detected by looking at the return code. The status and the standard output/error are stored on the build context.

The results can be displayed by registering a callback function. Here is how to call the predefined callback:

def build(bld):
        bld(features='cxx cxxprogram test', source='main.c', target='app')
        from waflib.Tools import waf_unit_test
        bld.add_post_fun(waf_unit_test.summary)
waflib.Tools.waf_unit_test.make_test(self)[source]

Task generator method

Create the unit test task. There can be only one unit test task by task generator.
feature:test
class waflib.Tools.waf_unit_test.utest(*k, **kw)[source]

Bases: waflib.Task.Task

Execute a unit test

color = 'PINK'
after = ['vnum', 'inst']
vars = []
runnable_status()[source]

Always execute the task if waf –alltests was used

__doc__ = '\n\tExecute a unit test\n\t'
__module__ = 'waflib.Tools.waf_unit_test'
hcode = '\tdef run(self):\n\t\t"""\n\t\tExecute the test. The execution is always successful, but the results\n\t\tare stored on ``self.generator.bld.utest_results`` for postprocessing.\n\t\t"""\n\n\t\tfilename = self.inputs[0].abspath()\n\t\tself.ut_exec = getattr(self, \'ut_exec\', [filename])\n\t\tif getattr(self.generator, \'ut_fun\', None):\n\t\t\tself.generator.ut_fun(self)\n\n\t\ttry:\n\t\t\tfu = getattr(self.generator.bld, \'all_test_paths\')\n\t\texcept AttributeError:\n\t\t\tfu = os.environ.copy()\n\t\t\tself.generator.bld.all_test_paths = fu\n\n\t\t\tlst = []\n\t\t\tfor g in self.generator.bld.groups:\n\t\t\t\tfor tg in g:\n\t\t\t\t\tif getattr(tg, \'link_task\', None):\n\t\t\t\t\t\tlst.append(tg.link_task.outputs[0].parent.abspath())\n\n\t\t\tdef add_path(dct, path, var):\n\t\t\t\tdct[var] = os.pathsep.join(Utils.to_list(path) + [os.environ.get(var, \'\')])\n\n\t\t\tif Utils.is_win32:\n\t\t\t\tadd_path(fu, lst, \'PATH\')\n\t\t\telif Utils.unversioned_sys_platform() == \'darwin\':\n\t\t\t\tadd_path(fu, lst, \'DYLD_LIBRARY_PATH\')\n\t\t\t\tadd_path(fu, lst, \'LD_LIBRARY_PATH\')\n\t\t\telse:\n\t\t\t\tadd_path(fu, lst, \'LD_LIBRARY_PATH\')\n\n\n\t\tcwd = getattr(self.generator, \'ut_cwd\', \'\') or self.inputs[0].parent.abspath()\n\t\tproc = Utils.subprocess.Popen(self.ut_exec, cwd=cwd, env=fu, stderr=Utils.subprocess.PIPE, stdout=Utils.subprocess.PIPE)\n\t\t(stdout, stderr) = proc.communicate()\n\n\t\ttup = (filename, proc.returncode, stdout, stderr)\n\t\tself.generator.utest_result = tup\n\n\t\ttestlock.acquire()\n\t\ttry:\n\t\t\tbld = self.generator.bld\n\t\t\tLogs.debug("ut: %r", tup)\n\t\t\ttry:\n\t\t\t\tbld.utest_results.append(tup)\n\t\t\texcept AttributeError:\n\t\t\t\tbld.utest_results = [tup]\n\t\tfinally:\n\t\t\ttestlock.release()\n'
waflib.Tools.waf_unit_test.summary(bld)[source]

Display an execution summary:

def build(bld):
bld(features=’cxx cxxprogram test’, source=’main.c’, target=’app’) from waflib.Tools import waf_unit_test bld.add_post_fun(waf_unit_test.summary)
waflib.Tools.waf_unit_test.options(opt)[source]

Provide the --alltests command-line option.

waflib.Tools.waf_unit_test.feature(*k)

Decorator: register a task generator method that will be executed when the object attribute ‘feature’ contains the corresponding key(s):

from waflib.Task import feature
@feature('myfeature')
def myfunction(self):
        print('that is my feature!')
def build(bld):
        bld(features='myfeature')
Parameters:k (list of string) – feature names
waflib.Tools.waf_unit_test.after_method(*k)

Decorator: register a task generator method which will be executed after the functions of given name(s):

from waflib.TaskGen import feature, after
@feature('myfeature')
@after_method('fun2')
def fun1(self):
        print('feature 1!')
@feature('myfeature')
def fun2(self):
        print('feature 2!')
def build(bld):
        bld(features='myfeature')
Parameters:k (list of string) – method names

Features defined in this module:

Previous topic

ruby

Next topic

tex

This Page