Home > itblogs > Эффективные юнит тесты. Часть II.

Эффективные юнит тесты. Часть II.

August 9th, 2006

Реализация алгоритма, описанного в первой части. В принципе исходный код говорит сам за себя. Остановлюсь на некоторых деталях.

Каждый элементарный тест описывается структурой:

struct Test
{
    const char* name;
    unsigned type;
    unsigned mask;
    bool positive;
    bool (*tearUp)();
    void (*tearDown)();
};
  • name – задает имя теста. Имя желательно выбирать коротким, поскольку полное имя комбинации тестов включает в себя имена всех элементарных тестов;
  • type – одна из констант TEST_XXX или их комбинация, определяющая тип теста. В примере тип каждого теста уникален. На самом деле это необязательное требование;
  • mask – комбинация констант TEST_XXX перечисляющая все типы тестов, совместимые в данным;
  • positive – ожидаемый результат теста;
  • tearUp – функция, выполняющая инициализацию и собственно тест;
  • teadDown – функция, ответственная за корректное завершение теста.

Константы TEST_XXX представляют собой битовую маску, где каждому биту соотвествует свой тип теста. В процессе выбора очередного теста список выбранных тестов сопоставляется с маской совместимых тестов:

if (
    ((mask & i->type) == 0) &&
    ((mask & ~(i->type | i->mask)) == 0))
{

Тест будет выбран только если тест еще не был выбран (первое условие), а также совместим с уже выбранными тестами. (второе условие).

В примере тесты групируются по категориям (или «вариантам»). Основной признак для такой группировки – в одну категорию попадают тесты, которые не могут входить ни в одну тестовую комбинацию одновременно.

Comments are closed.