-
Notifications
You must be signed in to change notification settings - Fork 3
GTest
Мы используем gtest для написания и запуска юнит-тестов. Эта страничка служит кратким гайдом.
Юниттесты сейчас собираются в цель сборки unit_tests
(unit_tests.exe
на windows). При запуске он запустит все тесты, которые в нем есть и выведет подробную информацию о них.
В случае, если есть необходимость запустить не все тесты, на помощь приходит параметр --gtest_filter
. Он принимает список фильтров через запятую. Фильтр может быть включающим (просто маска имен) и исключающим (начинается с минуса). Поддерживается символ *
для задания любого имени.
Пример (запустятся все тесты из base/values_unittest.cc
, кроме содержащих в названии слово Dictionary
):
./unit_tests --gtest_filter=ValuesTest.*,-ValuesTest.*Dictionary*
Рекомендуется писать тесты в файлах .cc
, с суффиксом _unittest
. Добавляя файл тестов необходимо добавить его в цель unit_tests
в CMakeLists.txt
. Тесты автоматически будут зарегистрированы в gtest.
В файл нужно подключить gtest/gtest.h
. Там находятся макросы и классы, инфраструктуры тестирования.
Имена тестов состоят из двух частей разделенных точкой. Часть до точки является общей для группы тестов, обычно расположенных в одном файле. Часть после точки индивидуальна для каждого теста.
Существует два типа тестов, тест-функция и тест-фикстура.
Самый простой тест, который читается как обычная функция. На самом деле, можно залесть в дебри и выяснить, что на каждую такую функцию генерируется отдельный класс и статическая переменная, а функция является методом этого класса, но это уже подробности реализации. Для создания теста нужно использовать макрос TEST(TestGroupName, TestName)
.
#include "gtest/gtest.h"
TEST(MyPrettyTest, HelloWorldTest) {
EXPECT_EQ(4, 2 + 2);
}
Этот тип тестов используется, когда удобно написать отдельный класс, выполняющий тестирование. В этом случае класс нужно унаследовать от testing::Test
. Его имя будет совпадать с названием группы тестов, основанной на этом классе. В классе может быть конструктор по умолчанию, должен быть виртуальный деструктор и могут быть переопределены методы void testing::Test::SetUp()
и void testing::Test::TearDown()
, вызываемые для инициализации и деинициализации объекта. Тест создается с помощью макроса TEST_F(FixtureClassName, TestName)
, использование которого похоже на использование макроса TEST(group, name)
.
#include <algorithm>
#include "gtest/gtest.h"
class MyPrettyFixture : public testing::Test {
public:
MyPrettyFixture();
virtual ~MyPrettyFixture();
virtual void SetUp() override;
virtual void TearDown() override;
void DoSomeStuff(int* a, int* b);
};
MyPrettyFixture::MyPrettyFixture() {}
MyPrettyFixture::~MyPrettyFixture() {}
void MyPrettyFixture::SetUp() {}
void MyPrettyFixture::TearDown() {}
void MyPrettyFixture::DoSomeStuff(int* a, int* b) {
std::swap(*a, *b);
}
TEST_F(MyPrettyFixture, SwapTest) {
int a = 1, b = 2;
DoSomeStuff(&a, &b);
EXPECT_EQ(2, a);
EXPECT_EQ(1, b);
}
Стоит обратить внимание, что у самого теста нет доступа к приватным данным класса фикстуры, потому что он является методом унаследованного класса.
Для проверок внутри тестов есть набор макросов, которые помимо того, что производят проверку, выводят подробное сообщение в случае если проверка не прошла. Вот только краткий список:
EXPECT_EQ(expected, real) // OK if equals
EXPECT_NE(expected, real) // OK if not equals
EXPECT_TRUE(value) // OK if true
EXPECT_FALSE(value) // OK if false
EXPECT_GT(expected, real) // OK if real greater then expected
EXPECT_GE(expected, real) // OK if real greater then or equals to expected
EXPECT_LT(expected, real) // OK if real less then expected
EXPECT_LE(expected, real) // OK if real less then or equals to expected
Также существуют ассерты, эти проверки в случае провала прекращают выполнение теста.
ASSERT_EQ(expected, real)
ASSERT_NE(expected, real)
ASSERT_TRUE(value)
ASSERT_FALSE(value)
ASSERT_GT(expected, real)
ASSERT_GE(expected, real)
ASSERT_LT(expected, real)
ASSERT_LE(expected, real)
Как видно, они полностью соответствуют обычным проверкам.
Тест считается пройденным, если не провалилась ни одна проверка.