diff --git a/cmake/FindPytest.cmake b/cmake/FindPytest.cmake index 480b2f5..d9bb693 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;EXTRA_ARGS" + "LIBRARY_PATH_PREPEND;PYTHON_PATH_PREPEND;ENVIRONMENT;PROPERTIES;DEPENDS;EXTRA_ARGS;DISCOVERY_EXTRA_ARGS" ) # Set platform-specific library path environment variable. @@ -133,6 +133,7 @@ if (Pytest_FOUND AND NOT TARGET Pytest::Pytest) -D "TEST_PROPERTIES=${_PROPERTIES}" -D "CTEST_FILE=${_tests_file}" -D "EXTRA_ARGS=${_EXTRA_ARGS}" + -D "DISCOVERY_EXTRA_ARGS=${_DISCOVERY_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 c13a7e1..095b3d0 100644 --- a/cmake/PytestAddTests.cmake +++ b/cmake/PytestAddTests.cmake @@ -27,6 +27,10 @@ if(CMAKE_SCRIPT_MODE_FILE) endforeach() # Handle EXTRA_ARGS for individual tests + if(BUNDLE_TESTS) + list(PREPEND EXTRA_ARGS ${DISCOVERY_EXTRA_ARGS}) + endif() + set(EXTRA_ARGS_WRAPPED) foreach(arg IN LISTS EXTRA_ARGS) list(APPEND EXTRA_ARGS_WRAPPED "[==[${arg}]==]") @@ -69,7 +73,7 @@ if(CMAKE_SCRIPT_MODE_FILE) execute_process( COMMAND "${PYTEST_EXECUTABLE}" --collect-only -q - --rootdir=${WORKING_DIRECTORY} . + --rootdir=${WORKING_DIRECTORY} ${DISCOVERY_EXTRA_ARGS} . OUTPUT_VARIABLE _output_lines ERROR_VARIABLE _output_lines OUTPUT_STRIP_TRAILING_WHITESPACE diff --git a/doc/api_reference.rst b/doc/api_reference.rst index d35bbb4..712e8ea 100644 --- a/doc/api_reference.rst +++ b/doc/api_reference.rst @@ -24,6 +24,7 @@ API Reference [STRIP_PARAM_BRACKETS] [BUNDLE_TESTS] [EXTRA_ARGS arg1 arg2...] + [DISCOVERY_EXTRA_ARGS arg1 arg2...] ) The options are: @@ -200,6 +201,26 @@ API Reference `Pytest Command-Line Flags `_ + * ``DISCOVERY_EXTRA_ARGS`` + + List of extra arguments to pass on the :term:`Pytest` command line for + the test discovery:: + + pytest_discover_tests( + ... + DISCOVERY_EXTRA_ARGS "-k=expression" + ) + + .. seealso:: + + `Pytest Command-Line Flags + `_ + + .. warning:: + + This option may affect test discovery. Some arguments can change + output format and break the test collection logic. Use with caution! + .. note:: This function works similarly to the `gtest_discover_tests diff --git a/doc/release/release_notes.rst b/doc/release/release_notes.rst index 568f025..f453aed 100644 --- a/doc/release/release_notes.rst +++ b/doc/release/release_notes.rst @@ -4,6 +4,15 @@ Release Notes ************* +.. release:: Upcoming + + .. change:: changed + + Added ``DISCOVERY_EXTRA_ARGS`` option to the + :func:`pytest_discover_tests` function, allowing custom arguments to be + passed to the :term:`Pytest` command during test collection. + Thanks :github_user:`AmeyaVS`! + .. release:: 0.12.0 :date: 2025-02-09 diff --git a/test/06-extra-args/CMakeLists.txt b/test/06-extra-args/CMakeLists.txt index e1bac5e..7c9b662 100644 --- a/test/06-extra-args/CMakeLists.txt +++ b/test/06-extra-args/CMakeLists.txt @@ -9,5 +9,23 @@ enable_testing() pytest_discover_tests( TestExtraArgs EXTRA_ARGS "--capture=no" "--cmdopt=demo" - DEPENDS test_extra_args.py +) + +pytest_discover_tests( + TestDiscoveryExtraArgs.IgnoreCustomArgs + EXTRA_ARGS "--capture=no" + DISCOVERY_EXTRA_ARGS "--ignore=custom_args" +) + +pytest_discover_tests( + TestDiscoveryExtraArgs.OnlyCustomArgs + EXTRA_ARGS "--cmdopt=demo" + DISCOVERY_EXTRA_ARGS "-k=custom" +) + +pytest_discover_tests( + TestDiscoveryExtraArgs.OnlyCustomArgsBundled + EXTRA_ARGS "--cmdopt=demo" + DISCOVERY_EXTRA_ARGS "-k=custom" + BUNDLE_TESTS ) diff --git a/test/06-extra-args/conftest.py b/test/06-extra-args/conftest.py index 2d52afa..4be0ed0 100644 --- a/test/06-extra-args/conftest.py +++ b/test/06-extra-args/conftest.py @@ -1,10 +1,4 @@ -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/custom_args/test_custom_args.py b/test/06-extra-args/custom_args/test_custom_args.py new file mode 100644 index 0000000..c52502b --- /dev/null +++ b/test/06-extra-args/custom_args/test_custom_args.py @@ -0,0 +1,7 @@ +import pytest + +def test_requires_cmdopt(request): + """Fails unless '--cmdopt=' is passed to pytest.""" + if request.config.getoption("--cmdopt") is None: + pytest.fail("Test requires '--cmdopt' to properly execute the test.") + assert True diff --git a/test/06-extra-args/test_extra_args.py b/test/06-extra-args/test_args.py similarity index 50% rename from test/06-extra-args/test_extra_args.py rename to test/06-extra-args/test_args.py index fe62a0c..52e1ec9 100644 --- a/test/06-extra-args/test_extra_args.py +++ b/test/06-extra-args/test_args.py @@ -5,12 +5,3 @@ def test_requires_no_capture(request): 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