scons e python unit testano le migliori pratiche

3

Sto usando scons per costruire un progetto di grandi dimensioni contenente un mix di C ++ e Python. Vorrei che gli scons eseguissero i test delle unità Python usando nose oppure no. Al momento disponiamo di un lungo elenco di file di test ed eseguiamo un test builder su ciascuno di essi. Questo fa sì che ogni file di test venga eseguito come uno script separato che si sente inelegante e inefficiente.

C'è un modo migliore per farlo?

    
posta Sardathrion 26.07.2012 - 09:29
fonte

1 risposta

3

Alla fine, ho creato un builder personalizzato che ha chiamato un runner di test esterno. Basta salvare quanto segue in site_scons/site_tools/run_py_test.py , importarlo nel file SConstruct principale e usarlo come faresti con qualsiasi altro builder.

import sys
import os
import subprocess
try:
    from fabulous.color import red, green, fg256
    utest_fail = lambda x: sys.stderr.write(red(x).as_utf8+'\n')
    utest_pass = lambda x: sys.stdout.write(green(x).as_utf8+'\n')
    utest_directory = lambda x: sys.stdout.write(fg256(63, x).as_utf8+'\n')
except ImportError:
    sys.stdout.write('Fabulous module not found: '
            'To install it, run sudo pip-python install fabulous\n')
    utest_fail = lambda x: sys.stderr.write(x)
    utest_pass = lambda x: sys.stdout.write(x)
    utest_directory = lambda x: sys.stdout.write(x+'\n')


def which (program):
    """Reimplementation of the shell command 'which'.

    @see: http://stackoverflow.com/a/377028/232794
    @type program: String
    @param program: The program name.
    @return The full path to the program or None.
    """
    is_exe = lambda x: os.path.isfile(x) and os.access(x, os.X_OK)
    fpath, fname = os.path.split(program)
    if fpath:
        if is_exe(program):
            return program
    else:
        for path in os.environ["PATH"].split(os.pathsep):
            exe_file = os.path.join(path, program)
            if is_exe(exe_file):
                return exe_file
    return None


def runTests (target = None, source = None, env = None):
    """Run a test aggregation tool (by default py.test) in directories 
    provided in TEST_DIR_LIST.

    @type target: String
    @param target: A target.
    @type source: String
    @param source: A source.
    @type env: SCONS ENV.
    @param env: This should contain TEST_RUNNER or TEST_DIR_LIST otherwise
                defaults values are used.
    """
    if not 'TEST_RUNNER' in env:
        env.Append(TEST_RUNNER='py.test')
    if not 'TEST_DIR_LIST' in env:
        sys.stderr.write("+++ TEST_DIR_LIST is not set, using project root.\n")
        env.Replace(TEST_DIR_LIST=['./'])
    cmd = which(env['TEST_RUNNER'])
    if cmd:
        retCode = 0
        for path in env['TEST_DIR_LIST']:
            utest_directory('\n+++ Running unit tests in directory %s:' % (path))
            retCode += subprocess.call([cmd], cwd=path)
        line = "="*80 + "\n"
        if retCode:
            try:
                utest_fail(line + u" ✘  Unit tests failed!\n" + line)
            except UnicodeEncodeError:
                utest_fail(line + " -  Unit tests failed!\n" + line)
        else:
            try:
                utest_pass(line + u" ✓  Unit tests passed.\n" + line)
            except UnicodeEncodeError:
                utest_pass(line + " +  Unit tests passed.\n" + line)
        env.Exit(retCode)
    else:
        sys.stderr.write("*** Could not find %s command\n" % (
            env['TEST_RUNNER']))
        env.Exit(-1)

Se stai per votare, almeno lascia un commento sul motivo per cui questa è una cattiva risposta in modo che possa essere migliorata !!!

    
risposta data 28.11.2012 - 09:30
fonte

Leggi altre domande sui tag