├── .gitignore ├── .travis.yml ├── CHANGELOG.rst ├── CMakeLists.txt ├── README.md ├── cmake └── pytest.cmake ├── package.xml ├── scripts └── ros_pytest_runner ├── setup.py ├── src └── ros_pytest │ ├── __init__.py │ └── tests │ └── test_ros_pytest.py └── tests └── libtest.test /.gitignore: -------------------------------------------------------------------------------- 1 | # Python 2 | *.pyc 3 | 4 | # Linux 5 | .directory 6 | core 7 | !core/ 8 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: required 2 | dist: trusty 3 | language: generic 4 | notifications: 5 | email: 6 | on_success: change 7 | on_failure: always 8 | env: 9 | global: 10 | - ROS_REPO=ros 11 | matrix: 12 | - ROS_DISTRO=kinetic UPSTREAM_WORKSPACE=debian 13 | - ROS_DISTRO=melodic UPSTREAM_WORKSPACE=debian 14 | matrix: 15 | allow_failures: 16 | - env: ROS_DISTRO=kinetic UPSTREAM_WORKSPACE=debian 17 | - env: ROS_DISTRO=melodic UPSTREAM_WORKSPACE=debian 18 | install: 19 | - git clone https://github.com/ros-industrial/industrial_ci.git .ci_config 20 | script: 21 | - .ci_config/travis.sh 22 | # - ./travis.sh # Enable this when you have a package-local script 23 | -------------------------------------------------------------------------------- /CHANGELOG.rst: -------------------------------------------------------------------------------- 1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 2 | Changelog for package ros_pytest 3 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 4 | 5 | 0.2.1 (2021-05-03) 6 | ------------------ 7 | * Merge pull request `#9 `_ from jspricke/missing_dependencies 8 | Add dependency on python-pytest-cov 9 | * Contributors: Alexander Rössler, Jochen Sprickerhof 10 | 11 | 0.2.0 (2020-08-12) 12 | ------------------ 13 | * Merge pull request `#7 `_ from machinekoder/fix-folders 14 | * Bugfix for pytest folder tests 15 | * Merge pull request `#5 `_ from sfalexrog/python3_compat 16 | * Merge pull request `#6 `_ from PilzDE/feature/add_coverage 17 | * Remove comment 18 | * Added reasoning and integrate if CATKIN_TEST_COVERAGE is set 19 | * Create subfolder for .coverage for each test 20 | * Add flag to pytest execution 21 | * Add coverage for pytest 22 | * package.xml: Use conditional dependencies 23 | * CMakeLists: Use catkin_install_python for script installation 24 | * Contributors: Alexander Gutenkunst, Alexander Rössler, Alexey Rogachevskiy, hslusarek 25 | 26 | 0.1.2 (2018-11-15) 27 | ------------------ 28 | * Added add_pytests cmake macro 29 | * enable passing of additional commands 30 | * Contributors: Alexander Rössler, Markus Grimm 31 | 32 | 0.1.1 (2018-10-07) 33 | ------------------ 34 | * Release for melodic 35 | 36 | 0.1.0 37 | ----- 38 | This is the first release the ros_pytest package. 39 | 40 | It contains everything necessary to run pytests with rostest. 41 | 42 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8.3) 2 | project(ros_pytest) 3 | 4 | ## Compile as C++11, supported in ROS Kinetic and newer 5 | # add_compile_options(-std=c++11) 6 | 7 | ## Find catkin macros and libraries 8 | ## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz) 9 | ## is used, also find other catkin packages 10 | find_package(catkin REQUIRED COMPONENTS 11 | rospy 12 | ) 13 | 14 | ## System dependencies are found with CMake's conventions 15 | # find_package(Boost REQUIRED COMPONENTS system) 16 | 17 | 18 | ## Uncomment this if the package has a setup.py. This macro ensures 19 | ## modules and global scripts declared therein get installed 20 | ## See http://ros.org/doc/api/catkin/html/user_guide/setup_dot_py.html 21 | catkin_python_setup() 22 | 23 | ################################################ 24 | ## Declare ROS messages, services and actions ## 25 | ################################################ 26 | 27 | ## To declare and build messages, services or actions from within this 28 | ## package, follow these steps: 29 | ## * Let MSG_DEP_SET be the set of packages whose message types you use in 30 | ## your messages/services/actions (e.g. std_msgs, actionlib_msgs, ...). 31 | ## * In the file package.xml: 32 | ## * add a build_depend tag for "message_generation" 33 | ## * add a build_depend and a run_depend tag for each package in MSG_DEP_SET 34 | ## * If MSG_DEP_SET isn't empty the following dependency has been pulled in 35 | ## but can be declared for certainty nonetheless: 36 | ## * add a run_depend tag for "message_runtime" 37 | ## * In this file (CMakeLists.txt): 38 | ## * add "message_generation" and every package in MSG_DEP_SET to 39 | ## find_package(catkin REQUIRED COMPONENTS ...) 40 | ## * add "message_runtime" and every package in MSG_DEP_SET to 41 | ## catkin_package(CATKIN_DEPENDS ...) 42 | ## * uncomment the add_*_files sections below as needed 43 | ## and list every .msg/.srv/.action file to be processed 44 | ## * uncomment the generate_messages entry below 45 | ## * add every package in MSG_DEP_SET to generate_messages(DEPENDENCIES ...) 46 | 47 | ## Generate messages in the 'msg' folder 48 | # add_message_files( 49 | # FILES 50 | # Message1.msg 51 | # Message2.msg 52 | # ) 53 | 54 | ## Generate services in the 'srv' folder 55 | # add_service_files( 56 | # FILES 57 | # Service1.srv 58 | # Service2.srv 59 | # ) 60 | 61 | ## Generate actions in the 'action' folder 62 | # add_action_files( 63 | # FILES 64 | # Action1.action 65 | # Action2.action 66 | # ) 67 | 68 | ## Generate added messages and services with any dependencies listed here 69 | # generate_messages( 70 | # DEPENDENCIES 71 | # std_msgs # Or other packages containing msgs 72 | # ) 73 | 74 | ################################################ 75 | ## Declare ROS dynamic reconfigure parameters ## 76 | ################################################ 77 | 78 | ## To declare and build dynamic reconfigure parameters within this 79 | ## package, follow these steps: 80 | ## * In the file package.xml: 81 | ## * add a build_depend and a run_depend tag for "dynamic_reconfigure" 82 | ## * In this file (CMakeLists.txt): 83 | ## * add "dynamic_reconfigure" to 84 | ## find_package(catkin REQUIRED COMPONENTS ...) 85 | ## * uncomment the "generate_dynamic_reconfigure_options" section below 86 | ## and list every .cfg file to be processed 87 | 88 | ## Generate dynamic reconfigure parameters in the 'cfg' folder 89 | # generate_dynamic_reconfigure_options( 90 | # cfg/DynReconf1.cfg 91 | # cfg/DynReconf2.cfg 92 | # ) 93 | 94 | ################################### 95 | ## catkin specific configuration ## 96 | ################################### 97 | ## The catkin_package macro generates cmake config files for your package 98 | ## Declare things to be passed to dependent projects 99 | ## INCLUDE_DIRS: uncomment this if your package contains header files 100 | ## LIBRARIES: libraries you create in this project that dependent projects also need 101 | ## CATKIN_DEPENDS: catkin_packages dependent projects also need 102 | ## DEPENDS: system dependencies of this project that dependent projects also need 103 | catkin_package( 104 | # INCLUDE_DIRS include 105 | # LIBRARIES ros_pytest 106 | # CATKIN_DEPENDS pyros python-pytest 107 | # DEPENDS system_lib 108 | CFG_EXTRAS pytest.cmake 109 | ) 110 | 111 | ########### 112 | ## Build ## 113 | ########### 114 | 115 | ## Specify additional locations of header files 116 | ## Your package locations should be listed before other locations 117 | include_directories( 118 | # include 119 | ${catkin_INCLUDE_DIRS} 120 | ) 121 | 122 | ## Declare a C++ library 123 | # add_library(${PROJECT_NAME} 124 | # src/${PROJECT_NAME}/ros_pytest.cpp 125 | # ) 126 | 127 | ## Add cmake target dependencies of the library 128 | ## as an example, code may need to be generated before libraries 129 | ## either from message generation or dynamic reconfigure 130 | # add_dependencies(${PROJECT_NAME} ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS}) 131 | 132 | ## Declare a C++ executable 133 | ## With catkin_make all packages are built within a single CMake context 134 | ## The recommended prefix ensures that target names across packages don't collide 135 | # add_executable(${PROJECT_NAME}_node src/ros_pytest_node.cpp) 136 | 137 | ## Rename C++ executable without prefix 138 | ## The above recommended prefix causes long target names, the following renames the 139 | ## target back to the shorter version for ease of user use 140 | ## e.g. "rosrun someones_pkg node" instead of "rosrun someones_pkg someones_pkg_node" 141 | # set_target_properties(${PROJECT_NAME}_node PROPERTIES OUTPUT_NAME node PREFIX "") 142 | 143 | ## Add cmake target dependencies of the executable 144 | ## same as for the library above 145 | # add_dependencies(${PROJECT_NAME}_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS}) 146 | 147 | ## Specify libraries to link a library or executable target against 148 | # target_link_libraries(${PROJECT_NAME}_node 149 | # ${catkin_LIBRARIES} 150 | # ) 151 | 152 | ############# 153 | ## Install ## 154 | ############# 155 | 156 | # all install targets should use catkin DESTINATION variables 157 | # See http://ros.org/doc/api/catkin/html/adv_user_guide/variables.html 158 | 159 | ## Mark executable scripts (Python etc.) for installation 160 | ## in contrast to setup.py, you can choose the destination 161 | catkin_install_python(PROGRAMS 162 | scripts/ros_pytest_runner 163 | DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} 164 | ) 165 | 166 | ## Mark executables and/or libraries for installation 167 | # install(TARGETS ${PROJECT_NAME} ${PROJECT_NAME}_node 168 | # ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} 169 | # LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} 170 | # RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} 171 | # ) 172 | 173 | ## Mark cpp header files for installation 174 | # install(DIRECTORY include/${PROJECT_NAME}/ 175 | # DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION} 176 | # FILES_MATCHING PATTERN "*.h" 177 | # PATTERN ".svn" EXCLUDE 178 | # ) 179 | 180 | ## Mark other files for installation (e.g. launch and bag files, etc.) 181 | # install(FILES 182 | # # myfile1 183 | # # myfile2 184 | # DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION} 185 | # ) 186 | 187 | ############# 188 | ## Testing ## 189 | ############# 190 | 191 | ## Add gtest based cpp test target and link libraries 192 | # catkin_add_gtest(${PROJECT_NAME}-test test/test_ros_pytest.cpp) 193 | # if(TARGET ${PROJECT_NAME}-test) 194 | # target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME}) 195 | # endif() 196 | 197 | ## Add folders to be run by python nosetests 198 | # catkin_add_nosetests(test) 199 | 200 | 201 | if(CATKIN_ENABLE_TESTING) 202 | find_package(rostest REQUIRED) 203 | add_rostest(tests/libtest.test) 204 | endif() 205 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Description 2 | 3 | The package provides a wrapper for pytest to be using conjunction with ROS. 4 | 5 | To use the `ros_pytest_runner` use the following stanza in your `.test` launch file: 6 | 7 | ```xml 8 | 9 | 10 | 11 | 12 | ``` 13 | 14 | Make sure to pass your test path as parameter `test_module` to the runner. 15 | 16 | A more elaborate description for why I created this ROS package can be found on [my blog](https://machinekoder.com/testing-ros-powered-robots-pytest/). 17 | 18 | ## Run 19 | 20 | To run the unit tests use following command inside your ROS package `catkin run_tests --this`. 21 | 22 | Then view the test results with: `catkin_test_results` 23 | -------------------------------------------------------------------------------- /cmake/pytest.cmake: -------------------------------------------------------------------------------- 1 | _generate_function_if_testing_is_disabled("add_pytests") 2 | 3 | # 4 | # Add Python py.test. 5 | # 6 | # Pytest collects tests from the directory ``dir`` automatically. 7 | # 8 | # .. note:: The test can be executed by calling ``py.test`` 9 | # directly or using: 10 | # `` make run_tests_${PROJECT_NAME}_pytests_${dir}`` 11 | # (where slashes in the ``dir`` are replaced with periods) 12 | # 13 | # :param path: a relative or absolute directory to search for 14 | # pytests in or a relative or absolute file containing tests 15 | # :type path: string 16 | # :param DEPENDENCIES: the targets which must be built before executing 17 | # the test 18 | # :type DEPENDENCIES: list of strings 19 | # :param OPTIONS: additional arguments to pass to pytest 20 | # :type OPTIONS: list of strings 21 | # :param WORKING_DIRECTORY: the working directory when executing the 22 | # tests (this option can only be used when the ``path`` argument is a 23 | # file but not when it is a directory) 24 | # :type WORKING_DIRECTORY: string 25 | # :param COVERAGE_MODULES: Explicit declaration of the python module for which 26 | # a coverage report is generated. If emtpy, the module named after the 27 | # `PROJECT_NAME` is used for reporting. 28 | # :type COVERAGE_MODULES: List of strings. 29 | # 30 | # @public 31 | # 32 | function(add_pytests path) 33 | _warn_if_skip_testing("add_pytests") 34 | 35 | if(NOT PYTESTS) 36 | message(STATUS "skipping pytests(${path}) in project '${PROJECT_NAME}'") 37 | return() 38 | endif() 39 | 40 | cmake_parse_arguments( 41 | _pytest 42 | "" # Flag-like arguments 43 | "WORKING_DIRECTORY" # One value arguments 44 | "OPTIONS;DEPENDENCIES;COVERAGE_MODULES" # Multi value arguments 45 | ${ARGN} 46 | ) 47 | 48 | # check that the directory exists 49 | set(_path_name _path_name-NOTFOUND) 50 | if(IS_ABSOLUTE ${path}) 51 | set(_path_name ${path}) 52 | else() 53 | find_file(_path_name ${path} 54 | PATHS ${CMAKE_CURRENT_SOURCE_DIR} 55 | NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH) 56 | if(NOT _path_name) 57 | message(FATAL_ERROR "Can't find pytests path '${path}'") 58 | endif() 59 | endif() 60 | 61 | 62 | # strip PROJECT_SOURCE_DIR and PROJECT_BINARY_DIR prefix from output_file_name 63 | set(output_file_name ${path}) 64 | _strip_path_prefix(output_file_name "${output_file_name}" "${PROJECT_SOURCE_DIR}") 65 | _strip_path_prefix(output_file_name "${output_file_name}" "${PROJECT_BINARY_DIR}") 66 | if("${output_file_name}" STREQUAL "") 67 | set(output_file_name ".") 68 | endif() 69 | string(REPLACE "/" "." output_file_name ${output_file_name}) 70 | string(REPLACE ":" "." output_file_name ${output_file_name}) 71 | 72 | set(output_path ${CATKIN_TEST_RESULTS_DIR}/${PROJECT_NAME}) 73 | # make --junit-xml argument an absolute path 74 | get_filename_component(output_path "${output_path}" ABSOLUTE) 75 | set(cmd "${CMAKE_COMMAND} -E make_directory ${output_path}") 76 | 77 | # check if coverage reports are being requested 78 | if("$ENV{CATKIN_TEST_COVERAGE}" STREQUAL "1") 79 | if(NOT _pytest_COVERAGE_MODULES) # Empty -> default to PROJECT_NAME 80 | list(APPEND _pytest_COVERAGE_MODULES ${PROJECT_NAME}) 81 | endif() 82 | 83 | set(_covarg "") 84 | foreach(cov_module IN ITEMS ${_pytest_COVERAGE_MODULES}) 85 | set(_covarg "${_covarg} --cov=${cov_module}") 86 | endforeach() 87 | 88 | set(_covarg " ${_covarg} --cov-append") 89 | endif() 90 | 91 | # Process list of options to a string 92 | string (REPLACE ";" " " _pytest_OPTIONS "${_pytest_OPTIONS}") 93 | 94 | set(cmd ${cmd} "${PYTESTS} ${_path_name} ${_pytest_OPTIONS} --junit-xml=${output_path}/pytests-${output_file_name}.xml${_covarg}") 95 | 96 | # check if coverage reports are being requested 97 | if("$ENV{CATKIN_TEST_COVERAGE}" STREQUAL "1") 98 | 99 | # A few quick words on the following lines: 100 | # If the coverage is measured using pytest it will create a .coverage file within 101 | # the active WORKING_DIRECTORY. This does not work if the tests run in parallel even with the --cov-append set. 102 | # As a solution the following lines create a directory for every test execution. 103 | # After the test run the .coverage file is copied into the ${PROJECT_BINARY_DIR} 104 | # to be collected by e.g. by https://github.com/mikeferguson/code_coverage 105 | 106 | set(coverage_dir "${output_path}${output_file_name}_coverageDIR") 107 | set(cmd ${cmd} "cp ${coverage_dir}/.coverage ${PROJECT_BINARY_DIR}/.coverage.${output_file_name}") 108 | 109 | # Add target for creating the coverage directory 110 | add_custom_target( 111 | create_coverage_dir_${output_file_name} "${CMAKE_COMMAND}" "-E" "make_directory" ${coverage_dir} 112 | ) 113 | 114 | # Now depending on the coverage directory to be created 115 | set(_pytest_DEPENDENCIES ${_pytest_DEPENDENCIES} create_coverage_dir_${output_file_name}) 116 | 117 | set(_pytest_WORKING_DIRECTORY ${coverage_dir}) 118 | endif() 119 | 120 | catkin_run_tests_target("pytests" ${output_file_name} "pytests-${output_file_name}.xml" COMMAND ${cmd} DEPENDENCIES ${_pytest_DEPENDENCIES} WORKING_DIRECTORY ${_pytest_WORKING_DIRECTORY}) 121 | 122 | endfunction() 123 | 124 | find_program(PYTESTS NAMES 125 | "py.test${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}" 126 | "py.test-${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}" 127 | "py.test${PYTHON_VERSION_MAJOR}" 128 | "py.test-${PYTHON_VERSION_MAJOR}" 129 | "py.test" 130 | "pytest${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}" 131 | "pytest-${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}" 132 | "pytest${PYTHON_VERSION_MAJOR}" 133 | "pytest-${PYTHON_VERSION_MAJOR}" 134 | "pytest") 135 | if(PYTESTS) 136 | message(STATUS "Using Python pytest: ${PYTESTS}") 137 | else() 138 | if("${PYTHON_VERSION_MAJOR}" STREQUAL "3") 139 | message(STATUS "pytests not found, Python tests can not be run (try installing package 'python3-pytest')") 140 | else() 141 | message(STATUS "pytests not found, Python tests can not be run (try installing package 'python-pytest')") 142 | endif() 143 | endif() 144 | -------------------------------------------------------------------------------- /package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | ros_pytest 4 | 0.2.1 5 | The ros_pytest package 6 | 7 | 8 | 9 | 10 | Alexander Rössler 11 | 12 | 13 | 14 | 15 | 16 | MIT 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | catkin 52 | python-setuptools 53 | python3-setuptools 54 | rospy 55 | python-pytest 56 | python3-pytest 57 | python-pytest-cov 58 | python3-pytest-cov 59 | rostest 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /scripts/ros_pytest_runner: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # coding=utf-8 3 | import sys 4 | from ros_pytest import run_pytest 5 | 6 | 7 | if __name__ == '__main__': 8 | sys.exit(run_pytest(sys.argv)) 9 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | # ! DO NOT MANUALLY INVOKE THIS setup.py, USE CATKIN INSTEAD 2 | 3 | from setuptools import setup 4 | from catkin_pkg.python_setup import generate_distutils_setup 5 | 6 | # fetch values from package.xml 7 | setup_args = generate_distutils_setup( 8 | packages=['ros_pytest'], 9 | package_dir={'': 'src'}, 10 | ) 11 | 12 | setup(**setup_args) 13 | -------------------------------------------------------------------------------- /src/ros_pytest/__init__.py: -------------------------------------------------------------------------------- 1 | # coding=utf-8 2 | import os 3 | from distutils.version import LooseVersion 4 | import pytest 5 | import rospy 6 | 7 | 8 | def get_output_file(argv): 9 | for arg in argv: 10 | if arg.startswith('--gtest_output'): 11 | return arg.split('=xml:')[1] 12 | 13 | raise RuntimeError('No output file has been passed') 14 | 15 | 16 | def get_additional_args(argv): 17 | args = [] 18 | for arg in argv[1:]: 19 | if arg.startswith('__') or arg.startswith('--gtest_output'): 20 | continue 21 | if arg in ['-t', '--text']: 22 | arg = '-s' # pytest alias for --capture=no 23 | args.append(arg) 24 | return args 25 | 26 | 27 | def create_cache_dir_args(version, output_file): 28 | # disable cache for Pytest < 3.2 29 | if LooseVersion("3.5.0") > LooseVersion(version): 30 | cache_dir_arg = '-p no:cacheprovider' 31 | else: 32 | root_dir = os.path.dirname(output_file) 33 | cache_dir_arg = '--rootdir={}'.format(root_dir) 34 | return cache_dir_arg.split(' ') 35 | 36 | 37 | def run_pytest(argv): 38 | output_file = get_output_file(argv) 39 | additional_args = get_additional_args(argv) 40 | test_module = rospy.get_param('test_module') 41 | module_path = os.path.realpath(test_module) 42 | cache_dir_args = create_cache_dir_args(pytest.__version__, output_file) 43 | 44 | return pytest.main( 45 | [module_path, '--junitxml={}'.format(output_file)] 46 | + cache_dir_args 47 | + additional_args 48 | ) 49 | -------------------------------------------------------------------------------- /src/ros_pytest/tests/test_ros_pytest.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import pytest 3 | 4 | import ros_pytest 5 | 6 | 7 | def test_output_file_is_correctly_extracted_from_argv(): 8 | output = ros_pytest.get_output_file(['runner.py', '--gtest_output=xml:~/junit_output.xml']) 9 | 10 | assert output == '~/junit_output.xml' 11 | 12 | 13 | def test_additional_args_are_correctly_extracted_from_argv(): 14 | output = ros_pytest.get_additional_args([ 15 | 'runner.py', '--gtest_output=xml:~/junit_output.xml', 16 | '--ignore=some_tests', '__name:=test_lib', 17 | ]) 18 | 19 | assert output == ['--ignore=some_tests'] 20 | 21 | 22 | def test_not_passing_output_file_throws_runtime_error(): 23 | with pytest.raises(RuntimeError): 24 | ros_pytest.get_output_file(['main.py', '--file', 'random.txt']) 25 | 26 | 27 | def test_caching_is_disabled_for_older_pytest_versions(): 28 | args = ros_pytest.create_cache_dir_args("3.0.1", "/tmp/output_file.xml") 29 | 30 | assert args == ['-p', 'no:cacheprovider'] 31 | 32 | 33 | def test_rootdir_is_set_for_newer_pytest_versions(): 34 | args = ros_pytest.create_cache_dir_args("3.5.0", "/tmp/output_file.xml") 35 | 36 | assert args == ['--rootdir=/tmp'] 37 | -------------------------------------------------------------------------------- /tests/libtest.test: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | --------------------------------------------------------------------------------