|
Что это такоеОднажды захотелось мне попробовать использовать один из основных принципов экстремального программирования - "Пиши тесты раньше программы", скачал, значит, CppUnit (аналог JUnit). Попробовал все скомпилировать под Visual C++ - вроде бы все прошло без проблем. Ну, думаю, ладно, теперь должно все быть хорошо и под Visual C++ 7.0 (все-таки в 6-ке ошибок побольше будет). Однако получился облом - куча ошибок при линковке самих библиотек да и скомпилированные у меня что-то не захотели работать. Правда, если честно, я и не особо настаивал, т.к. уже давно хотелось написать свой UnitTest - просто из интереса, не особо навороченный. Ну а тут уж такой повод появился :) Так и появился этот небольшой проект под названием CTinyTester. Основные требования к тестеру были такие:
Конечно, на мошь CppUnit я не претендую, но какой-то минимум сделать хотелось. Внутренняя реализация классов очень простая и вы можете сами все посмотреть. Я буду описывать, в основном то, как этими классами пользоваться. Комментарии в исходниках оформлены специально для программы doxygen. Документация, которая была сгенерирована этой замечательной программкой в формате chm вы можете скачать здесь. Основные классыВсе классы объединены в пространство имен tut (от слов Tiny Unit Test). В этом проекте содержатся два основных класса:
tut::CTinyTester - это основа всех тестов. Именно в нем содержатся все методу, которые можно назвать тестами. Подробности чуть попозже. Сами классы и пример использования вы можете скачать здесь. CTestLogИтак, в первую очередь вы должны создать класс, производный от CTestLog. CTestLog - это базовый класс для классов, которые представляют результаты тестирования в какой-либо форме (далее я их буду называль логеры или просто логи). Сам CTestLog абстрактный, поэтому надо будет делать классы производные от него. Например, в архиве лежит класс CTextLog, он записывает результаты тестов в текстовый файл. С ним познакомимся попозже. Основные методы класса CTestLog описаны в документации. В двух словах о их можно сказать так:
Все вышесказанное вам понадобится, если вы захотите сделать свой логер. Как пример логера я включил в архив CTextLog - логер, который пишет результаты в обычный текстовый файл наподобие . Его описание также есть в докуменнтации. Скажу только, что для его создания надо передать в конструктор имя файла, в который будет писать логер. CTinyTesterА это основа всех тестов. Именно в его методах и проходят тесты. Вам нужно создать класс, производный от CTinyTester и переопределить в нем чисто виртуальную функцию void TestBody(); Она должна быть защищенной (protected). Именно в ней и происходят тесты. Методы для тестирования вы можете посмотреть в документации (их немного), найдя в разделе "Группы" подраздел "Собственно сами тесты". А макросы для тестирования исключений, описаны в подразделе "Макросы, предназначенные для отладки исключений". То есть в переопределенном методе TestBody() вы используете эти методы и макросы для составления тестов. К самим классам в архиве прилагается пример тестированяи класса для работы с реестром, там вы можете посмотреть все это на примере. ИтогоТипичная функция main() для тестирования может выглядеть следующим образом (взято из примера): #include "TinyTest\TextLog.h" #include "RegTester.h" int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { try { tut::CTextLog Log("reg.log"); CRegTester Tester (&Log); Tester.Start(); } catch (tut::CTextLog::EFileOpenError) { } return 0; } Здесь CRegTester - это класс, производный от tut::CTinyTester. В данном случае его описание выглядит так: #include "tinytest\tinytester.h" #include "Registry\RegistryReader.h" #include "Registry\SimplyRegistry.h" #include "Registry\RegistryWriter.h" using reg::CRegistryReader; using reg::CRegistryWriter; using reg::CSimplyRegistry; class CRegTester : public tut::CTinyTester { private: // Подготовимся к тесту bool Prepare(); // Тестирование класса для записи void TestWriter(); // Тестирование класса для чтения void TestReader(); // Тестирование класса для быстрого доступа void TestSimply(); public: CRegTester(tut::CTestLog *pLog); virtual ~CRegTester(void); protected: void TestBody(); }; Не обращайте внимание на приватные члены - они сделаны просто для разделения тестов. Метод TestBody() в нашем случае выглядит так: void CRegTester::TestBody() { if (!Prepare()) { return; } TestReader(); TestWriter(); TestSimply(); } Здесь Prepare() просто подготавливает записи реестра, на которых будут проходить испытания. У вас его может и не быть. Таким образом, простейший класс для тестирования может выглядить так: #include "tinytest\tinytester.h" #include "Registry\RegistryReader.h" #include "Registry\SimplyRegistry.h" #include "Registry\RegistryWriter.h" using reg::CRegistryReader; using reg::CRegistryWriter; using reg::CSimplyRegistry; class CMyTester : public tut::CTinyTester { public: CRegTester(tut::CTestLog *pLog); virtual ~CRegTester(void); protected: void TestBody(); }; Но не забудьте вызвать конструктор базового класса, в который также передается указатель на класс логера: CMyTester::CMyTester(tut::CTestLog *pLog): CTinyTester (pLog) { } ЗаключениеНу вот пожалуй и все. За более подробным описанием обращайтесь к документации, как говорится RTFM :)
|