Выделенная память в нескольких модульных тестах cmocka - PullRequest
0 голосов
/ 24 апреля 2018

Я пытаюсь протестировать некоторый исходный код с помощью cmocka.В основном (соответствующий) исходный код выглядит аналогично Source.c.

В модульном тесте каждая функция вызывается отдельно.При тестировании функции Add () эта функция в конечном итоге вызовет util_malloc () (эта функция обычно проверяет размер 0 перед malloc), который оборачивается модульным тестом.В завернутой функции __ wrap_util_malloc () в Wrappers.c сначала проверяется ожидаемый размер, после чего malloc используется для выделения памяти.

Далее Удалить() проверяется функция, при которой ранее выделенная память освобождается.


При запуске теста cmocka возвращается со следующими ошибками:

<failure><![CDATA[Blocks allocated... project_path/wrappers.c:46:  note: block 00341e58 allocated here ERROR: Add_Test leaked 1 block(s) ]]></failure>

и

<failure><![CDATA[EXCEPTION_ACCESS_VIOLATION occurred at 004060af.
To debug in Visual Studio... [...]
]]></failure>

На данный момент я добавил Удалить() вызов в конце функции Add_Test () Add () в начале Remove_Test () ).Кажется, это решает проблему.Исходя из этого, следует освободить всю выделенную память в каждом отдельном модульном тесте.

Теперь мои вопросы:

  1. Можно ли использовать выделенную память в тестировании нескольких модулей?
  2. Как лучше всего решить эту проблему?

Source.c:

static ST_SOME_STRUCT GlobStruct;

void Add()
{
    GlobStruct = util_malloc(sizeof(ST_SOME_STRUCT));
}

void Remove()
{
    util_free(&GlobStruct);    
}

void DoStuff()
{
    //Do stuff using the global structure GlobStruct
}

Unit_test.c:

int main( int argc, char **argv )
{
const struct CMUnitTest Test[] =
   {
      cmocka_unit_test(Add_Test),      
      cmocka_unit_test(Remove_Test),
   };
   cmocka_set_message_output( CM_OUTPUT_XML );
   return cmocka_run_group_tests( Test, NULL, NULL );
}

static void Add_Test (void** state)
{
   expect_value(__wrap_util_malloc, size, sizeof(ST_SOME_STRUCT ));
   Add();
}

static void Remove_Test (void** state)
{
   expect_not_value(__wrap_util_free, memory, cast_ptr_to_largest_integral_type(NULL));
   Remove();
}

Wrappers.c:

void *__wrap_util_malloc(int size)
{
    check_expected(size);
    return malloc(size);
}

void __wrap_util_free(void *memory)
{
    check_expected_ptr(memory);
    free(memory);
}

1 Ответ

0 голосов
/ 24 апреля 2018

При запуске тестов с использованием cmocka_run_group_tests, cmocka будет по-прежнему запускать отдельные функции настройки или демонтажа для каждого теста вместе со своими внутренними функциями, которые проверяют, не забыли ли вы освободить блоки (отсюда и сообщение Add_Test leaked 1 block(s)).После каждого теста cmocka также освобождает все блоки, выделенные внутри этого теста, прежде чем запускать следующий.

Общий подход состоит в том, что каждый из ваших тестов должен выполнять очистку всего, что выделено в этом отдельном тесте.Если вы хотите инициализировать общее состояние в начале группового теста, задайте функции настройки / разрыва группы для инициализации общего состояния (которое будет передаваться каждому модульному тесту в качестве параметра), или используйте функции настройки / разрыва теста, которые должны вызываться докаждый тест.

Как всегда, плохая идея (и затрудняет тестирование) иметь глобальные общие переменные.Ваши функции Add и Remove (и все другие, имеющие отношение к этому объекту) должны принимать указатель на структуру, содержащую данные.

...