diff --git a/cmake/FindPytest.cmake b/cmake/FindPytest.cmake index 341d697..480b2f5 100644 --- a/cmake/FindPytest.cmake +++ b/cmake/FindPytest.cmake @@ -58,7 +58,7 @@ if (Pytest_FOUND AND NOT TARGET Pytest::Pytest) cmake_parse_arguments( PARSE_ARGV 1 "" "STRIP_PARAM_BRACKETS;INCLUDE_FILE_PATH;BUNDLE_TESTS" "WORKING_DIRECTORY;TRIM_FROM_NAME;TRIM_FROM_FULL_NAME" - "LIBRARY_PATH_PREPEND;PYTHON_PATH_PREPEND;ENVIRONMENT;PROPERTIES;DEPENDS" + "LIBRARY_PATH_PREPEND;PYTHON_PATH_PREPEND;ENVIRONMENT;PROPERTIES;DEPENDS;EXTRA_ARGS" ) # Set platform-specific library path environment variable. @@ -132,6 +132,7 @@ if (Pytest_FOUND AND NOT TARGET Pytest::Pytest) -D "ENVIRONMENT=${_ENVIRONMENT}" -D "TEST_PROPERTIES=${_PROPERTIES}" -D "CTEST_FILE=${_tests_file}" + -D "EXTRA_ARGS=${_EXTRA_ARGS}" -P "${CMAKE_CURRENT_FUNCTION_LIST_DIR}/PytestAddTests.cmake") # Create a custom target to run the tests. diff --git a/cmake/PytestAddTests.cmake b/cmake/PytestAddTests.cmake index 15250cb..c13a7e1 100644 --- a/cmake/PytestAddTests.cmake +++ b/cmake/PytestAddTests.cmake @@ -26,10 +26,17 @@ if(CMAKE_SCRIPT_MODE_FILE) list(APPEND ENCODED_ENVIRONMENT "${env}") endforeach() + # Handle EXTRA_ARGS for individual tests + set(EXTRA_ARGS_WRAPPED) + foreach(arg IN LISTS EXTRA_ARGS) + list(APPEND EXTRA_ARGS_WRAPPED "[==[${arg}]==]") + endforeach() + list(JOIN EXTRA_ARGS_WRAPPED " " EXTRA_ARGS_STR) + # Macro to create individual tests with optional test properties. macro(create_test NAME IDENTIFIER) string(APPEND _content - "add_test([==[${NAME}]==] \"${PYTEST_EXECUTABLE}\" [==[${IDENTIFIER}]==])\n" + "add_test([==[${NAME}]==] \"${PYTEST_EXECUTABLE}\" [==[${IDENTIFIER}]==] ${EXTRA_ARGS_STR} )\n" ) # Prepare the properties for the test, including the environment settings. diff --git a/test/06-extra-args/CMakeLists.txt b/test/06-extra-args/CMakeLists.txt new file mode 100644 index 0000000..e1bac5e --- /dev/null +++ b/test/06-extra-args/CMakeLists.txt @@ -0,0 +1,13 @@ +cmake_minimum_required(VERSION 3.20) + +project(TestExtraArgs) + +find_package(Pytest REQUIRED) + +enable_testing() + +pytest_discover_tests( + TestExtraArgs + EXTRA_ARGS "--capture=no" "--cmdopt=demo" + DEPENDS test_extra_args.py +) diff --git a/test/06-extra-args/conftest.py b/test/06-extra-args/conftest.py new file mode 100644 index 0000000..2d52afa --- /dev/null +++ b/test/06-extra-args/conftest.py @@ -0,0 +1,10 @@ +import pytest + +def pytest_addoption(parser): + parser.addoption( + "--cmdopt", action="store", help="custom options" + ) + +@pytest.fixture +def cmdopt(request): + return request.config.getoption("--cmdopt") diff --git a/test/06-extra-args/test_extra_args.py b/test/06-extra-args/test_extra_args.py new file mode 100644 index 0000000..fe62a0c --- /dev/null +++ b/test/06-extra-args/test_extra_args.py @@ -0,0 +1,16 @@ +import pytest + +def test_requires_no_capture(request): + """Fails unless '--capture=no' is passed to pytest.""" + if "--capture=no" not in request.config.invocation_params.args: + pytest.fail("Test requires '--capture=no' to properly display output.") + assert True + + +def test_requires_args(cmdopt): + """Fails unless '--cmdopt=' is passed to pytest.""" + if cmdopt != None: + print(f"Option Value: cmdopt: {cmdopt}") + else: + pytest.fail("Test requires '--cmdopt=' to properly execute the test.") + pass diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 4732ec5..6eef290 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -52,3 +52,13 @@ ExternalProject_Add( -C Release -VV -R TestProperties.Validate ) + +ExternalProject_Add( + TestExtraArgs + SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/06-extra-args + BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/_deps/06-extra-args + BUILD_COMMAND ${CMAKE_COMMAND} --build + INSTALL_COMMAND "" + TEST_COMMAND ${CMAKE_CTEST_COMMAND} + -C Release -VV +)