Как гарантированно работает регистрация тестов через TEST () в googletest? - PullRequest
0 голосов
/ 26 января 2020

в настоящее время я смотрю на саморегистрационные классы (да, я также читал о проблемах, связанных с ними, но я все еще думаю, что у меня есть вариант использования для этого) и закончил UO с googletest, который использует эту технику для создания и зарегистрировать новые тесты с помощью макроса TEST(test_suite_name, test_name). См. Следующие определения:

в gtest.h

#define GTEST_TEST(test_suite_name, test_name)             \
  GTEST_TEST_(test_suite_name, test_name, ::testing::Test, \
              ::testing::internal::GetTestTypeId())

#define TEST(test_suite_name, test_name) GTEST_TEST(test_suite_name, test_name)

в gtest-internal.h

// Helper macro for defining tests.
#define GTEST_TEST_(test_suite_name, test_name, parent_class, parent_id)      \
  class GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)                    \
      : public parent_class {                                                 \
   public:                                                                    \
    GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)() {}                   \
    ~GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)() override = default; \
    GTEST_DISALLOW_COPY_AND_ASSIGN_(GTEST_TEST_CLASS_NAME_(test_suite_name,   \
                                                           test_name));       \
    GTEST_DISALLOW_MOVE_AND_ASSIGN_(GTEST_TEST_CLASS_NAME_(test_suite_name,   \
                                                           test_name));       \
                                                                              \
   private:                                                                   \
    void TestBody() override;                                                 \
    static ::testing::TestInfo* const test_info_ GTEST_ATTRIBUTE_UNUSED_;     \
  };                                                                          \
                                                                              \
  ::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_suite_name,          \
                                                    test_name)::test_info_ =  \
      ::testing::internal::MakeAndRegisterTestInfo(...)\

Как следует из названия MakeAndRegisterTestInfo, чьи аргументы я опущено выше для краткости, создает новый экземпляр TestInfo и регистрирует его в одноэлементном объекте UnitTest. Вот цитата из документации googletest :

TEST () и TEST_F () неявно регистрируют свои тесты в googletest. Таким образом, в отличие от многих других C ++ каркасов тестирования, вам не нужно повторно перечислять все определенные тесты, чтобы запустить их.

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

Как я понимаю, я могу написать несколько тестов через макрос TEST(...) в нескольких единицах перевода, и все они будут зарегистрированы. Это правильно? Если это так, то возникает еще один вопрос:

  1. Каково точное определение «блока ссылок»? Я искал этот термин, но полученные результаты не были действительно удовлетворительными.

  2. Как гарантируется, что регистрация произойдет до запуска gtest_main(), который запускает все зарегистрированные тесты (я знаю, что рекомендуется создать свой собственный main())? Вот почему я спрашиваю (см. Этот ответ ):

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

То есть, если исходный файл определяет новый тест с помощью TEST(...), как гарантируется, что переменная-член stati c ::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_suite_name,test_name)::test_info_ инициализируется и тест зарегистрировано до запуска всех тестов?

Чтобы уточнить, я хочу понять, как и почему это работает или какие неправильные представления существуют с моей стороны. Я не ищу плюсы и минусы саморегистрации.

Спасибо за вашу помощь.

Всего наилучшего, Стефан

...