I am learning CTest
over the following code:
// A program that echoes lines on stdin back.
#include <iostream>
#include <string>
int main()
{
std::string line;
do
{
std::getline(std::cin, line);
std::cout << line << std::endl;
}while(! line.empty());
}
Now I need to perform a system test.
How can my tests.cpp
refer to standard input and output of the compiled binary? The test should obviously invoke it, produce some input and verify the output mirrors it. What's the CTest way of doing that?
My current CMakeLists.txt
stanza, though probably completely irrelevant:
enable_testing()
add_executable(tests tests.cpp)
add_test(NAME Tests
COMMAND tests)
Conclusion after reading the linked question(also closed).
You can see if this function works in your case.
FUNCTION(interactive_command_line_test test_executable input_arguments expected_output
expected_error)
EXECUTE_PROCESS(
COMMAND
bash -c "echo \"${input_arguments}\" | ${CMAKE_BINARY_DIR}/${test_executable}"
RESULT_VARIABLE result
OUTPUT_VARIABLE output
ERROR_VARIABLE err_output
COMMAND_ECHO STDOUT
ECHO_OUTPUT_VARIABLE)
# Find if ${expected_output} is in ${output}; if cannot be found, found =
# "-1"
STRING(FIND ${output} ${expected_output} found)
MESSAGE(found ${found})
IF((NOT (${result} STREQUAL "0")) OR (${found} STREQUAL "-1"))
MESSAGE(
FATAL_ERROR
"Test failed with return value '${result}'; output '${output}'; expected output '${expected_output}' and found '${found}'";
)
ENDIF()
ENDFUNCTION()
This is how you could use it, in a test.cmake
:
INTERACTIVE_COMMAND_LINE_TEST(gcd "5 20" "GCD of 5 and 20 is 5" "")
How it works:
~/.../${CMAKE_BINARY_DIR}/gcd
using bash.OUTPUT VARIABLE output
sets the output to stdout
to the cmake
variable output
.${output}
is, cmake
tries to find the ${expected_output}
substring within ${output}
.cmake
finds it, the cmake
variable ${found}
will be set to a non-zero integer, else it will be set to "-1"
.IF((NOT (${result} STREQUAL "0")) OR (${found} STREQUAL "-1"))
MESSAGE(
FATAL_ERROR
"Test failed with return value '${result}'; output '${output}'; expected output '${expected_output}' and found '${found}'";
)
is self-explanatory.
Note:
expected_error
is unused.ctest
, e.g. is --test-dir
passed in as an argument, etc.