Ответ 1
Я решил проблему к моему удовлетворению! Я буду двигаться полностью сейчас. Это в основном просит учебник. Есть много решений, которые должны быть приняты, надеюсь, логически, чтобы Google Test прекрасно подходил для автоинструментов. Поэтому я заранее прошу прощения за длинный ответ, но все детали должны быть там.
Первая проблема
Чтобы понять ответ, вопрос нужно немного перефразировать. Мы собираем Google Test как библиотеку, на которую будет ссылаться наш тестовый код. Библиотека не будет установлена. Вопрос, который мы хотим задать,
"Как настроить автоинструменты для компиляции Google Test в виде библиотеки, с которой наш тестовый код может ссылаться?"
Для этого нам нужно скачать Google Test и поместить его в наш проект. Я использую Github, поэтому я делаю это, добавляя подмодуль в корневой путь моего проекта:
$ git submodule add [email protected]:google/googletest.git
$ git submodule init
$ git submodule update
Это загружает googletest в мой корень моего проекта:
/:
Makefile.am
configure.ac
src/:
(files for my project)
tests/:
(test files)
googletest/:
googletest/:
include/:
(headers, etc., to be included)
gtest/:
gtest.h
m4/:
(directory for m4 scripts and things)
src/:
(source files for Google Test)
Мне нужно собрать в соответствии с инструкциями. Я хочу, чтобы библиотека Google Test создавалась только после запуска make check
, поэтому я буду использовать check_LTLIBRARIES. Я добавляю следующее в мои тесты Makefile.am в /tests:
check_LTLIBRARIES = libgtest.la
libgtest_la_SOURCES = ../googletest/googletest/src/gtest-all.cc
libgtest_la_CPPFLAGS = -I$(top_srcdir)/googletest/googletest/include -I$(top_srcdir)/googletest/googletest
libgtest_la_LDFLAGS = -pthread
Это требует, чтобы subdir-объекты были включены в configure.ac. Это достигается путем добавления его в строку AM_INIT_AUTOMAKE. Мне также нужно включить make файл в AC_CONFIG_FILES. Мы также хотим использовать libtool, потому что мы компилируем библиотечные файлы (я объясню, почему и как это работает через мгновение). Чтобы использовать libtool, мы добавляем AM_PROG_AR, LT_INIT. Мы хотим, чтобы autoreconf установил макросы m4 в /m4, а затем мы хотим, чтобы automake нашла их, поэтому нам нужен AC_CONFIG_MACRO_DIRS. В моем файле configure.ac обновлены строки:
AM_INIT_AUTOMAKE([-Wall -Werror subdir-objects])
...
AM_PROG_AR
LT_INIT
AC_CONFIG_MACRO_DIRS([m4])
...
AC_CONFIG_FILES([Makefile
src/Makefile
tests/Makefile
])
Мне также нужно включить подкаталог и строку, указывающую на макросы, в каталог макросов /m4 в моем /Makefile.am:
ACLOCAL_AMFLAGS = -I m4
SUBDIRS = src tests
Что это сделало? Libtool был включен с AM_PROG_AR и LT_INIT. Check_LTLIBRARIES означает, что мы будем использовать libtool для создания так называемой удобной библиотеки libgtest.la. С включенными объектами subdir он будет встроен в каталог /tests, но не установлен. Это означает, что всякий раз, когда мы хотим обновить наши тесты, нам не нужно перекомпилировать библиотеку Google Test libgtest.la. Это сэкономит время при тестировании и поможет нам выполнять итерации быстрее. Затем мы захотим скомпилировать наши модульные тесты позже по мере их обновления. Библиотека будет скомпилирована только после запуска make check
, что make check
сэкономить время, не компилируя ее, если все, что мы хотим сделать, - это make
или make install
.
Вторая проблема
Теперь необходимо уточнить вторую проблему: как вы (а) создаете тест (б), который связан с библиотеками Google Test и, таким образом, использует их? Вопросы как бы переплетены, поэтому мы отвечаем на них сразу.
Создание теста - это всего лишь вопрос помещения следующего кода в файл gtest.cpp
расположенный по адресу /tests/gtest.cpp
:
#include "gtest/gtest.h" // we will add the path to C preprocessor later
TEST(CategoryTest, SpecificTest)
{
ASSERT_EQ(0, 0);
}
int main(int argc, char **argv)
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
Это запускает только простой тест 0 = 0. Чтобы создать тест для вашей библиотеки, вам нужно прочитать учебник. Вы заметите, что нам не нужен заголовок для этого (пока). Мы ссылаемся на файл "gtest/gtest.h", поэтому нам нужно убедиться, что мы скажем automake включить каталог с gtest/gtest.h
.
Далее нам нужно сообщить automake, что мы хотим построить тест и запустить его. Тест собирается встроить в исполняемый файл, который мы не хотим устанавливать. Затем automake собирается запустить этот исполняемый файл. Он сообщит, говорит ли этот исполняемый файл, что тесты пройдены или не пройдены.
Automake делает это, просматривая в make файле переменную check_PROGRAMS. Это программы, которые он будет компилировать, но он не обязательно будет их запускать. Поэтому мы добавляем в /tests/Makefile.am
:
check_PROGRAMS = gtest
gtest_SOURCES = gtest.cpp
gtest_LDADD = libgtest.la
gtest_LDFLAGS = -pthread
gtest_CPPFLAGS = -I$(top_srcdir)/googletest/googletest/include -I$(top_srcdir)/googletest/googletest -pthread
Gtest_SOURCES находит файл /tests/gtest.cpp
и компилирует его. gtest_LDADD ссылается на libgtest.la, которая будет скомпилирована в каталог /tests. Google хочет, чтобы мы использовали строку gtest_LDFLAGS для включения pthreads. Наконец, нам нужно указать место, где будет найден заголовок "gtest/gtest.h", и это строка gtest_CPPFLAGS. Google также хочет, чтобы мы /googletest/googletest
местоположение /googletest/googletest
и /googletest/googletest
Положение вещей: библиотека Test Google libgtest.la
откомпилироваться make
в каталоге/тесты, но не может быть установлено. Двоичный gtest будет скомпилирован только с make check
, но не будет установлен.
Далее мы хотим сказать automake, что он на самом деле должен запускать скомпилированный двоичный gtest и сообщать об ошибках. Это достигается добавлением строки в /tests/Makefile.am
:
TESTS = gtest
Финальный файл /tests/Makefile.am выглядит следующим образом:
check_LTLIBRARIES = libgtest.la
libgtest_la_SOURCES = ../googletest/googletest/src/gtest-all.cc
libgtest_la_CPPFLAGS = -I$(top_srcdir)/googletest/googletest/include -I$(top_srcdir)/googletest/googletest -pthread
check_PROGRAMS = gtest demo
gtest_SOURCES = gtest.cpp ../src/fields.cpp
gtest_LDADD = libgtest.la
gtest_LDFLAGS = -pthread
gtest_CPPFLAGS = -I$(top_srcdir)/googletest/googletest/include -I$(top_srcdir)/src
demo_SOURCES = demo.cpp ../src/fields.cpp
demo_CPPFLAGS = -I$(top_srcdir)/src
TESTS = gtest
Теперь autoreconf -fiv
(обратите внимание на любые ошибки и, надеюсь, исправьте их) из /
и make check
и вы должны получить тест, который выполняется:
build(dev)$ make check
Making check in tests
/Applications/Xcode.app/Contents/Developer/usr/bin/make gtest
make[2]: 'gtest' is up to date.
/Applications/Xcode.app/Contents/Developer/usr/bin/make check-TESTS
PASS: gtest
============================================================================
Testsuite summary for IonMotion 0.0.1
============================================================================
# TOTAL: 1
# PASS: 1
# SKIP: 0
# XFAIL: 0
# FAIL: 0
# XPASS: 0
# ERROR: 0
============================================================================