Я пытаюсь написать консольное приложение для обработки текста на C ++, и я впервые встретился с Windows API. Но прежде чем определить грамматику или использовать существующие инструменты bison / flex или boost, я хочу реализовать подход TDD и написать все тесты и интерфейсы (за исключением того, что я поставил фиктивный тест, испытывающий затруднения даже с запуском .exe из тестового кода). ,
Мой дизайн следующий:
— Модульные тесты из родного тестового проекта вызывают CreateProcess()
функция из Windows API, которую я положил в CreateProc()
макро. Пример этого макроса (я немного его модифицировал) взят из MSDN. Идея этого макроса состоит в том, чтобы выполнить мое консольное приложение, но из модульного теста для имитации ввода пользователя после. Вот код:
#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_CLASS(UnitTest1)
{
public:
TEST_METHOD(Should_Open_Console)
{
PROCESS_INFORMATION processInfo = CreateProc();
Assert::IsTrue(processInfo.dwProcessId); // check if process id is not zero
}
main
Функция консольного приложения выглядит так:
int main()
{
std::cout << "test that function is running" << std::endl;
std::string myline = "";
std::getline(std::cin, myline);
return 0;
}
В основном мой CreateProc()
успешно запускает исполняемый файл Однако я хочу, чтобы тесты имитировали пользовательский ввод, который main
слушает с getline(...)
, После того, как я собираюсь проанализировать эту последовательность с некоторым парсером.
Как я могу имитировать этот вход в текущий процесс консоли? Конечно, я буду благодарен, если вы можете посоветовать мне некоторые конкретные инструменты (это этот SendInput()
решение лучший способ симулировать ввод?) и самый важный — как это должно быть сделано с точки зрения дизайна? В идеале я вижу строку, определенную в модульном тесте и пройденную через CreateProcess()
в качестве аргумента для главной и той же строки каким-то образом читается из консоли после. Вид этого:
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
}
Я прав? Если да, то как я могу это сделать? (если вы можете исправить фрагменты кода, это было бы здорово)
Задача ещё не решена.
Других решений пока нет …