Search code examples
pythonsconspytest

Scons running py.test in different subdirectories


We have a large repository containing several Python packages(*). I want scons to run py.test in each of the sub directories and not from the project root. This is proving rather frustrating. Currently, I have this action with all error checking removed:

def runTests (target = None, source = None, env = None):
    cmd = which(env['TEST_RUNNER'])
    if cmd:
        retCode = True
        for path in env['TEST_DIR_LIST']:
            print 'Doing directory %s:' % (path)
            retCode = retCode and subprocess.call([cmd], cwd=path)
        env.Exit(retCode)

Which I call as in the SConstruct file:

runTestsCmd = env.Command('runTests', None, Action(runTests, "Running tests"))
AlwaysBuild(runTestsCmd)
Alias('test', runTestsCmd)

And in each SConscript file, I have this:

env.Append(TEST_DIR_LIST = ['PackageDirectory'])

What I get is that only one instance of py.test is run. I can see the "Doing directory X" messages but no run of py.test.

Clearly, there is a need to not clone the environment in SConscript or if the env is cloned, making sure that the addition to TEST_DIR_LIST happens on original env.

So, my questions are two fold:

  1. Is this a sensible way of doing what I want?
  2. If it is, What am I doing wrong? If it is not, what should I be doing?

(*) Yes, we are looking at changing this. No, it will not happens soon enough so I do need the above.


Solution

  • The problem is the line:

    retCode = retCode and subprocess.call([cmd], cwd=path)
    

    subprocess.call returns 0 (which evaluates to False) on success. You need to insert a not or maybe do a proper check like this:

    retcode = subprocess.call([cmd], cwd=path)
    if retcode != 0:
         print ("failed ...")
         break  # or not break if you want to continue anyway