Commit 0e17fac7 authored by BOHMRR's avatar BOHMRR
Browse files

Merge branch '4-migrate-to-pytest-framework' into 'main'

"Migrate software test framework to pytest (177)"

See merge request !52
parents 6cf97a68 811bb182
Loading
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -46,6 +46,8 @@ scripts/ref/
scripts/test/
scripts/out/
scripts/self_test_summary.txt
tests/dut
tests/ref

# Python files that pop up when running scripts
__pycache__/
+57 −72
Original line number Diff line number Diff line
@@ -6,6 +6,8 @@ variables:
  OUT_FORMATS_CHANNEL_BASED: "stereo mono 5_1 5_1_2 5_1_4 7_1 7_1_4"
  OUT_FORMATS_SCENE_BASED: "FOA HOA2 HOA3"
  OUT_FORMATS_BINAURAL: "BINAURAL BINAURAL_ROOM"
  EXIT_CODE_NON_BE: 123
  EXIT_CODE_FAIL: 1


# This sets when pipelines are created. Jobs have more specific rules to restrict them.
@@ -253,7 +255,7 @@ asan-on-merge-request-linux:


# compare bit exactness between target and source branch
self-test-on-merge-request:
pytest-on-merge-request:
  extends: 
    - .test-job-linux
    - .rules-merge-request
@@ -295,54 +297,51 @@ self-test-on-merge-request:
    - mv IVAS_dec ../IVAS_dec_ref
    - cd ..

    ### re-checkout the commit from the source branch to have up-to-date self_test.py and scripts/testv (and actually everything)
    ### re-checkout the commit from the source branch to have up-to-date test scripts and test vectors (and actually everything)
    - git checkout $source_branch_commit_sha

    ### run selftest
    - ls -altr scripts/testv
    - python3 ./scripts/self_test.py --encref IVAS_cod_ref --decref IVAS_dec_ref --enctest IVAS_cod_test --dectest IVAS_dec_test | tee test_output.txt
    - python3 ./scripts/self_test.py --encref IVAS_cod_ref --decref IVAS_dec_ref --enctest IVAS_cod_test --dectest IVAS_dec_test scripts/config/self_test_evs.prm | tee test_output_evs.txt
    ### analyse test output

    # some helper variables - "|| true" to prevent failures from grep not finding anything
    - evs_non_be_flag=$(echo $CI_MERGE_REQUEST_TITLE | grep -c --ignore-case "\[evs[ -]*non[ -]*be\]") || true
    - non_be_flag=$(echo $CI_MERGE_REQUEST_TITLE | grep -c --ignore-case "\[non[ -]*be\]") || true
    - run_errors=$(cat test_output.txt test_output_evs.txt | grep -c "test conditions had run errors") || true
    - bitexact=$(cat test_output.txt | grep -c "All [0-9]* tests are bitexact") || true
    - bitexact_evs=$(cat test_output_evs.txt | grep -c "All [0-9]* tests are bitexact") || true
    - EXIT_CODE_NON_BE=123
    - EXIT_CODE_FAIL=1
    - expected_nonbe_1=0
    - expected_nonbe_2=0
    - expected_nonbe_3=0
    - fail_1=0
    - fail_2=0
    - fail_3=0

    # check for crashes during the test, if any happened, fail the test
    - if [ $run_errors != 0 ] ; then echo "Run errors in self_test.py"; fail_1=1; fi
    ### prepare pytest
    # create short test vectors
    - python3 tests/create_short_testvectors.py
    # rename test binaries back
    - mv IVAS_cod_test IVAS_cod
    - mv IVAS_dec_test IVAS_dec
    # create references
    - python3 -m pytest tests -v --update_ref 1 -m create_ref
    - python3 -m pytest tests -v --update_ref 1 -m create_ref_part2
    - python3 -m pytest tests/test_param_file.py -v --update_ref 1 -m create_ref --param_file scripts/config/self_test_evs.prm

    ### run pytest
    - exit_code=0
    - python3 -m pytest tests -v --junit-xml=report-junit.xml || exit_code=$?
    - zero_errors=$(cat report-junit.xml | grep -c 'errors="0"') || true

    # check for non bitexact output and store exit code to also always run the SBA pytest
    - if [ $bitexact == 0 ] && [ $non_be_flag == 0 ] ; then echo "Non-bitexact cases without non-BE tag encountered"; fail_1=1; fi
    - if [ $bitexact == 0 ] && [ $non_be_flag != 0 ]; then echo "Non-bitexact cases with non-BE tag encountered"; expected_nonbe_1=1; fi
    - if [ $zero_errors != 1 ]; then echo "Run errors in pytest"; fail_1=1; fi

    # check for non bitexact EVS output
    - if [ $bitexact_evs == 0 ] && [ $evs_non_be_flag == 0 ] ; then echo "Non-bitexact EVS cases without EVS-non-BE tag encountered"; fail_2=1; fi
    - if [ $bitexact_evs == 0 ] && [ $evs_non_be_flag != 0 ] ; then echo "Non-bitexact EVS cases with EVS-non-BE tag encountered"; expected_nonbe_2=1; fi
    - if [ $exit_code -eq 1 ] && [ $non_be_flag == 0 ]; then echo "pytest run had failures without non-BE tag encountered"; fail_1=1; fi
    - if [ $exit_code -eq 1 ] && [ $non_be_flag != 0 ]; then echo "pytest run had failures with non-BE tag encountered"; expected_nonbe_1=1; fi

    ### run SBA pytest
    ### run pytest for EVS cases
    - exit_code=0
    - python3 ./scripts/ivas_pytests/self_test_b.py --encref IVAS_cod_ref --decref IVAS_dec_ref --encdut IVAS_cod_test --decdut IVAS_dec_test || exit_code=$?
    - zero_errors=$(cat report-junit.xml | grep -c 'errors="0"') || true
    - python3 -m pytest tests/test_param_file.py -v --param_file scripts/config/self_test_evs.prm --junit-xml=report-junit-evs.xml || exit_code=$?
    - zero_errors=$(cat report-junit-evs.xml | grep -c 'errors="0"') || true

    - if [ $zero_errors != 1 ]; then echo "Run errors in SBA pytest"; fail_3=1; fi
    - if [ $zero_errors != 1 ]; then echo "Run errors in pytest for EVS"; fail_2=1; fi

    - if [ $exit_code -eq 1 ] && [ $non_be_flag == 0 ]; then echo "pytest run had failures without non-BE tag encountered"; fail_3=1; fi
    - if [ $exit_code -eq 1 ] && [ $non_be_flag == 1 ]; then echo "pytest run had failures with non-BE tag encountered"; expected_nonbe_3=1; fi
    - if [ $exit_code -eq 1 ] && [ $evs_non_be_flag == 0 ]; then echo "Non-bitexact EVS cases without EVS-non-BE tag encountered"; fail_2=1; fi
    - if [ $exit_code -eq 1 ] && [ $evs_non_be_flag != 0 ]; then echo "Non-bitexact EVS cases with EVS-non-BE tag encountered"; expected_nonbe_2=1; fi

    # Check results from all three tests
    - if [ $fail_1 -eq 1 ] || [ $fail_2 -eq 1 ] || [ $fail_3 -eq 1 ]; then exit $EXIT_CODE_FAIL; fi
    - if [ $expected_nonbe_1 -eq 1 ] || [ $expected_nonbe_2 -eq 1 ] || [ $expected_nonbe_3 -eq 1 ]; then exit $EXIT_CODE_NON_BE; fi
    # Check results from both tests
    - if [ $fail_1 -eq 1 ] || [ $fail_2 -eq 1 ]; then exit $EXIT_CODE_FAIL; fi
    - if [ $expected_nonbe_1 -eq 1 ] || [ $expected_nonbe_2 -eq 1 ]; then exit $EXIT_CODE_NON_BE; fi
    - exit 0

  allow_failure:
@@ -352,14 +351,13 @@ self-test-on-merge-request:
    name: "mr-$CI_MERGE_REQUEST_IID--sha-$CI_COMMIT_SHORT_SHA--stage-$CI_JOB_STAGE--results"
    when: always
    paths:
      - test_output.txt
      - test_output_evs.txt
      - scripts/test/logs/
      - scripts/ref/logs/
      - report-junit.xml
    expose_as: 'Self test results'
      - report-junit-evs.xml
    expose_as: 'pytest results'
    reports:
      junit: report-junit.xml
      junit:
        - report-junit.xml
        - report-junit-evs.xml


# ---------------------------------------------------------------
@@ -436,37 +434,26 @@ codec-comparison-on-main-push:
    ### re-checkout the latest commit in the main branch
    - git checkout $latest_commit

    ### run selftest
    - ls -altr scripts/testv
    - python3 ./scripts/self_test.py --encref IVAS_cod_ref --decref IVAS_dec_ref --enctest IVAS_cod_test --dectest IVAS_dec_test | tee test_output.txt

    ### analyse test output

    # some helper variables - "|| true" to prevent failures from grep not finding anything
    # helper variable - "|| true" to prevent failures from grep not finding anything
    - non_be_flag=$(echo $CI_MERGE_REQUEST_TITLE | grep -c --ignore-case "\[non[ -]*be\]") || true
    - run_errors=$(cat test_output.txt | grep -c "test conditions had run errors") || true
    - bitexact=$(cat test_output.txt | grep -c "All [0-9]* tests are bitexact") || true
    - EXIT_CODE_NON_BE=123
    - EXIT_CODE_FAIL=1

    - selftest_exit_code=0

    # check for crashes during the test, if any happened, fail the test
    - if [ $run_errors != 0 ] ; then echo "Run errors in self_test.py"; exit $EXIT_CODE_FAIL; fi

    # check for non bitexact output and store exit code to also always run the SBA pytest
    - if [ $bitexact == 0 ] && [ $non_be_flag == 0 ] ; then echo "Non-bitexact cases without non-BE tag encountered"; selftest_exit_code=$EXIT_CODE_FAIL; fi
    - if [ $bitexact == 0 ] && [ $non_be_flag != 0 ]; then echo "Non-bitexact cases with non-BE tag encountered"; selftest_exit_code=$EXIT_CODE_NON_BE; fi

    ### run SBA pytest
    ### prepare pytest
    # create short test vectors
    - python3 tests/create_short_testvectors.py
    # rename test binaries back
    - mv IVAS_cod_test IVAS_cod
    - mv IVAS_dec_test IVAS_dec
    # create references
    - python3 -m pytest tests -v --update_ref 1 -m create_ref
    - python3 -m pytest tests -v --update_ref 1 -m create_ref_part2

    ### run pytest
    - exit_code=0
    - python3 ./scripts/ivas_pytests/self_test_b.py --encref IVAS_cod_ref --decref IVAS_dec_ref --encdut IVAS_cod_test --decdut IVAS_dec_test || exit_code=$?
    - python3 -m pytest tests -v --junit-xml=report-junit.xml || exit_code=$?
    - if [ $exit_code -eq 1 ] && [ $non_be_flag == 0 ]; then echo "pytest run had failures and non-BE flag not present"; exit $EXIT_CODE_FAIL; fi
    - zero_errors=$(cat report-junit.xml | grep -c 'errors="0"') || true
    - if [ $exit_code -eq 1 ] && [ $zero_errors == 1 ]; then echo "pytest run had failures, but no errors and non-BE flag present"; exit $EXIT_CODE_NON_BE; fi
    - if [ $exit_code -ne 0 ]; then echo "pytest run had errors"; exit $EXIT_CODE_FAIL; fi;
    # return exit code from selftest if everything went well with the pytest run
    - exit $selftest_exit_code
  allow_failure:
    exit_codes:
      - 123
@@ -474,9 +461,6 @@ codec-comparison-on-main-push:
    name: "main-push--sha-$CI_COMMIT_SHORT_SHA--stage-$CI_JOB_STAGE--results"
    when: always
    paths:
      - test_output.txt
      - scripts/test/logs/
      - scripts/ref/logs/
      - report-junit.xml
    expose_as: 'Results of comparison to previous merge commit'
    reports:
@@ -645,9 +629,10 @@ coverage-test-on-main-scheduled:
  script:
    - *print-common-info
    - make GCOV=1 -j
    - ./scripts/self_test.py --create -t 1
    - ./scripts/self_test.py --create -t 1 scripts/config/self_test_evs.prm
    - ./scripts/ivas_pytests/self_test_b.py --create_only --numprocesses 1 --encref IVAS_cod --decref IVAS_dec --encdut IVAS_cod --decdut IVAS_dec
    - python3 tests/create_short_testvectors.py
    - python3 -m pytest tests -v -n 0 --update_ref 1 -m create_ref --ref_encoder_path IVAS_cod --ref_decoder_path IVAS_dec
    - python3 -m pytest tests -v -n 0 --update_ref 1 -m create_ref_part2 --ref_encoder_path IVAS_cod --ref_decoder_path IVAS_dec
    - python3 -m pytest tests/test_param_file.py -v -n 0 --update_ref 1 -m create_ref --param_file scripts/config/self_test_evs.prm --ref_encoder_path IVAS_cod --ref_decoder_path IVAS_dec
    - lcov -c -d obj -o coverage.info
    - genhtml coverage.info -o coverage
  artifacts:
+7 −2
Original line number Diff line number Diff line
# pytest.ini
# note: per convention, this file is placed in the root directory of the repository
[pytest]
addopts = -ra --tb=short --basetemp=./tmp -v
addopts = -ra --tb=short --basetemp=./tmp -n auto
# Write captured system-out log messages to JUnit report.
junit_logging = system-out
# Do not capture log information for passing tests to JUnit report.
junit_log_passing_tests = False
junit_duration_report = call
junit_family = xunit1
log_file_level = DEBUG
log_format = %(asctime)s %(levelname)s %(message)s
+0 −273
Original line number Diff line number Diff line
#!/usr/bin/env python3

"""
   (C) 2022 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
   Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
   Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
   Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
   contributors to this repository. All Rights Reserved.

   This software is protected by copyright law and by international treaties.
   The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
   Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
   Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
   Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
   contributors to this repository retain full ownership rights in their respective contributions in
   the software. This notice grants no license of any kind, including but not limited to patent
   license, nor is any license granted by implication, estoppel or otherwise.

   Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
   contributions.

   This software is provided "AS IS", without any express or implied warranties. The software is in the
   development stage. It is intended exclusively for experts who have experience with such software and
   solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
   and fitness for a particular purpose are hereby disclaimed and excluded.

   Any dispute, controversy or claim arising under or in relation to providing this software shall be
   submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
   accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
   the United Nations Convention on Contracts on the International Sales of Goods.
"""

"""
Script to run the pytest tests.

Step 1: Set the stage for the pytest run.

Step 2: Run pytest.
"""

import os
import sys
import argparse
import subprocess
import platform
from pathlib import Path

sys.path.append('scripts/ivas_pytests/tests/')
from cut_pcm import cut_samples

BIN_EXT = ".exe" if platform.system() == "Windows" else ""
HERE = Path(__file__).parent.resolve()
DEFAULT_ENCODER_DUT = str(HERE.joinpath(f"../../IVAS_cod{BIN_EXT}").resolve())
DEFAULT_DECODER_DUT = str(HERE.joinpath(f"../../IVAS_dec{BIN_EXT}").resolve())
DEFAULT_ENCODER_REF = str(HERE.joinpath(f"../../IVAS_cod_ref{BIN_EXT}").resolve())
DEFAULT_DECODER_REF = str(HERE.joinpath(f"../../IVAS_dec_ref{BIN_EXT}").resolve())
CREND_UNITTEST_REF = str(HERE.joinpath(f"tests/unit_tests/crend/IVAS_crend_unit_test_ref{BIN_EXT}").resolve())
TEST_VECTOR_DIR = str(HERE.joinpath("../testv").resolve())
REFERENCE_DIR = str(HERE.joinpath("ref").resolve())
DUT_BASE_DIR = str(HERE.joinpath("dut").resolve())


def build_enc_and_dec(src_dir):
    """
    Build the encoder and decoder binaries.
    """
    if platform.system() == "Windows":
        olddir = os.getcwd()
        os.chdir(src_dir)
        os.chdir("Workspace_msvc")
        command = ["MSBuild.exe", "Workspace_msvc.sln", "/t:Clean", "/p:configuration=Release", "/p:Platform=Win32"]
        subprocess.run(command, check=True)
        command = ["MSBuild.exe", "Workspace_msvc.sln", "/property:configuration=Release", "/p:Platform=Win32"]
        subprocess.run(command, check=True)
        os.chdir(olddir)
    else:
        command = ["make", "-C", src_dir, "clean"]
        subprocess.run(command, check=True)
        command = ["make", "-C", src_dir]
        subprocess.run(command, check=True)


def build_crend_unittest(src_dir):
    """
    Build the crend unit test binary.
    """
    crend_dir = f"{src_dir}/scripts/ivas_pytests/tests/unit_tests/crend"
    if platform.system() == "Windows":
        olddir = os.getcwd()
        os.chdir(crend_dir)
        # command = ["MSBuild.exe", "ivas_crend_unit_test.sln", "/t:Clean", "/p:configuration=Release", "/p:Platform=Win32"]
        # subprocess.run(command, check=True)
        command = ["MSBuild.exe", "ivas_crend_unit_test.sln", "/property:configuration=Release", "/p:Platform=Win32"]
        subprocess.run(command, check=True)
        os.chdir(olddir)
    else:
        # command = ["make", "-C", src_dir, "clean"]
        # subprocess.run(command, check=True)
        command = ["make", "-C", src_dir, "IVAS_crend_unit_test"]
        subprocess.run(command, check=True)


def build_dut_binaries():
    """
    Build the DUT binaries.
    """
    print("Building the DUT binaries")
    dut_src_dir = str(HERE.joinpath("../..").resolve())
    build_enc_and_dec(dut_src_dir)
    build_crend_unittest(dut_src_dir)


def create_short_testvectors():
    """
    Create short (5sec) testvectors.
    """
    print("Creating short (5sec) testvectors")
    num_channels = "4" # currently only FOA
    cut_from = "0.0"
    cut_len = "5.0"
    for fs in ['48', '32', '16']:
        in_file = f"{TEST_VECTOR_DIR}/stvFOA{fs}c.pcm"
        cut_gain = "1.0"
        cut_file = f"{TEST_VECTOR_DIR}/stvFOA{fs}c_cut.pcm"
        cut_samples(in_file, cut_file, num_channels, fs + "000", cut_from, cut_len, cut_gain)
        cut_gain = "16.0"
        cut_file = f"{TEST_VECTOR_DIR}/stvFOA{fs}c_cut_{cut_gain}.pcm"
        cut_samples(in_file, cut_file, num_channels, fs + "000", cut_from, cut_len, cut_gain)


def main(argv):
    # check for python >= 3.7
    if sys.version_info[0] < 3 or sys.version_info[1] < 7:
        sys.exit("This script is written for Python >= 3.7. Found: " + platform.python_version())

    parser = argparse.ArgumentParser(formatter_class=argparse.RawTextHelpFormatter)
    parser.add_argument(
        "--create_only",
        action="store_true",
        default=False,
        help="Create references when needed, but don't run the tests"
    )
    parser.add_argument(
        "--numprocesses",
        action="store",
        default="auto",
        help="Number of processes to use in pytest (default: auto)",
    )
    parser.add_argument("--encref", help=f"REF encoder binary (default:{DEFAULT_ENCODER_REF})")
    parser.add_argument("--decref", help=f"REF decoder binary (default:{DEFAULT_DECODER_REF})")
    parser.add_argument("--encdut", help=f"DUT encoder binary (default:{DEFAULT_ENCODER_DUT})")
    parser.add_argument("--decdut", help=f"DUT decoder binary (default:{DEFAULT_DECODER_DUT})")

    args = parser.parse_args(argv[1:])

    # check for DUT binaries
    if args.encdut:
        encdut_path = os.path.realpath(args.encdut)
        if not os.path.exists(encdut_path):
            sys.exit(f"DUT encoder binary {encdut_path} does not exist.")
    else:
        encdut_path = DEFAULT_ENCODER_DUT
    if args.decdut:
        decdut_path = os.path.realpath(args.decdut)
        if not os.path.exists(decdut_path):
            sys.exit(f"DUT encoder binary {decdut_path} does not exist.")
    else:
        decdut_path = DEFAULT_DECODER_DUT
    if not os.path.exists(encdut_path) or not os.path.exists(decdut_path):
        build_dut_binaries()

    if not os.path.exists(REFERENCE_DIR):
        # check for REF binaries
        if args.encref:
            encref_path = os.path.realpath(args.encref)
            if not os.path.exists(encref_path):
                sys.exit(f"REF encoder binary {encref_path} does not exist.")
        else:
            encref_path = DEFAULT_ENCODER_REF
        if args.decref:
            decref_path = os.path.realpath(args.decref)
            if not os.path.exists(decref_path):
                sys.exit(f"REF encoder binary {decref_path} does not exist.")
        else:
            decref_path = DEFAULT_DECODER_REF
        if not os.path.exists(encref_path) or not os.path.exists(decref_path):
            sys.exit("Reference binaries do not exist.")

    # check for test vectors
    if not os.path.exists(TEST_VECTOR_DIR):
        sys.exit(f"Test vector directory {TEST_VECTOR_DIR} does not exist.")

    # check for references
    if os.path.exists(REFERENCE_DIR):
        print(f"Using existing references directory {REFERENCE_DIR}")
    else:
        # create references
        print(f"Creating references within the references directory {REFERENCE_DIR}")
        create_short_testvectors()
        if platform.system() == "Windows":
            base_cmd = ["pytest"]
        else:
            base_cmd = ["python3", "-m", "pytest"]
        base_cmd += [
            "scripts/ivas_pytests/tests",
            "-n",
            args.numprocesses,
            "--update_ref",
            "1",
            "-v",
            "--data_system_tests_path",
            TEST_VECTOR_DIR,
            "--reference_path",
            REFERENCE_DIR,
            "--dut_base_path",
            DUT_BASE_DIR,
            "--ref_encoder_path",
            encref_path,
            "--ref_decoder_path",
            decref_path,
            "--dut_encoder_path",
            encdut_path,
            "--dut_decoder_path",
            decdut_path,
        ]
        # work-around in unit tests via environment variable
        # TESTVECTOR_PATH_REL_GROUPB: to specify the test vector directory relative to ivas_pytests folder
        # TESTVECTOR_PATH_REL_TRUNK:  to specify the test vector directory relative to trunk
        my_env = os.environ.copy()
        my_env["TESTVECTOR_PATH_REL_GROUPB"] = "testv/"
        my_env["TESTVECTOR_PATH_REL_TRUNK"] = "/scripts/ivas_pytests/testv/"  # leading "/" is important
        my_env["CREND_UNIT_TEST_BIN"] = CREND_UNITTEST_REF
        print("pytest command line to be executed from project root folder:")
        print(" ".join(base_cmd + ["-m", "create_ref"]))
        subprocess.run(base_cmd + ["-m", "create_ref"], check=False, env=my_env)
        print("pytest command line to be executed from project root folder:")
        print(" ".join(base_cmd + ["-m", "create_ref_part2"]))
        subprocess.run(base_cmd + ["-m", "create_ref_part2"], check=False, env=my_env)

    if args.create_only:
        return

    # run pytest
    if platform.system() == "Windows":
        cmd = ["pytest"]
    else:
        cmd = ["python3", "-m", "pytest"]
    cmd += [
        "scripts/ivas_pytests/tests",
        "-n",
        args.numprocesses,
        "-v",
        "--data_system_tests_path",
        TEST_VECTOR_DIR,
        "--reference_path",
        REFERENCE_DIR,
        "--dut_base_path",
        DUT_BASE_DIR,
        "--dut_encoder_path",
        encdut_path,
        "--dut_decoder_path",
        decdut_path,
        "--junit-xml=report-junit.xml",
    ]
    # print pytest commandline
    print("pytest command line to be executed from project root folder:")
    print(" ".join(cmd))
    result = subprocess.run(cmd, check=False)
    return result.returncode


if __name__ == "__main__":
    sys.exit(main(sys.argv))
+0 −61

File deleted.

Preview size limit exceeded, changes collapsed.

Loading