настройка unittest ++ - PullRequest
       22

настройка unittest ++

1 голос
/ 27 августа 2011

Я спрашиваю об этом с надеждой, что кто-то был на моем месте и у него есть идеиПопытка не изобретать велосипед, так сказать.

Я использую UnitTest ++: http://unittest -cpp.sourceforge.net / UnitTest ++. Html

У меня уже есть довольно много тестов, ивсе они выполняются каждый раз, когда я запускаю тестовую сборку, что, конечно, следует ожидать.Я даже определил свой собственный класс TestReporter, который предоставляет мне немного больше информации о каждом тесте, чем по умолчанию - он печатает время, которое потребовалось для каждого теста в конце, а также имеет цветовые коды начала и окончания тестатак что мне легче ориентироваться в результатах теста.

Но я дошел до того, что огромное количество тестов сбрасывает столько вывода, что буфер моей консоли даже не содержит результатов первых нескольких тестов, и я устал от измененияэта настройка.Поэтому я хотел бы иметь возможность указать в качестве необязательных аргументов для запуска теста сборку тестов, которые я хотел бы запустить, и пропустить остальные.

Код для UnitTest ++ довольно прост, и я допускаю, что, возможно, мог бы это выяснить, если бы посмотрел на него еще немного, но наверняка кто-нибудь уже это понял?Я пытаюсь найти способ связать мой argv [] с Test :: GetTestList ().Я хотел бы отфильтровать список тестов с помощью аргументов cmdline и запустить только эти тесты.

Хм.Похоже, это просто связанный список.Я полагаю, я могу просто изуродовать его ... O (m * n) поиск, m = общее количество тестов, n = указанные тесты.Что ж.Я продолжаю отвечать на свои вопросы.Моды: я опубликую ответ с реализацией моего решения.Надеюсь, это сэкономит кому-то двадцать минут.

Редактировать: Похоже, я действительно должен использовать вещь Предиката:

template <class Predicate>
int RunTestsIf(TestList const& list, char const* suiteName, 
               const Predicate& predicate, int maxTestTimeInMs) const
{
    Test* curTest = list.GetHead();

    while (curTest != 0)
    {
        if (IsTestInSuite(curTest,suiteName) && predicate(curTest))
        {
            RunTest(m_result, curTest, maxTestTimeInMs);
        }

        curTest = curTest->next;
    }

    return Finish();
}   

Таким образом, я могу просто использовать RunTestsIf().

редактировать: думаю, я понял это.Ух ты, первый шаг в программировании шаблонов.

1 Ответ

0 голосов
/ 27 августа 2011

Вот мое решение:

namespace UnitTest {
    class ListFilter {
        char **list;
        int n;
    public:
        ListFilter(char **list_, int count) {
            list = list_; n = count;
        }
        bool operator()(const Test* const t) const {
            for (int i=0;i<n;++i) {
                std::string dot_cpp_appended = std::string(list[i]) + ".cpp";
                if (!strcasecmp(t->m_details.testName, list[i]) ||
                        !strcasecmp(t->m_details.suiteName, list[i]) ||
                        !strcasecmp(t->m_details.filename, list[i]) ||
                        !strcasecmp(t->m_details.filename, dot_cpp_appended.c_str())) {
                    // erring on the side of matching more tests
                    return true;
                }
            }
            return false;
        }
    };

    int RunTheseTests(char ** list, int n) {
        TestReporterStdout reporter;
        TestRunner runner(reporter);
        return runner.RunTestsIf(Test::GetTestList(), NULL, ListFilter(list,n), 0);
    }
}

int main(int argc, char *argv[]) {
    if (argc == 1) {
        UnitTest::RunAllTests();
    } else {
        UnitTest::RunTheseTests(argv+1, argc-1); // skip the program's name itself.
    }
}

Единственное, что меня немного беспокоит, так это то, что нет никакого чистого способа проверить, соответствует ли какой-либо конкретный тестовый сопоставитель чему-либо.

...