问题
If I want to write my own test.cpp that checks if another .cpp file is outputting the way I want it to output, is there anyway to do it without explicitly printing it?
In other words, is there anything such as
assert(output_of_file_being_tested, "this is the correct output");
where output_of_file_being_tested is something that's supposed to be "cout"ed.
回答1:
The solution is not to hard-code the output stream. Pass a reference to std::ostream
to your code somehow, and use std::stringstream
to collect the output in test environment.
For example, this is the content of your "another .cpp" file:
void toBeTested(std::ostream& output) {
output << "this is the correct output";
}
So in your production/release code you may pass std::cout
to the function:
void productionCode() {
toBeTested(std::cout);
}
while in the test environment you may collect the output to a sting stream and check it for correctness:
// test.cpp
#include <sstream>
#include <cassert>
void test() {
std::stringstream ss;
toBeTested(ss);
assert(ss.str() == "this is the correct output");
}
回答2:
In addition to Sergey
's great answer above, you may choose to have std::cout
as a default parameter.
So, if you have a code:
// Only need console output
using std::cout;
...
void toBeTested()
{
cout << "This is the correct output.";
}
And it is used (or may be frequently used in the future) in many places:
int main()
{
...
toBeTested();
...
toBeTested();
...
// And so on...
return 0;
}
In order to avoid breaking a lot of code and maintaining a simple interface,
you can convert the above function to:
using std::cout;
...
void toBeTested(std::ostream& cout = std::cout)
{
cout << "This is the correct output.";
}
And your main
does not need to be touched.
Note that cout
of the function now overshadows cout
of the global scope. Therefore, this cout
can be any output stream, and does not interfere with the global cout
.
And now you can test this as above!
#include <sstream>
#include <cassert>
...
void testMyFunctionDisplay()
{
// Arrange
std::ostringstream output_buffer;
// Act
toBeTested(output_buffer);
// Assert
assert(output_buffer.str() == "This is the correct output.");
}
However. it is not necessary to make every function in this way.
It is useful if we want to redirect that function's output to other output streams:
- Stringstreams: If you want to use the output somewhere, perhaps for testing the module, or for other purposes in the program.
- Files: If you want to maintain the output even after the program termination.
来源:https://stackoverflow.com/questions/40297782/c-unit-testing-check-output-is-correct