我們有幾個單元測試,我們希望作爲構建過程的一部分運行。CMake - 運行測試作爲構建過程的一部分,並將stdout輸出捕獲到文件中
爲了達到這個目的,我有一個助手腳本,它創建一個運行測試的自定義命令,如果成功,創建一個文件"test_name.passed"
。
然後我添加一個自定義目標"test_name.run"
,這取決於"test_name.passed"
。
這個想法是,如果"test_name.passed"
不存在或者比"test_name"
舊,則將運行自定義命令。
構建將繼續運行自定義命令,直到測試通過。一旦通過,後續構建將不會調用自定義命令,因此在不需要時將不會運行測試。正是
到目前爲止,所有的作品中描述
下面是腳本:
# create command which runs the test and creates a sentinel file if it passes
add_custom_command(
OUTPUT ${TEST_NAME}.passed
COMMAND $<TARGET_FILE:${TEST_NAME}>
COMMAND ${CMAKE_COMMAND} -E touch ${TEST_NAME}.passed
DEPENDS ${TEST_NAME}
)
# create test.run module which depends on test.passed
add_custom_target(${TEST_NAME}.run
ALL
DEPENDS ${TEST_NAME}.passed
)
問題 - 對stdout
問題噪聲是我們的測試中經常登錄一噸的信息stdout
,它使一個非常嘈雜的建設。
我想現在將stdout
捕獲到一個文件,並且只有在發生故障時才顯示測試輸出。
我的第一次嘗試是嘗試Bash shell腳本語法 - 將stdout
捕獲到文件中,當退出狀態爲錯誤時,將該文件捕獲。
add_custom_command(
OUTPUT ${TEST_NAME}.passed
COMMAND $<TARGET_FILE:${TEST_NAME}> > ${TEST_NAME}.output || cat ${TEST_NAME}.output
COMMAND ${CMAKE_COMMAND} -E touch ${TEST_NAME}.passed
DEPENDS ${TEST_NAME}
)
這不起作用,因爲即使試驗失敗我正在創建的前哨"test_name.passed"
文件,這意味着下一次我嘗試建立它認爲通過測試。
可能的子標準修復
通過與ctest
積分,我可以通過CTEST運行每個測試和使用命令行選項--output-on-failure
add_custom_command(
OUTPUT ${TEST_NAME}.passed
COMMAND ctest --build-config $<CONFIGURATION> --tests-regex ${TEST_NAME} --output-on-failure
COMMAND ${CMAKE_COMMAND} -E touch ${TEST_NAME}.passed
DEPENDS ${TEST_NAME}
)
與此有兩方面的問題。
- 它很大增加了構建時間。每個測試都必須通過一個單獨的ctest過程來執行,所有註冊的測試名稱都是針對正則表達式進行解析的,等等。隨着單個測試的數量的增加,我們有額外的時間大大增加。
- ctest默認輸出很多噪音。指定
--quiet
標誌抑制--output-on-failure
標誌,因此您可以輸出有噪聲或無輸出 - 無法僅獲得失敗。
問題
有沒有一種方法可以達到我想要什麼?
即:
- 手動運行測試(即:不通過CTEST)
- 捕獲輸出到文件
- 只有在指示失敗的測試退出狀態事件文件輸出。
- 如果測試退出狀態指示成功,觸摸一個哨兵文件。
一個跨平臺的方法的獎勵點,但如果它必須只有Linux,那就這樣吧。
爲什麼不使用ctest和cmake的集成? – fghj
@ user1034749 AFAIK ctest不會將測試作爲構建的一部分運行。這是一個單獨的目標'make test'。我以前使用ctest來運行每個測試('COMMAND ctest --build-config $ --tests-regex $ {TEST_NAME} --output-on-failure'),但通過ctest調用每個單元測試都會大大增加編譯時間 –
@ user1034749更新了我與ctest有關的問題,以及爲什麼我要尋找替代方法 –