Search code examples
python-3.xpytestyoctobitbake

Yocto Bitbake Recipe for Custom Python Script and PyTest


I have a custom Python Flask App and I build it for my embedded target using Yocto and Bitbake. I also have a set of test cases that I run on my Build Machine against the app using PyTest. I'd like the build to fail if the tests fail.

I'm looking for a Yocto way of running these tests as a custom task as part of my recipe. So far by Google search has ( unusually ) come up empty.

Here is what I have implemented so far - it works but it requires the system Python3 and various pip installs. Ideally the requirements would be built in Yocto but only for the Host machine and not the target. I haven't figured out how to do that yet.

# Run the pytest test cases against the app code after it is installed
python do_run_pytest_testsuite(){

    # Change to the testing directory
    import os
    testDir = "%s"%(d.getVar('WORKDIR', True))
    os.chdir(testDir)

    # Run pytest execute the test suite
    from subprocess import Popen, PIPE
    with open("%s/TestOutput.txt"%(testDir), "w") as testReportFile:
        with Popen(['/usr/bin/python3','-m','pytest','-v','tests/test_app.py'], stdout=PIPE, bufsize=1, universal_newlines=True) as proc:
            for line in proc.stdout:
                testReportFile.write(line)

    # Get the return code
    if not proc.returncode == 0:

        # Force Failure
        bb.fatal("Test Cases Failed! ( %s )"%(testDir))

}
addtask run_pytest_testsuite before do_install after do_configure

How can I accomplish this self-contained within the Yocto environment and not install any PyTest dependencies for the target board.


Solution

  • First I would have a look at poky/meta/recipes-devtools/python to get an idea what python recipes are available (mind which release you are working on).

    Then you can add a dependency on the native version of the recipes e.g. DEPENDS = "python3-native python3-yaml-native" (or whatever packages you need to run your python application)

    Then add a task that runs your application

    do_run_testsuite(){
      python3 ${WORKDIR}/test/test_app.py
    }
    addtask do_run_testsuite before do_install after do_configure
    

    Maybe also check the openembedded python layer

    If you don't find all the dependencies you need, it is relatively easy to add a pip package to your own layer (just have a look at the recipes in the mentioned layers).