infrastructure: keep QTest's output visible when ctest runs on Windows (#9751)

#### Brief overview of PR changes/additions

- Appends `QT_ASSUME_STDERR_HAS_CONSOLE=1` to the `ENVIRONMENT` test
property of every registered test - 95 of 95 confirmed with `ctest
--show-only=json-v1` - leaving each test's existing `ASAN_OPTIONS`,
`QT_QPA_PLATFORM` and `ENVIRONMENT_MODIFICATION` untouched.
- One `cmake_language(DEFER CALL)` per directory that registers tests,
rather than the variable copy-pasted into a dozen strings, so a test
added later cannot miss it wherever in the file it lands.
- Drops the 8 `QT_FORCE_STDERR_LOGGING` entries from the four workflows.
`shouldLogToStderr()` is `forceStderrLogging() ||
stderrHasConsoleAttached()`, so the test property now covers what CI was
setting by hand, and every one of those steps runs nothing but `ctest`.

#### Motivation for adding to Mudlet

Qt on Windows diverts QTest's output to `OutputDebugString` unless it
believes stderr has a console attached, and an MSYS2 shell gives it
none, so a failing test reported an exit code with no `FAIL!` lines, no
compared values and no totals. Setting it as a test property fixes local
runs and CI from one place instead of two.

#### Other info (issues closed, discussion etc)

**Test case:** full Linux `ctest` suite 95/95 pass; `ctest
--show-only=json-v1` shows all 95 tests carrying the variable with no
other property changed; `ctest -V` shows it in the test process
environment. The Windows behaviour itself is not reproducible on Linux -
it rests on the reporter's 219 vs 12233 byte A/B and on
`QPlainTestLogger::outputMessage`, which only calls `OutputDebugStringA`
when `!QtPrivate::shouldLogToStderr()`.

Closes #9747

Assisted-by: Claude:claude-opus-5
This commit is contained in:
Vadim Peretokin 2026-08-10 22:18:08 +02:00 committed by GitHub
parent 15e52faef9
commit 8901b59d84
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 16 additions and 13 deletions

View file

@ -417,7 +417,6 @@ jobs:
run: ctest --output-on-failure
env:
QT_QPA_PLATFORM: offscreen
QT_FORCE_STDERR_LOGGING: 1
# This runner has Qt's FFmpeg backend and can decode, so TMediaLoopTest must
# demonstrate every media behaviour rather than skip any of them. Without a floor
# somewhere, a lost codec or a changed default backend would turn the whole file
@ -428,15 +427,11 @@ jobs:
if: runner.os == 'macOS'
working-directory: '${{runner.workspace}}/b/ninja'
run: ctest --output-on-failure
env:
QT_FORCE_STDERR_LOGGING: 1
# the full ctest run above already covers every functional-labelled test
- name: Run QTest
if: matrix.run_tests != 'true'
run: ctest --test-dir ${{runner.workspace}}/b/ninja -L functional --output-on-failure
env:
QT_FORCE_STDERR_LOGGING: 1
- name: add ssh-agent for release uploads
if: (runner.os == 'Linux' || runner.os == 'macOS') && matrix.deploy == 'deploy' && startsWith(github.ref, 'refs/tags/Mudlet-')

View file

@ -139,7 +139,6 @@ jobs:
ctest --test-dir $GITHUB_WORKSPACE/build-$MSYSTEM/test --output-on-failure
env:
QT_FORCE_STDERR_LOGGING: 1
# This runner has Qt's FFmpeg backend and can decode, so TMediaLoopTest must
# demonstrate every media behaviour rather than skip any of them. Without a floor
# somewhere, a lost codec or a changed default backend would turn the whole file

View file

@ -115,8 +115,6 @@ jobs:
export LUA_CPATH
ctest --test-dir $GITHUB_WORKSPACE/build-$MSYSTEM/test --output-on-failure
env:
QT_FORCE_STDERR_LOGGING: 1
- name: (Windows) Run Lua tests
timeout-minutes: 2

View file

@ -403,21 +403,16 @@ jobs:
run: ctest --output-on-failure
env:
QT_QPA_PLATFORM: offscreen
QT_FORCE_STDERR_LOGGING: 1
- name: (macOS) Run C++ tests
if: runner.os == 'macOS'
working-directory: '${{runner.workspace}}/b/ninja'
run: ctest --output-on-failure
env:
QT_FORCE_STDERR_LOGGING: 1
# the full ctest run above already covers every functional-labelled test
- name: Run QTest
if: matrix.run_tests != 'true'
run: ctest --test-dir ${{runner.workspace}}/b/ninja -L functional --output-on-failure
env:
QT_FORCE_STDERR_LOGGING: 1
- name: add ssh-agent for release uploads
if: (runner.os == 'Linux' || runner.os == 'macOS') && matrix.deploy == 'deploy' && startsWith(github.ref, 'refs/tags/Mudlet-')

View file

@ -9,6 +9,19 @@ endif()
find_package(Qt6 6.8.2 REQUIRED COMPONENTS Test Network Widgets)
# On Windows Qt diverts QTest's stdout to OutputDebugString unless it believes
# stderr has a console attached, which an MSYS2 shell or a CI runner does not give
# it, so a failing test reports an exit code and nothing else (#9747). Deferred so
# that tests registered further down the file are covered too; TESTS does not
# descend into subdirectories, hence the second call in functional_tests.
function(restore_windows_test_output)
get_property(registeredTests DIRECTORY PROPERTY TESTS)
foreach(testName ${registeredTests})
set_property(TEST ${testName} APPEND PROPERTY ENVIRONMENT "QT_ASSUME_STDERR_HAS_CONSOLE=1")
endforeach()
endfunction()
cmake_language(DEFER CALL restore_windows_test_output)
set(UNIT_TESTS
TEntityResolverTest
TEntityHandlerTest

View file

@ -2,6 +2,9 @@ if(NOT WIN32)
include(${CMAKE_SOURCE_DIR}/src/cmake/EnableSanitizers.cmake)
endif()
# Defined in the parent test/CMakeLists.txt; TESTS is per-directory, so call it here too.
cmake_language(DEFER CALL restore_windows_test_output)
set(FUNCTIONAL_TEST_SOURCES
ConfigDirOverrideTest.cpp
TelnetTextDisplayedTest.cpp