После тренинга Кевлина Хенни, я понял, что отсутствие под рукой удобной библиотеки для unit тестирования не является причиной его не использовать. Макрос assert
, который есть везде, является достаточным условием для использования тестов.
Например, есть мини-проект в один файл, и не охота тащить Google Test или cmockery. Я обычно делаю что-то такое:
#include <cassert> void foo(...) { // something } ... #ifdef UNIT_TESTING void Test_for_a_particular_use_case() { // Initialization ... assert(condition_1); ... assert(condition_N); } ... int main(...) { Test_for_a_particular_use_case(); std::cout << “All tests passed.” << std::endl; return 0; } #else int main(...) { // a proper main } #endif
Тут, конечно, не так удобно, так как иногда забываешь добавить запуск теста в main()
, и вроде как бы все работает, но на самом деле просто тест не запускается.
Но! Все это мелочи, по сравнению с удобством, которое дают тесты.
Кстати, заметил за собой интересую привычку. Практически всегда, когда пишу функцию, работающую с файлами, всегда рождаются две, например:
void FunctionDoingSomethingFromStream(std::istream* is) { ... } void FunctionDoingSomethingFromFile(const std::string& filename) { std::ifstream is(filename); return FunctionDoingSomethingFromStream(&is); }
Первая функция прекрасно тестируется, так как ей можно подсунуть std::istringstream
с тестовыми данными. Вторую же можно практически не тестировать (ну разве что на фазе QA, на реальных файлах, но не в unit-тестах в процессе сборки).
Еще интересный приемчик от Кевлина Хенни. У теста обычно есть объект тестирования (класс или функция), начальное условие (pre-condition) и конечное состояние (post-condition). И данные фазы удобно подчеркнуть в комментариях словами “Given”, “When” и “Then”, например:
void Test_for_a_particular_use_case_to_check() { // Given: ClassToTest a; // When: a.do_this(...); a.do_that(...); a.setup_something(...); // Then: assert(condition_1); ... assert(condition_N); }
Явное разделение этих фаз провоцирует правильную структуру теста: без циклов и условий, и работа только по одному сценарию (для другого сценария будет другой тест).
■