From a7f8332efd377eace63084cec839f7a5252d3be1 Mon Sep 17 00:00:00 2001 From: "Thiago M. de C. Marques" Date: Fri, 13 Nov 2026 13:29:51 -0300 Subject: [PATCH 1/2] Move check_test_property.cmake to test utils Allow other tests to check the properties of discovered tests. --- test/05-properties/CMakeLists.txt | 8 ++++---- test/{05-properties => utils}/check_test_property.cmake | 0 2 files changed, 4 insertions(+), 4 deletions(-) rename test/{05-properties => utils}/check_test_property.cmake (100%) diff --git a/test/05-properties/CMakeLists.txt b/test/05-properties/CMakeLists.txt index 9ffd7c1..2a49327 100644 --- a/test/05-properties/CMakeLists.txt +++ b/test/05-properties/CMakeLists.txt @@ -16,7 +16,7 @@ add_test(NAME TestProperties.Validate.Timeout -D "TEST_PREFIX=TestProperties.Timeout" -D "TEST_PROPERTY=TIMEOUT" -D "EXPECTED_VALUE=120.0" - -P ${CMAKE_CURRENT_LIST_DIR}/check_test_property.cmake + -P ${CMAKE_CURRENT_LIST_DIR}/../utils/check_test_property.cmake ) pytest_discover_tests( @@ -29,7 +29,7 @@ add_test(NAME TestProperties.Validate.Labels -D "TEST_PREFIX=TestProperties.Labels" -D "TEST_PROPERTY=LABELS" -D "EXPECTED_VALUE=[ \"bar\", \"foo\" ]" - -P ${CMAKE_CURRENT_LIST_DIR}/check_test_property.cmake + -P ${CMAKE_CURRENT_LIST_DIR}/../utils/check_test_property.cmake ) pytest_discover_tests( @@ -42,7 +42,7 @@ add_test(NAME TestProperties.Validate.Disabled -D "TEST_PREFIX=TestProperties.Disabled" -D "TEST_PROPERTY=DISABLED" -D "EXPECTED_VALUE=ON" - -P ${CMAKE_CURRENT_LIST_DIR}/check_test_property.cmake + -P ${CMAKE_CURRENT_LIST_DIR}/../utils/check_test_property.cmake ) pytest_discover_tests( @@ -55,5 +55,5 @@ add_test(NAME TestProperties.Validate.SkipReturnCode -D "TEST_PREFIX=TestProperties.SkipReturnCode" -D "TEST_PROPERTY=SKIP_RETURN_CODE" -D "EXPECTED_VALUE=77" - -P ${CMAKE_CURRENT_LIST_DIR}/check_test_property.cmake + -P ${CMAKE_CURRENT_LIST_DIR}/../utils/check_test_property.cmake ) diff --git a/test/05-properties/check_test_property.cmake b/test/utils/check_test_property.cmake similarity index 100% rename from test/05-properties/check_test_property.cmake rename to test/utils/check_test_property.cmake From 6f9e990fac72dd3a221acc219eebbbff5f85a49b Mon Sep 17 00:00:00 2001 From: "Thiago M. de C. Marques" Date: Fri, 13 Nov 2026 13:29:51 -0300 Subject: [PATCH 2/2] Keep symbolic links in the working directory of tests The working directory was resolved at configuration time, so the tests ran from the real path even when a symbolic link was given. A build tree configured through a link could not run its tests once the link targeted another location. The working directory is now only made absolute. Test collection still resolves it, as Pytest resolves symbolic links in the invocation directory but not in 'rootdir' (pytest-dev/pytest#12291). --- cmake/FindPytest.cmake | 2 +- cmake/PytestAddTests.cmake | 9 ++++-- doc/release/release_notes.rst | 11 +++++++ test/07-working-directory/CMakeLists.txt | 40 ++++++++++++++++++++++++ 4 files changed, 59 insertions(+), 3 deletions(-) diff --git a/cmake/FindPytest.cmake b/cmake/FindPytest.cmake index c40b723..74249d8 100644 --- a/cmake/FindPytest.cmake +++ b/cmake/FindPytest.cmake @@ -166,7 +166,7 @@ if (Pytest_FOUND AND NOT TARGET Pytest::Pytest) set(_WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) endif() - get_filename_component(_WORKING_DIRECTORY "${_WORKING_DIRECTORY}" REALPATH) + get_filename_component(_WORKING_DIRECTORY "${_WORKING_DIRECTORY}" ABSOLUTE) # Override option by environment variable if available. if (DEFINED ENV{BUNDLE_PYTHON_TESTS}) diff --git a/cmake/PytestAddTests.cmake b/cmake/PytestAddTests.cmake index 9b2487f..0e4c79f 100644 --- a/cmake/PytestAddTests.cmake +++ b/cmake/PytestAddTests.cmake @@ -103,9 +103,14 @@ if(CMAKE_SCRIPT_MODE_FILE) set(ENV{PYTEST_CMAKE_DLL_DIRECTORIES} "${DLL_DIRECTORIES}") endif() + # Collect from the resolved path, as Pytest resolves symbolic links in + # the invocation directory but not in 'rootdir'. + # https://github.com/pytest-dev/pytest/issues/12291 + get_filename_component(_collect_directory "${WORKING_DIRECTORY}" REALPATH) + set(_command "${PYTEST_EXECUTABLE}" --collect-only -q - "--rootdir=${WORKING_DIRECTORY}" + "--rootdir=${_collect_directory}" ${DLL_PLUGIN_ARGS} ${DISCOVERY_EXTRA_ARGS} ) @@ -120,7 +125,7 @@ if(CMAKE_SCRIPT_MODE_FILE) OUTPUT_VARIABLE _output_lines ERROR_VARIABLE _output_lines OUTPUT_STRIP_TRAILING_WHITESPACE - WORKING_DIRECTORY ${WORKING_DIRECTORY} + WORKING_DIRECTORY ${_collect_directory} ) # Check for errors during test collection. diff --git a/doc/release/release_notes.rst b/doc/release/release_notes.rst index 65eeece..ed14cb3 100644 --- a/doc/release/release_notes.rst +++ b/doc/release/release_notes.rst @@ -4,6 +4,17 @@ Release Notes ************* +.. release:: Upcoming + + .. change:: fixed + + Updated the :func:`pytest_discover_tests` function to keep symbolic + links in the ``WORKING_DIRECTORY`` value, so that tests run from the + path given instead of the resolved one. Previously, a build tree + configured through a symbolic link could not run its tests once the + link targeted another location. Test collection still uses the + resolved path, as introduced in version 0.5.2. + .. release:: 1.6.1 :date: 2026-09-28 diff --git a/test/07-working-directory/CMakeLists.txt b/test/07-working-directory/CMakeLists.txt index f52b775..aac1465 100644 --- a/test/07-working-directory/CMakeLists.txt +++ b/test/07-working-directory/CMakeLists.txt @@ -16,3 +16,43 @@ pytest_discover_tests( WORKING_DIRECTORY subdir BUNDLE_TESTS ) + +# Link to this directory, using a junction on Windows as it does not require +# elevated privileges. +set(_link "${CMAKE_CURRENT_BINARY_DIR}/link") +if (NOT EXISTS "${_link}") + if (WIN32) + file(TO_NATIVE_PATH "${_link}" _native_link) + file(TO_NATIVE_PATH "${CMAKE_CURRENT_SOURCE_DIR}" _native_target) + execute_process( + COMMAND cmd /c mklink /J "${_native_link}" "${_native_target}" + OUTPUT_QUIET + COMMAND_ERROR_IS_FATAL ANY + ) + else() + file(CREATE_LINK "${CMAKE_CURRENT_SOURCE_DIR}" "${_link}" SYMBOLIC) + endif() +endif() + +# Tests should run from the linked path. Collection must still succeed, without +# loading the conftest file from the parent of the resolved path. +pytest_discover_tests( + TestWorkingDirectory.Link.Simple + WORKING_DIRECTORY "${_link}/subdir" +) + +pytest_discover_tests( + TestWorkingDirectory.Link.Bundled + WORKING_DIRECTORY "${_link}/subdir" + BUNDLE_TESTS +) + +foreach (_variant IN ITEMS Simple Bundled) + add_test(NAME TestWorkingDirectory.Validate.Link.${_variant} + COMMAND ${CMAKE_COMMAND} + -D "TEST_PREFIX=TestWorkingDirectory.Link.${_variant}" + -D "TEST_PROPERTY=WORKING_DIRECTORY" + -D "EXPECTED_VALUE=${_link}/subdir" + -P ${CMAKE_CURRENT_LIST_DIR}/../utils/check_test_property.cmake + ) +endforeach()