I am trying to write a text processing console application in C++ and I have met Windows API for the first time. But before defining a grammar or using the existing bison/flex or boost tools I want to realize a TDD approach and write all tests and interfaces (except here I have put a dummy test having hard time with even launching the .exe from test code).
My design is following:
- Unit tests from native test project call a CreateProcess()
function from Windows API that I have put into CreateProc()
macro. Example of this macro (I have slightly modified it) is taken from MSDN. Idea of this macro is execute my console application but from unit test to simulate user input after. Here is the code:
#define MYEXE L"my_Console_Application_Path.exe"
#ifdef MYEXE
PROCESS_INFORMATION CreateProc() {
STARTUPINFO si = { 0 };
PROCESS_INFORMATION pi = { 0 };
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
if (CreateProcess
(
MYEXE,
NULL,
NULL,
NULL,
NULL, //,
CREATE_NEW_CONSOLE,
NULL,
NULL,
&si,
&pi
)
)
{
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
return pi;
}
else
{
std::cout << "Unable to execute.";
return pi;
}
}
#endif
Test that runs and "uses" my console application is defined:
TEST_CLASS(UnitTest1)
{
public:
TEST_METHOD(Should_Open_Console)
{
PROCESS_INFORMATION processInfo = CreateProc();
Assert::IsTrue(processInfo.dwProcessId); // check if process id is not zero
}
main
function of console application looks like this:
int main()
{
std::cout << "test that function is running" << std::endl;
std::string myline = "";
std::getline(std::cin, myline);
return 0;
}
Basically my CreateProc()
sucessfully launches the executable. However I want tests to simulate user input that main
is listening to with getline(...)
. After I am going to parse this sequence with some parser.
How could I simulate this input within current console process? Of course I will be grateful if you can advise me some concrete instruments (is this SendInput()
solution the best way to simulate input?) and the most important - how it should be done in terms of design? Ideally I see a string defined in a Unit test and passed through CreateProcess()
as argument to main and the same string is somehow read from console after. Kind of this:
TEST_CLASS(UnitTest1)
{
public:
// parsing Hola as Hello
TEST_METHOD(Should_Return_Hello_If_Input_Equals_to_Hola)
{
CreateProc("Hola");
Assert::AreEqual(Console.readline() = "Hello"); // dummy code
}
Am I right? If yes, how could I actually do it? (if you can correct code snippets it would be great)