Google test - организация проекта
От: DTF  
Дата: 20.01.17 00:50
Оценка:
Доброй ночи.

Есть у меня учебная программка, в которой я хочу использовать Google tests.

Программа состоит из бинарника и статической библиотеки. Написана в MSVS 2015.
Соответственно, бинарник — это один проект, а библиотека — другой. Оба в одном солюшене.
Хочу сделать юнит-тесты библиотеки.


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


Но вот тут начинаются проблемы.

Если в той единице трансляции, где описаны тесты, нет какого-либо функционала, который используется программой, то линкер эту единицу трансляции проигнорирует.
Соответственно, нужно либо дописывать в эти файлы какие-то левые функции, либо include'ить их в обычный cpp-файл, либо изначально писать тесты в файлах с кодом.

Все эти варианты кажутся (лично мне) неудобными.



А как делаете вы в своих проектах?
gtest msvs
Re: Google test - организация проекта
От: uzhas Ниоткуда  
Дата: 20.01.17 07:49
Оценка:
Здравствуйте, DTF, Вы писали:

DTF>Встает вопрос, куда эти тесты впихнуть.

DTF>Кажется, что наиболее удобный вариант — сделать в этом же солюшене новый тестовый бинарник для прогона тестов, сделать его зависимым от библиотеки.
DTF>Сами тесты вынести в отдельный файл или файлы.
звучит логично

DTF>Но вот тут начинаются проблемы.

DTF>Если в той единице трансляции, где описаны тесты, нет какого-либо функционала, который используется программой, то линкер эту единицу трансляции проигнорирует.

как это нет функционала? приведите пример
как вы определили, что линкер выкинул единицу трансляции?
Re[2]: Google test - организация проекта
От: DTF  
Дата: 20.01.17 12:04
Оценка:
U>как это нет функционала? приведите пример

Ну например когда в файле только тест и больше ничего:
#include <gtest/gtest.h>

TEST(TestCase1, Test1) {
   EXPECT_EQ(2 * 2, 4);
}



U>как вы определили, что линкер выкинул единицу трансляции?

1. Если в библиотеке есть вышеприведенный файл, то тест не выполняется.
Однако, если точно такой же тест написать в .cpp-файле, где есть функционал, то он выполнится

2. Это поведение описано в документации

When Visual C++ linker sees that nothing in the library is referenced from other places it throws the library out



Там же предлагается и решение проблемы — сделать ничего не делающую функцию и вызывать ее из программы-теста.
Но я решил спросить у сообщества, мб оно придумало более элегантные варианты?
Re[3]: Google test - организация проекта
От: uzhas Ниоткуда  
Дата: 20.01.17 12:08
Оценка:
Здравствуйте, DTF, Вы писали:

U>>как вы определили, что линкер выкинул единицу трансляции?

DTF>1. Если в библиотеке есть вышеприведенный файл, то тест не выполняется.

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

DTF>2. Это поведение описано в документации

DTF>

When Visual C++ linker sees that nothing in the library is referenced from other places it throws the library out


это верно для библиотек. тесты не надо размещать в библиотеке
Re[3]: Google test - организация проекта
От: VTT http://vtt.to
Дата: 20.01.17 12:19
Оценка:
Здравствуйте, DTF, Вы писали:

U>>как это нет функционала? приведите пример


DTF>Ну например когда в файле только тест и больше ничего:

DTF>
DTF>#include <gtest/gtest.h>

DTF>TEST(TestCase1, Test1) {
DTF>   EXPECT_EQ(2 * 2, 4);
DTF>}

DTF>



U>>как вы определили, что линкер выкинул единицу трансляции?

DTF>1. Если в библиотеке есть вышеприведенный файл, то тест не выполняется.
DTF>Однако, если точно такой же тест написать в .cpp-файле, где есть функционал, то он выполнится

DTF>2. Это поведение описано в документации

DTF>

When Visual C++ linker sees that nothing in the library is referenced from other places it throws the library out



DTF>Там же предлагается и решение проблемы — сделать ничего не делающую функцию и вызывать ее из программы-теста.

DTF>Но я решил спросить у сообщества, мб оно придумало более элегантные варианты?

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

Что касается организации тестов, то я храню тестовые файлы рядом с тестируемыми, с таким же именем, но с расширением .test.hpp
Но используются они только в проекте с тестами.

Да, и gtest в студии на самом деле не особо нужен, ибо есть CppUnitTestFramework из коробки.
Говорить дальше не было нужды. Как и все космонавты, капитан Нортон не испытывал особого доверия к явлениям, внешне слишком заманчивым.
Re[4]: Google test - организация проекта
От: DTF  
Дата: 20.01.17 12:41
Оценка:
U>тесты должны быть не в библиотеке, а в отдельном проекте для тестов (вы же сами об этом написали в первом посте). тогда и линкер ничего не выкинет
Ну, я имел в виду, что у меня отдельный тестовый бинарник, который инициализирует тесты (т.е. выполняет testing::InitGoogleTest). А сами тесты я хотел хранить рядом с тестируемым кодом и в том же проекте.

U>это верно для библиотек. тесты не надо размещать в библиотеке

А это не будет неудобным?

Допустим, у нас в бибилиотеке есть некоторый логически выделенный кусок, который мы хотим тестировать.
Его файлы складываются в отдельную папку.
Т.е. файлы хранятся вот так:
ThePiece/
|
|- test.cpp
|
|- the_piece.cpp
|
\- the_piece.h


Если мы включим the_piece.cpp и the_piece.h в один проект, а test.cpp — в другой, то если вдруг захотим потом переместить папку ThePiece в другое место, то придется исправлять два проектных файла.
Re[5]: Google test - организация проекта
От: uzhas Ниоткуда  
Дата: 20.01.17 12:54
Оценка:
Здравствуйте, DTF, Вы писали:

DTF>А это не будет неудобным?


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

DTF>Если мы включим the_piece.cpp и the_piece.h в один проект, а test.cpp — в другой, то если вдруг захотим потом переместить папку ThePiece в другое место, то придется исправлять два проектных файла.


двигать папки — это всегда больно
я могу посоветовать такое расположение:

LibraryA
--> A.cpp
--> A.h
--> B.cpp
--> B.h
--> Alib.vcxproj
--> Tests
----> TestGroup1.cpp
----> TestGroup2.cpp
----> TestGroup3.cpp
----> AlibTestsExe.vcxproj

Отредактировано 20.01.2017 14:21 uzhas . Предыдущая версия . Еще …
Отредактировано 20.01.2017 13:40 uzhas . Предыдущая версия .
Отредактировано 20.01.2017 12:55 uzhas . Предыдущая версия .
Re[6]: Google test - организация проекта
От: DTF  
Дата: 20.01.17 14:10
Оценка:
Попробую, спасибо.
Re: Google test - организация проекта
От: DTF  
Дата: 20.01.17 14:18
Оценка:
И еще вопрос, вдогонку.

Пусть есть, к примеру, класс, который мы хотим оттестировать.
Он объявлен в myclass.h и определен, соответственно, в myclass.cpp.

Для своей работы класс использует функции-хелперы. Мы их не хотим показывать клиентам, поэтому их объявления в myclass.h не пишем.

Но тестировать эти функции хотим.
Как люди поступают в таких случаях? Пишут тесты в файлах исходников? Или заводят отдельные .h-файлы, которые используются только в тестовом проекте?
Re[2]: Google test - организация проекта
От: uzhas Ниоткуда  
Дата: 20.01.17 16:10
Оценка:
Здравствуйте, DTF, Вы писали:

DTF>Для своей работы класс использует функции-хелперы. Мы их не хотим показывать клиентам, поэтому их объявления в myclass.h не пишем.

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

DTF>Но тестировать эти функции хотим.

все тесты — в проекте с тестами
Re[5]: Google test - организация проекта
От: Vain Россия google.ru
Дата: 21.01.17 13:36
Оценка:
Здравствуйте, DTF, Вы писали:

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

DTF>Ну, я имел в виду, что у меня отдельный тестовый бинарник, который инициализирует тесты (т.е. выполняет testing::InitGoogleTest). А сами тесты я хотел хранить рядом с тестируемым кодом и в том же проекте.
Ну так у вас оно либо будет всё тупо пересобираться из-за изменения одного теста (если один хедер), либо будет избыточность (каждому cpp по хедеру). Зачем такое вообще надо? Проще сразу в cpp писать.
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re: Google test - организация проекта
От: push  
Дата: 22.01.17 11:53
Оценка:
Короче, используй стандартную архитектуру и не мудри:
1) Весь свой код вынеси в библиотеки (иначе код с экзешника ты толком не протестируешь при сложном проекте).
2) Добавь минимальный .exe-проект "запускатор", который берёт класс Application с твоей либы и стартует приложение. (не забудь, конечно, прилинковать все либы)
3) Добавить в солюшн отдельный консольный проект для тестов.
3) К тестовому проекту прилинкуй используемые библиотеки, а .h файлы включаешь напрямую из конкретных библиотек (ничего дублировать не надо!).

Как организовать сам тестовый солюшн:
1) Каталог/и для фикстур
2) Каталог/и для тестов
3) Каталог для тестовых утилит.
Re[6]: Google test - организация проекта
От: SeVlaT  
Дата: 23.01.17 15:10
Оценка:
Здравствуйте, uzhas, Вы писали:

U>

U>LibraryA
-->> .....
-->> Alib.vcxproj
-->> Tests
---->> .....
---->> AlibTestsExe.vcxproj


При таком подходе есть один недостаток.
Большинство настроек тест-проекта должно совпадать с настройками основного проекта. Например, список include-директорий — иначе тест-проект просто не найдет нужных файлов.
Чтобы не прописывать руками одинаковые настройки в оба проекта, можно сделать их разделяемыми. То есть, вынести настройки во внешний файл, и использовать его из обоих проектов.
В MSVS это можно сделать при помощи PropertySheet (файлы с расширением *.props). Действительно, удобно. Но в проектах MSVS есть правило: относительные пути почти всегда разрешаются относительно директории, где лежит *.vcxproj файл. Отсюда следует, что файлы основного и тестового проектов должны находиться в одном каталоге. (Это касается только файлов *.vcxproj, остальные файлы c/cpp/h/rc/props/etc могут быть где угодно.)
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.