[Distutils] test suite support

Thomas Heller thomas.heller@ion-tof.com
Tue Jan 15 13:48:01 2002

From: "M.-A. Lemburg" <mal@lemburg.com>
> Why not add this as new "test" command to distutils ?! It could have
> options which programmers can then set in order for the command to find
> the test suits to run, e.g.
> python setup.py test
> I'd suggest to use an approach similar to what build_ext and the
> Extension class have to offer (in terms of code design).
I've used the following code which was posted by Berthold H=F6llmann
to this list with good success in several of my setup scripts...


class test(Command):
    # Original version of this class posted
    # by Berthold H=F6llmann to distutils-sig@python.org
    description =3D "test the distribution prior to install"

    user_options =3D [
        ('test-dir=3D', None,
         "directory that contains the test definitions"),
        ('test-prefix=3D', None,
         "prefix to the testcase filename"),
        ('test-suffixes=3D', None,
         "a list of suffixes used to generate names the of the testcases"=

    def initialize_options(self):
        self.build_base =3D 'build'
        # these are decided only after 'build_base' has its final value
        # (unless overridden by the user or client)
        self.test_dir =3D 'tests'
        self.test_prefix =3D 'test_'
        self.test_suffixes =3D None

    # initialize_options()

    def finalize_options(self):
        import os
        if self.test_suffixes is None:
            self.test_suffixes =3D []
            pref_len =3D len(self.test_prefix)
            for file in os.listdir(self.test_dir):
                if (file[-3:] =3D=3D ".py" and

        build =3D self.get_finalized_command('build')
        self.build_purelib =3D build.build_purelib
        self.build_platlib =3D build.build_platlib

    # finalize_options()

    def run(self):
        import sys
        # Invoke the 'build' command to "build" pure Python modules
        # (ie. copy 'em into the build tree)

        # remember old sys.path to restore it afterwards
        old_path =3D sys.path[:]

        # extend sys.path
        sys.path.insert(0, self.build_purelib)
        sys.path.insert(0, self.build_platlib)
        sys.path.insert(0, self.test_dir)

        # build include path for test

        for case in self.test_suffixes:
            TEST =3D __import__(self.test_prefix+case,
                              globals(), locals(),
                tested_modules =3D TEST.tested_modules
            except AttributeError:
                tested_modules =3D None
                from code_coverage import Coverage
                coverage =3D Coverage(modules=3Dtested_modules)


            if tested_modules is not None:
                # reload tested modules to get coverage of imports, etc.
                for name in tested_modules:
                    module =3D sys.modules.get(name)
                    if module:

                sys.stdout.write("code coverage:\n")

        # restore sys.path
        sys.path =3D old_path[:]

    # run()

# class test