Модульные (unit) тесты — это автоматизированные тесты, которые проверяют корректность работы отдельных модулей программы (функций, классов) изолированно от других частей системы.
Как помогает:
Тесты обнаруживают баги сразу после внесения изменений, а не на этапе интеграции или в production.
// Пример: тест для функции сложения
int add(int a, int b) {
return a + b;
}
void test_add() {
assert(add(2, 2) == 4); // Позитивный тест
assert(add(-1, 1) == 0); // Граничный случай
assert(add(0, 0) == 0); // Еще один граничный случай
}
Преимущество:
Тесты дают уверенность, что изменения кода не сломали существующую функциональность.
Польза:
Тесты служат живыми примерами использования API, показывая, как должен работать код.
// Тест документирует ожидаемое поведение
void test_string_utils() {
// trim должен удалять пробелы по краям
assert(trim(" hello ") == "hello");
// to_upper должен преобразовывать в верхний регистр
assert(to_upper("Hello") == "HELLO");
}
Эффект:
Необходимость тестировать код заставляет писать:
// Пример теста на Google Test
TEST(MathTest, Addition) {
EXPECT_EQ(add(1, 1), 2);
EXPECT_EQ(add(-1, 1), 0);
}
TEST(StringTest, Trim) {
std::string s = " test ";
trim(s);
EXPECT_EQ(s, "test");
}
// Плохой тест (проверяет только очевидное)
TEST(AddTest, Basic) {
ASSERT_EQ(add(2, 2), 4);
}
// Хороший тест (проверяет разные сценарии)
TEST(AddTest, Comprehensive) {
// Позитивные случаи
ASSERT_EQ(add(0, 0), 0);
ASSERT_EQ(add(-1, 1), 0);
ASSERT_EQ(add(INT_MAX, 0), INT_MAX);
// Проверка на переполнение
ASSERT_THROW(add(INT_MAX, 1), std::overflow_error);
}
Правильно написанные модульные тесты — это не дополнительная нагрузка, а инструмент, который в долгосрочной перспективе экономит время разработки и снижает количество ошибок в production.