skip to Main Content

I would like to generate parameters for a test

def test_project_run(prj_root, board_type, successful_output, test_input)

using the pytest framework.
I want the parameters to be based on data in a YAML file with all needed information

Zephyr:
  projects:
     - prj_root: "/home/ubuntu/nrf5340_threads"
       prj_name: "threads"
       test_input: []
       successful_output: ["Toggled led0:", "Toggled led1:"]
       boards_to_test_on: ["nrf5340", "mps2-an521"]
     - prj_root: "/home/ubuntu/nrf5340_psa"
       prj_name: "psa"
       test_input: ["run"]
       successful_output: ["encrypted"]
       boards_to_test_on: ["nrf5340", "mps2-an521" ]

From all this parameters I would like to create a costum ID from prj_name and board_to_test_on. So I would be able to use the -k option to run a specific test.

2

Answers


  1. Do you mean custom ID?

    import yaml
    import pytest
    
    with open('test_data.yaml', 'r') as f:
        data = yaml.safe_load(f)
    
    test_data = []
    for project in data['Zephyr']['projects']:
        prj_root = project['prj_root']
        prj_name = project['prj_name']
        successful_output = project['successful_output']
        test_input = project['test_input']
        for board_type in project['boards_to_test_on']:
            test_id = f"{prj_name}_{board_type}"
            test_data.append((prj_root, board_type, successful_output, test_input, test_id))
    
    Login or Signup to reply.
  2. I wrote a library called Parametrize From File that aims to make it easy to load test parameters from structured data files. Here’s what basic usage looks like:

    # test_demo.yml
    test_demo:
        - a: 1
          b: 2
        - a: 2
          b: 3
    
    # test_demo.py
    import parametrize_from_file as pff
    
    @pff.parametrize
    def test_demo(a, b):
        assert a + 1 == b
    

    Hopefully you can see how the values in the YAML file correspond directly to the parameters of the test function. In your case, there are two additional complexities to consider:

    1. Generating test IDs from other parameters.
    2. Creating separate test cases for each board type.

    The key to both of these features is providing the pff.parametrize(preprocess=...) argument, which allow you to perform arbitrary transformations on the test parameters before running the test. The snippet below shows exactly how to do this:

    import parametrize_from_file as pff
    
    def preprocess(params_in):
        params_out = []
    
        for template in params_in:
    
            # Create a separate test case for each board:
            for board in template.pop('boards_to_test_on'):
                p = template.copy()
    
                # The 'id' parameter is handled specially: it becomes the test
                # ID used by pytest.  Note that we get rid of the 'prj_name'
                # parameter, because it's not an argument to the test function.
                p['id'] = f"{p.pop('prj_name')}-{board}"
    
                # Add a new 'board_type' parameter:
                p['board_type'] = board
    
                params_out.append(p)
    
        return params_out
    
    # It's only necessary to specify a path to the parameter file if it
    # can't be inferred from name of the test script.
    @pff.parametrize(path='test_data.yaml', preprocess=preprocess)
    def test_project_run(prj_root, board_type, successful_output, test_input):
        ...
    
    $ pytest test_project.py -q
    ....
    4 passed in 0.10s
    
    $ pytest test_project.py -q -k threads
    ..
    2 passed, 2 deselected in 0.09s
    
    $ pytest test_project.py -q -k nrf
    ..
    2 passed, 2 deselected in 0.08s
    

    I don’t understand the meaning of the "Zephyr/projects" keys, so I didn’t consider that in the example above. Parametrize From File assumes that the top level keys in the parameter file correspond to the names of the test functions (e.g. test_project_run in this case), but if necessary you can customize this using the pff.parametrize(loaders=...) argument.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search