Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cmake/FindPytest.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -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})
Expand Down
9 changes: 7 additions & 2 deletions cmake/PytestAddTests.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -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}
)
Expand All @@ -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.
Expand Down
11 changes: 11 additions & 0 deletions doc/release/release_notes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
8 changes: 4 additions & 4 deletions test/05-properties/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand All @@ -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(
Expand All @@ -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(
Expand All @@ -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
)
40 changes: 40 additions & 0 deletions test/07-working-directory/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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()