Как выполнить модульное тестирование функций c с участием ввода-вывода?

Я сталкиваюсь с проблемами при написании модульных тестов для функций C, которые включают операцию ввода-вывода. Например, ниже приведен код, который я написал для получения входной строки от пользователя из консоли. Я не знаю, как автоматизировать тестирование пользовательского ввода с помощью функции getchar().

char * GetStringFromConsole()
{

    char *strToReturn = NULL;
    int len = 128;

    strToReturn = (char*)malloc(len);
    if (strToReturn) 
    {
        int ch;
        char *ptr  = strToReturn;
        int counter = 0;
        for (; ;) 
        {
            ch = getchar();
            counter++;

            if (counter == len)
            {
                strToReturn = realloc(strToReturn, len*=2 );
                ptr = strToReturn + counter-1;
            }

            if ((ch != EOF) && (ch != '\n') && (counter < len))
            {
                *ptr++ = ch;
            }
            else 
            {
                break;
            }

        }
        *ptr = '\0';
    }
    return strToReturn;
}   

person ramkumarhn    schedule 25.12.2012    source источник
comment
Вы можете создать сценарий оболочки для запуска вашей программы и сравнения ее вывода с ожидаемым содержимым.   -  person Basile Starynkevitch    schedule 25.12.2012


Ответы (1)


Макет getchar:

  1. Использование препроцессора, например. в вашем тестовом файле.

    #define getchar mock_getchar
    #include "GetStringFromConsole.h"
    ...
    const char* mock_getchar_data_ptr;
    char mock_getchar()
    {
        return *mock_getchar_data_ptr++;
    }
    ...
    // in test function
    mock_getchar_data_ptr = "hello!\n";
    YourAssertEquals("hello", GetStringFromConsole());
    
  2. Заменить символ для компоновщика (сложнее, на мой взгляд), например. определите свой собственный getchar где-нибудь в исходных файлах .c вместо ссылки на stdlib (например, msvcrt в Windows)

  3. Изменить тестируемую функцию, чтобы она принимала функцию, возвращающую char, лучший выбор (ИМХО) — никаких конфликтов с stdlib. И настройте тест, передав что-то вроде mock_getchar из точки 1 в тестовом коде.

    typedef char (*getchartype)();
    char * GetStringFromConsole(getchartype mygetchar)
    {
        ...
        c  = mygetchar()
    

Для точек 1 и 2 я бы предложил использовать вашу собственную функцию вместо getchar (например, mygetchar) - таким образом вы могли бы имитировать/заменять ее, не сталкиваясь с конфликтами со стандартными включениями. /библиотеки.

person kerim    schedule 28.12.2012
comment
Инфраструктура модульного тестирования cmocka поддерживает фиктивные объекты и показывает, как переопределить исходную функцию с помощью фиктивных функций. Нажмите «Подробнее» на cmocka.org. - person asn; 20.12.2013