GoogleTestPrimerRussian /

Filename Size Date modified Message
43.6 KB
README.md edited online with Bitbucket

Введение в Google C++ Testing Framework

Это перевод Google C++ Testing Framework Primer, выполненный demin, благополучно потерянный гуглом при переезде с code.google.com на github и вытащенный из кэша гугла

Введение: Что такое Google C++ Testing Framework?

Google C++ Testing Framework (далее по тексту Google Test) призвана помочь вам в создании качественных тестов для программ на C++.

Неважно, работаете ли вы в Linux, Windows или Mac - если вы пишете программы на С++, то Google Test поможет вам в этом.

Что значит хороший тест, и как именно Google Test помогает делать хорошие тесты?

  • Тесты должны быть независимыми и повторяемыми. Неудобно отлаживать тест, когда его результат зависит от других тестов. Google Test изолирует каждый тест, запуская его отдельным объектом. Если тест сбоит, то Google Test дает возможность запускать его независимо для быстрой отладки.
  • Тесты должны быть грамотно организованы и отражать структуру тестируемого кода. Google Test группирует тесты в наборы (test cases), которые могут иметь общие данные и подпрограммы. Такой подход просто реализуем и позволяет легко управлять тестами. Подобное единообразие крайне полезно, когда люди переключаются с одного проекта на другой и начинают работать с новым для них кодом.
  • Тесты должны быть переносимы и пригодны для повторного использования. В мире открытого программного обеспечения очень много переносимого кода, поэтому его тесты также должны быть переносимы. Google Test работает на разных операционных системах, с разными компиляторами, с поддержкой исключений или нет, поэтому тесты в Google Test могут работать в разнообразных конфигурациях. (На данный момент имеются скрипты для сборки только под Linux - мы работаем над скриптами для других платформ).
  • Когда тест дает сбой, он должен предоставлять максимум информации об ошибке. Google Test не останавливается при первом же сбое. Наоборот, только текущий тест прерывается, а управление передается следующему тесту. Вы можете использовать в тестах мягкие (нефатальные) типы проверок, после сбоя на которых тест продолжает работу. Таким образом, вы можете обнаружить и исправить несколько ошибок в одном прогоне.
  • Среда тестирования должна избавить автора тестов от рутинных операций и позволить сконцентрироваться непосредственно на cмысле тестов. Google Test автоматически регистрирует все объявленные тесты и не требует от программиста ручного добавления их в систему запуска.
  • Тесты должны быть быстрыми. В Google Test вы можете повторно использовать общие для всех тестов или какого-то конкретного тестового набора ресурсы без необходимости делать тесты зависимыми друг от друга, так как есть возможность инициализировать среду тестирования и чистить мусор только один раз. Так как Google Test построена на базе популярной архитектуры xUnit, вы будете чувствовать себя как дома, если вы раньше работали с JUnit или PyUnit. Если нет, вам потребуется 10 минут чтобы освоить основы и начать работать. Поехали!

Замечание: Как упоминалось раньше, неформально полное название Google C++ Testing Framework может сокращаться до Google Test.

Создание нового проекта

Для создания тестовой программы с использованием Goole Test вам необходимо скомпилировать Google Test в формат библиотеки и прилинковать к вашим тестам. Мы создали необходимые скрипты и файлы конфигурации для некоторых популярных системы сборки (msvc/ для Visual Studio, xcode/ для Mac Xcode, make/ для GNU make, codegear/ для Borland C++ Builder, scons/ для Scons, и скрипт для autotools в корневом каталоге Google Test). Если вы используете другую систему сборки, возьмите за образец файл make/Makefile чтобы понять, как собрать Google Test (по сути, вам надо скомпилировать src/gtest-all.cc со значениями GTEST_ROOT и GTEST_ROOT/include в списке путей для заголовочных файлов, где GTEST_ROOT является корневым каталогом директории Google Test).

Скомпилировав Google Test как библиотеку, вы можете создать новый проект. Убедитесь, что путь GTEST_ROOT/include включен в список поиска заголовочных файлов, чтобы компилятор смог найти <gtest/gtest.h>. Проект должен быть слинкован с библиотекой Google Test (например, для Visual Studio, вы можете добавить зависимость от gtest.vcproj). Если какие-то моменты остались неясными, посмотрите, как у Google Test устроена система самотестирования, и используйте ее в качестве примера.

Основная идея

Работая с Google Test, вы пишете утверждения, которые являются операторами проверки истинности некоторого условия. Проверка утверждения может закончится успехом, фатальной ошибкой (fatal error) или нефатальной ошибкой (non-fatal error). При фатальной ошибке выполнение текущей функции прерывается. В противном случае программа просто продолжает работу дальше.

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

Вы можете группировать тесты в наборы (test cases), сообразно структуре тестируемой программы. Если несколько тестов используют общие объекты и подпрограммы, вы может объединить их в тестовый класс (test fixture).

Тестовая программа может состоять из нескольких наборов тестов.

Мы покажем, как писать тестовую программу, начиная с уровня отдельных утверждений, затем поднимаясь на уровень тестовых наборов и тестовых классов.

Утверждения

Утверждения в Google Test являются макросами, схожими с вызовами функций. Вы тестируете класс или функцию, делая предположения в форме утверждений, которые соответствуют ожидаемой логике. Когда утверждение не срабатывает, Google Test печатает имя файла и номер строки, где произошел сбой. Также выводится диагностическое сообщение об ошибке. Вы можете задавать свои собственные дополнительные сообщения, которые будут добавлены к стандартному.

Утверждения бывают двух типов, схожих по названию, но по разному влияющих на выполнение текущей функции. ASSERT_* генерируют фатальные ошибки, при возникновении которых выполнение текущей функции прерывается. Другой тип, EXPECT_*, генерирует "мягкие", нефатальные ошибки, которые не прерывают текущую функцию. Такие утверждения являются более предпочтительными, так как дают возможность обнаружить сразу несколько проблем в тесте. Однако вам следует использовать ASSERT_*, если уже не имеет смысла продолжать тест после сбоя.

Когда показавший ошибку ASSERT_* немедленно прерывает выполнение текущей функции, возможно, что часть кода, ответственного за чистку мусора и освобождение ресурсов после теста, не будет выполнена, что может привести к утечкам памяти. В зависимости от типа утечки может и не стоит заботиться о них в данном случае, но надо быть готовым к возможным сообщениям об ошибках от систем проверки динамически распределенной памяти.

Чтобы вывести свое собственное сообщение об ошибке, просто используйте макрос утверждения как стандартный поток и оператор <<. Например:

ASSERT_EQ(x.size(), y.size()) << "Длина вектора x не равна длине вектора y";

for (int i = 0; i < x.size(); ++i) {
  EXPECT_EQ(x[i], y[i]) << "Вектора x и y имеют отличия по индексу " << i;
}

Так можно распечатать все, что может быть выведено в поток ostream. В частности, строки языка С и объекты string. Если печатается многобайтовая строка (wchar_t*, TCHAR* в режиме UNICODE в Windows, или std::wstring), то она будет преобразована в кодировку UTF-8.

Основные типы утверждений

Данные утверждения производят проверку на ложь/истина.

Фатальное утверждение Нефатальное утверждение Цель проверки
ASSERT_TRUE( _условие_ ); EXPECT_TRUE( _условие_ ); условие истино
ASSERT_FALSE( _условие_ ); EXPECT_FALSE( _условие_ ); условие ложно

Обратите внимание, что когда утверждение дает сбой, ASSERT_* генерирует фатальную ошибку и прекращает выполнение текущей функции, тогда как EXPECT_* генерирует "мягкую", нефатальную ошибку, и текущая функция продолжает выполнение. В любом случае считается, что данный тест в целом дал сбой.

Доступность: Linux, Windows, Mac.

Парное сравнение

Этот раздел описывает утверждения для сравнение друх значений.

Фатальное утверждение Нефатальное утверждение Цель проверки
ASSERT_EQ( _знач1_, _знач2_ ); EXPECT_EQ( _знач1_, _знач2_ ); _знач1_ == _знач2_
ASSERT_NE( _знач1_, _знач2_ ); EXPECT_NE( _знач1_, _знач2_ ); _знач1_ != _знач2_
ASSERT_LT( _знач1_, _знач2_ ); EXPECT_LT( _знач1_, _знач2_ ); _знач1_ < _знач2_
ASSERT_LE( _знач1_, _знач2_ ); EXPECT_LE( _знач1_, _знач2_ ); _знач1_ <= _знач2_
ASSERT_GT( _знач1_, _знач2_ ); EXPECT_GT( _знач1_, _знач2_ ); _знач1_ > _знач2_
ASSERT_GE( _знач1_, _знач2_ ); EXPECT_GE( _знач1_, _знач2_ ); _знач1_ >= _знач2_

В случае ошибки Google Test печатает оба значения, и знач1, и знач2.

Историческая справка: до февраля 2016 в выражении *_EQ первый параметр считался ожидаемым значением, а второй - значением, полученным на самом деле. Довольно много кода было написано с расчётом именно на такой порядок. Сейчас оба параметра выражения *_EQ обрабатываются одинаково.

Значения аргументов должны иметь возможность сравнения, иначе вы получите сообщение компилятора об ошибке. Значения также должны поддерживать оператор << для вывода в поток ostream. Все встроенные типы данных удовлетворяют этим условиям.

Утверждения могут работать с пользовательскими типами, но только если вы зададите соответственные операторы сравнения (например, ==, < и т.д.). Если соответствующий оператор определен, то предпочтительнее использовать макросы ASSERT_*(), так как они печатают не только результат сравнения, но сами операнды.

Аргументы всегда вычисляются только один раз, поэтому можно спокойно использовать вызовы с побочными эффектами. Однако, в языках С и С++ порядок вычисления аргументов функций не определен, и компилятор может их вычислить в любом порядке, поэтому полагаться на определенный порядок вычисления аргументов утверждения нельзя.

ASSERT_EQ() поддерживает сравнение указателей. Если это две строки С, будет проверено, указывают ли они на одну и ту же область памяти, и значения самих строк сравниваться не будут. Если же вы хотите сравнить значения двух строк С (например, const char*), то используйте ASSERT_STREQ(), которое будет описано ниже. В частности, для проверки строки С на NULL используйте ASSERT_STREQ(NULL, c_string), однако для сравнения двух объектов типа string надо использовать ASSERT_EQ.

Макросы, описанные в данном разделе, работают с обычными и многобайтовыми строковыми объектами (string и wstring).

Доступность: Linux, Windows, Mac.

Сравнение строк

Утверждения в данной группе все сравнивают строки С. Если вы хотите сравнить два объекта типа string, то используйте вместо них EXPECT_EQ, EXPECT_NE и т.д.

Фатальное утверждение Нефатальное утверждение Цель проверки
ASSERT_STREQ( _стр1_, _стр2_ ); EXPECT_STREQ( _стр1_, _стр2_ ); две строки С содержат одинаковые значения
ASSERT_STRNE( _стр1_, _стр2_ ); EXPECT_STRNE( _стр1_, _стр2_ ); две строки С содержат разные значения
ASSERT_STRCASEEQ( _стр1_, _стр2_ ); EXPECT_STREQ( _стр1_, _стр2_ ); две строки С содержат одинаковые значения без учета регистра
ASSERT_STRCASENE( _стр1_, _стр2_ ); EXPECT_STRNE( _стр1_, _стр2_ ); две строки С содержат разные значения без учета регистра

Обратите внимание, что "CASE" в имени утверждения означает, то регистр будет проигнорирован.

*STREQ* и *STRNE* также могут работать с многобайтовыми строками С (wchar_t*). В случае неудачного сравнения двух многобайтовых строк их значения буду напечатаны в виде однобайтовых строк в формате UTF-8.

Значение указателя NULL и пустая строка являются разными значениям.

Доступность: Linux, Windows, Mac.

См. также: Более подробная информация о приемах сравнения (например, подстроки, префиксы и регулярные выражения), см. Advanced Google Test Guide.

Элементарные тесты

Для создания теста:

  • Используйте макрос TEST() для определения функции теста. Это обычная функция языка С++, которая не имеет возвращаемого значения.
  • В этой функции можно использовать любые корректные операторы С++ вместе с утверждениями Google Test для проверки значений.
  • Результат теста определяется утверждениями; если хоть одно утверждение в тесте дало ошибку (фатальную или нефатальную), или если тест завершился аварийно, но тест в целом считается сбойным. В противном случае, тест регистрируется как успешный.
TEST(имя_набора_тестов, имя_теста) {
 ... тело_теста ...
}

Аргуметы макроса TEST() идут от общего к частному. Первый аргумент является именем набора тестов, а второй -- именем теста в данном наборе. Набор тестов может содержать любое количество отдельных тестов. Полное имя теста состоит из имени набора, которому этот тест принадлежит, и его собственного имени. Тесты из разных наборов могут иметь одинаковые собственные имена.

Например, имеется функция, возвращающая целое:

int Factorial(int n); // Вернуть факториал n

Тест для этой функции может быть таким:

// Проверить факториал от 0.
TEST(FactorialTest, HandlesZeroInput) {
  EXPECT_EQ(1, Factorial(0));
}

// Проверить факториал некоторых положительных значений.
TEST(FactorialTest, HandlesPositiveInput) {
  EXPECT_EQ(1, Factorial(1));
  EXPECT_EQ(2, Factorial(2));
  EXPECT_EQ(6, Factorial(3));
  EXPECT_EQ(40320, Factorial(8));
}

Google test группирует результаты тестов по наборам, так что связанные по смыслу тесты должны быть в одном наборе; другими словами, первый аргумент их TEST() должен быть одинаковым. В приведенном выше примере вы имеем два теста, HandlesZeroInput and HandlesPositiveInput, принадлежащих одному набору с именем FactorialTest.

Доступность: Linux, Windows, Mac.

Тестовые классы: использования единой конфигурации для нескольких тестов

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

Для создания тестового класса:

  • Унаследуйте свой класс от ::testing::Test. Начните описание класса с protected: или public: в зависимости от вашего желания дать доступ к членам тестового класса в его подклассах.
  • Внутри класса объявите любые объекты, которые планируете использовать.
  • Если это необходимо, напишите конструктор по умолчанию или функцию SetUp() для инициализации объекта для каждого теста. Распространенной ошибкой является написание SetUp() как Setup(), то есть со строчной буквой u -- не делайте этого.
  • Если требуется, также напишите деструктор или функцию TearDown() для освобождения ресурсов, распределенных в SetUp(). Для более подробной информации о том, когда использовать конструктор/деструктор, а когда SetUp()/TearDown(), обратитесь к вопросу в FAQ.
  • Если необходимо, объявите подпрограммы, которые ваши тесты будут использовать.

Когда используете тестовый класс, пишите TEST_F() вместе TEST(), что даст тесту доступ к объектам и подпрограммам тестового класса.

TEST_F(имя_набора_тестов, имя_теста) {
 ... тело_теста ...
}

Как и у TEST() первый аргумент -- это имя набора тестов, но для TEST_F() он должен совпадать с именем тестового класса. Возможно вы догадались: _F от английского fixture.

С сожалению система макросов в С++ не позволяет нам создать единый макрос, который бы поддерживал оба типа тестов. Использование неправильного макроса приведет к ошибке компиляции.

Также вы должны объявить тестовый класс до использования его имени в TEST_F(), иначе вы получите ошибку компиляции "virtual outside class declaration".

Для теста, объявленного с помощью TEST_F(), Google test:

  • Создаст новый экземпляр тестового класса в процессе выполнения.
  • Сразу же проиницилизирует его через SetUp().
  • Запустит тест.
  • Вызовет TearDown() для чистки мусора.
  • Удалит экземпляр тестового класса. Каждый тест в тестовом наборе будет работать со своим собственным экземпляром тестового класса, а Google Test всегда удаляет предыдущий экземпляр тестового класса перед созданием следующего.

Google test не использует повторно один и тот же экземпляр тестового класса для разных тестов. Любые изменения, которые тест может сделать в очередном экземпляре тестового класса, не затрагивают остальные тесты.

Как пример, давайте напишем тест для очереди типа FIFO с именем Queue, имеющей следующий интерфейс:

template <typename E> // E - типа элемента.
class Queue {
 public:
  Queue();
  void Enqueue(const E& element);
  E* Dequeue(); // Возвращает NULL, если очередь пуста.
  size_t size() const;
  ...
};

Сначала определяем тестовый класс. По соглашению вам стоит назвать его FooTest, где Foo - имя тестируемого класса.

class QueueTest : public ::testing::Test {
 protected:
  virtual void SetUp() {
    q1_.Enqueue(1);
    q2_.Enqueue(2);
    q2_.Enqueue(3);
  }

  // virtual void TearDown() {}

  Queue<int> q0_;
  Queue<int> q1_;
  Queue<int> q2_;
};

В этом случае TearDown() не требуется, так как не нужно ничего освобождать после теста в дополнение к тому, что делается в деструкторе.

Теперь напишем тесты, используя TEST_F() и тестовый класс.

TEST_F(QueueTest, IsEmptyInitially) {
  EXPECT_EQ(0, q0_.size());
}

TEST_F(QueueTest, DequeueWorks) {
  int* n = q0_.Dequeue();
  EXPECT_EQ(NULL, n);

  n = q1_.Dequeue();
  ASSERT_TRUE(n != NULL);
  EXPECT_EQ(1, *n);
  EXPECT_EQ(0, q1_.size());
  delete n;

  n = q2_.Dequeue();
  ASSERT_TRUE(n != NULL);
  EXPECT_EQ(2, *n);
  EXPECT_EQ(1, q2_.size());
  delete n;
}

Мы использовали оба типа утверждений: ASSERT_* и EXPECT_*. Используйте EXPECT_*, если хотите, чтобы тест продолжил работу после регистрации ошибки. Если продолжение теста бессмысленно, то используйте ASSERT_*. Например, второе утверждение в тесте Dequeue -- ASSERT_TRUE(n != NULL), так как мы собираемся разыменовывать указатель n ниже, а это может закончиться нарушением защиты памяти, если n равен NULL.

Когда все это запускается, происходит следующее:

  • Google Test создает объект QueueTest (назовем его t1).
  • t1.SetUp() инициализирует t1.
  • Первый тест (IsEmptyInitially) использует t1.
  • t1.TearDown() чистит мусор, когда тест закачивается.
  • t1 уничтожается.
  • Все шаги повторяются снова с другим объектом QueueTest, который на этот раз используется в тесте DequeueWorks.

Доступность: Linux, Windows, Mac.

Замечание: Google test автоматически сохраняет все свои настройки, когда тестовый объект создается и восстанавливает, когда он уже уничтожен.

Запуск тестов

TEST() и TEST_F() автоматически регистрируют ваши тест в Google Test. Так что в отличие от многих других утилит тестирования для С++ вам не надо вручную прописывать тест в отдельном списке для запуска.

После объявление тестов вы можете просто вызвать функцию RUN_ALL_TESTS(), которая вернет 0, если все тесты прошли успешно, и 1 в противном случае. RUN_ALL_TESTS() запускает все тесты в вашем исполняемом модуле -- тесты могут находиться в разных тестовых наборах или разных исходных модулях.

При старте макрос RUN_ALL_TESTS():

  • Запоминает настройки Google Test.
  • Создает объект тестового класса первого теста.
  • Инициализирует его вызовом SetUp().
  • Запускает тест с использованием объекта тестового класса.
  • Производит чистку мусора объекта тестового класса путем вызова TearDown().
  • Удаляет объект тестового класса.
  • Восстанавливает настройки Google Test.
  • Повторяет указанные шаги для всех остальных тестов.

Дополнительно, если конструктор тестового класса завершился с ошибкой на шаге 2, шаги с 3 до 5 пропускаются. Аналогично если на шаге 3 возникает ошибка, то шаг 4 пропускается.

Важно: Вы не должны игнорировать возвращаемое функцией RUN_ALL_TESTS() значение, иначе gcc сообщит вам об ошибке. Смысл этого в том, что автоматизированная система тестирования определяет успешность прохождения тестов по коду возврата, а не по данным, выведенным в стандартные потоки stdout/stderr; поэтому ваша функция main() должна возвращать значение, полученное от RUN_ALL_TESTS().

Также стоит помнить, что вы можете вызывать RUN_ALL_TESTS() только один раз. Повторный ее вызов может конфликтовать с дополнительными возможностями Google Test (например, "смертельные" тесты), и данная возможность не поддерживается.

Доступность: Linux, Windows, Mac.

Пишем функцию main()

Можете начать вот с такой заготовки:

#include "this/package/foo.h"
#include <gtest/gtest.h>

namespace {

// Тестовый класс для тестирования класса Foo.
class FooTest : public ::testing::Test {
 protected:
  // Можете удалить любую или все из функций ниже, если они пустые.

  FooTest() {
    // Здесь можно подготовить тестовые данные для каждого теста.
  }

  virtual ~FooTest() {
    // Здесь производится чистка мусора. Данная функция не должна
    // генерировать исключений.
  }

  // Если конструктор или деструктор не подходят вам для настройки
  // тестовых данных и чистки мусора, то можете использовать следующие
  // методы:

  virtual void SetUp() {
    // Данная функция вызывается сразу после конструктора (до теста).
  }

  virtual void TearDown() {
    // Данная функция вызывается сразу после теста (до деструктора).
  }

  // Объекты, объявленные тут, могут быть использованы во всем тестовом
  // классе Foo.
};

// Проверяем, что метод Foo::Bar() правильно делает функцию Abc.
TEST_F(FooTest, MethodBarDoesAbc) {
  const string input_filepath = "this/package/testdata/myinputfile.dat";
  const string output_filepath = "this/package/testdata/myoutputfile.dat";
  Foo f;
  EXPECT_EQ(0, f.Bar(input_filepath, output_filepath));
}

// Проверяем, что класс Foo правильно выполняет задачу Xyz.
TEST_F(FooTest, DoesXyz) {
  // Убеждаемся, что Xyz работает правильно в Foo.
}

}  // namespace

int main(int argc, char **argv) {
  ::testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}

Функция ::testing::InitGoogleTest() производит разбор параметров командной строки для Google Test и удаляет все неизвестные флаги. Это позволяет пользователю управлять тестовой программой через различные флаги, описанные в GoogleTestAdvancedGuide. Вы должны вызвать эту функцию до RUN_ALL_TESTS(). Иначе настройки Google Test не будут должным образом проинициализированы.

В Windows InitGoogleTest() поддерживает многобайтовые строки, и может быть скомпилирована в режиме UNICODE.

Резонно предположить, что написание функции main() занятие скучное. Может быть, и поэтому Google Test предоставляет уже готовую реализацию фунции main(). Если она вас устраивает, то просто прилинкуйте библиотеку gtest_main и все.

Важное замечание для пользователей Visual C++

Если вы помещаете тесты в библиотеку, а ваша функция main() находится в другой библиотеке или .exe файле, то такие тесты не будут работать. Причина в ошибке в Visual C++. Когда вы определяете тесты, Google Test создает соответствующие статические объекты для их регистрации. На эти объекты никто не ссылается, но их конструкторы все равно работают. Когда линкер Visual C++ обнаруживает, что ни на один объект в библиотеке никто не ссылается, он исключает такую библиотеку из линковки. Вам надо как-то сослаться на вашу библиотеку, чтобы линкер ее не выкинул. И вот как это делается. Где-нибудь в коде библиотеки объявите функцию:

__declspec(dllimport) int PullInMyLibrary() { return 0; }

Если вы помещаете тесты в статическую библиотеку (не DLL), тогда __declspec(dllexport) не нужно. Затем в главной программе напишите код, который будет вызывать данную функцию:

int PullInMyLibrary();
static int dummy = PullInMyLibrary();

Это создаст видимость явного использования вашей библиотеки тестами, и позволит им быть зарегистрированными при старте.

Также, если вы помещаете тесты в статическую библиотеку, то добавьте /OPT:NOREF в настройки линкера главной программы. Если вы используете графическую среду MSVC++, то зайдите в настройки проекта .exe файла Properties/Configuration Properties/Linker/Optimization и установите опцию References в Keep Unreferenced Data (/OPT:NOREF). Это не даст линкеру исключить отдельные имена функций, генерируемых вашими тестами, из конечного исполняемого файла.

Есть еще одна проблема. Если вы используете Google Test как статическую библиотеку (как это задано в gtest.vcproj), ваши тесты также должны находиться в статической библиотеке. Если они у вас вынуждено находятся в DLL, вы должны скомпилировать Google Test тоже в форме DLL. Иначе ваши тесты не будут правильно запускаться или запускаться вообще. Из этого можно сделать вывод: для упрощения жизни -- не используйте библиотеки для ваших тестов!

Что дальше?

Поздравляем! Вы освоили основы Google Test. Вы можете начать писать и запускать тесты c Google Test, посмотреть примеры, или продолжить читать Advanced Guide, где описано множество других полезных возможностей Google Test.

Ограничения

Google Test разработана быть безопасной для многопоточного выполнения. Однако пока у нас недостаточно времени для реализации механизмов синхронизации для различных платформ, поэтому пока небезопасно использовать утверждения Google Test параллельно в двух потоках. Так как в большинстве тестов утверждения, как правило, проверяются в главном потоке, обычно это не составляет проблемы. При желании вы можете самостоятельно разработать примитивы синхронизации в gtest-port.h.