Lets say your program takes a set of strings and does something on them. Lets call it process_strings
which needs to be tested. You want to pass different sets of strings for different test cases, say {"abc", "efg", "hij"}
, {"thin", "run", "win"}
, {"cat", "rat", "mat"}
, etc. In future you want to add more such test cases without altering your original function process_strings
. Then the right way to go about this problem is to modify the (driver) program such that you don't have to recompile for different test cases added/removed. An example might be:
#include <fstream>
#include <iostream>
#include <string>
#include <memory>
#include <sstream>
#include <vector>
#include <iterator>
// tested function
void process_strings(const std::vector<std::string>& params)
{
for (auto iter = params.cbegin(); iter < params.cend(); ++iter)
std::cout << *iter << '\t';
}
// driver program
int main(int argc, char *argv[])
{
if (argc < 2)
{
std::cout << "Insufficient data" << std::endl;
return -1;
}
std::ifstream test_file(argv[1]); // pass test cases file as an argument
std::string test_case;
while (std::getline(test_file, test_case))
{
// each line is a test case
std::istringstream iss(test_case);
std::vector<std::string> params;
// break parameters separated by ' ' blankspace
copy(std::istream_iterator<std::string>(iss),
std::istream_iterator<std::string>(),
std::back_inserter(params));
// if there're valid parameters, then pass it to the tested function
if (!params.empty())
{
process_strings(params);
std::cout << std::endl;
}
}
}
Example of a test cases file, tests.txt
:
abc efg
cat rat mat
animal man
The output produced for C:\> simple.exe tests.txt
:
abc efg
cat rat mat
animal man
If you've arguments which contains space i.e. if space cannot be used as delimiter, then see this post on how to extract the arguments from the line.
Thus we've separated input data from code. Every time the test cases change, you needn't recompile the program. Just change the input, run it by the already compiled program and verify the output. This saves a lot of development time, and in some sense the basis of data-driven programming.