Где разместить источник модульного тестирования и открыть внутренние компоненты?

Я беру на себя проект, который предоставляет компоненты через ATL.

Я вижу две основные области, которые модульный тест должен охватить с помощью этой настройки:

  • Тестирование внутренних компонентов (может быть или не быть выставленным через COM)
  • Тестирование внешних открытых компонентов (также известное как тестирование открытого интерфейса)

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

Из исследования, которое я проводил, кажется, что «нормой» является размещение модульного тестирования в другом подпроекте и наличие основных крючков для решения для модульных тестов для доступа к внутренним компонентам. При такой настройке решение для модульного тестирования будет устанавливать зависимость от тестируемого решения. Является ли это действительно «нормой», или есть много людей, которые размещают свою среду модульного тестирования внутри тестируемого решения (он же модульный тест — это не подпроект, а довольно свободный cpps, которые #ifdef выводятся, если флаг препроцессора не указан)?

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

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

Итак, мои вопросы:

  1. Является ли нормой размещать модульные тесты в отдельном (под)проекте и выставлять компоненты из исходного кода, которые будут тестироваться (через хуки, раскрывая определение класса и т. д.)?
  2. Каков наилучший способ открыть внутренние компоненты из DLL COM?
  3. Будет ли флаг препроцессора, разрешающий __declspec тестированию внутренних компонентов, плохой идеей? Кто-нибудь еще делал это со своими модульными тестами, когда тестируемый элемент обычно не подвергается воздействию во время нормальной работы?

Спасибо за комментарии!


person BabelFish    schedule 12.09.2011    source источник
comment
UnitTest++ тоже очень приятный вариант.   -  person Tom Kerr    schedule 12.09.2011


Ответы (3)


Кто-то из другой команды сказал, что их команда поместила все модульные тесты в отдельные проекты и смогла раскрыть внутренности через статические библиотеки. Для меня это имеет большой смысл, поскольку помогает с модульностью и дает множество других преимуществ. Таким образом, каждое основное соединение кода будет статической библиотекой (не заходя слишком далеко;)) и для каждой статической библиотеки у вас будет отдельное решение для модульного тестирования. Затем ваша основная DLL становится тонкой оболочкой, открывающей необходимые элементы.

Таким образом, решение будет выглядеть так:

Основное решение

  • ProjCommonLib
  • ProjExportsLib
  • ProjImportsLib
  • ProjOtherStuffLib
  • COMDLL-проект
  • UnitTestsFolder
    • ProjCommonLibTests
    • ProjExportsLibTests
    • ProjImportsLibTests
    • ProjOtherStuffLibTests
    • COMDLL-ProjTests

Этот тип настройки позволяет модульным тестам устанавливать зависимости от статической библиотеки и иметь полный доступ к внутренним компонентам без необходимости иметь дело с __declspec. Это кажется намного чище, потому что DLL не имеет никакого снижения производительности из-за модульности, потому что другие библиотеки - это просто статические библиотеки.

Я размещаю это как «ответ», чтобы увидеть, получит ли он какие-либо голоса (иначе говоря, «этот ответ - хороший подход, и я тоже это делаю»). Если это плохое решение, опубликуйте свои ответы.

person BabelFish    schedule 13.09.2011
comment
Хороший подход, я тоже так делаю. Когда я не использую статические библиотеки для хранения кода, в проектах модульного тестирования я добавляю папку $(SolutionDir)$(ProjectName)Debug\obj в дополнительные каталоги библиотек компоновщика. - person John Deters; 16.09.2011
comment
это умно. Я должен буду попробовать это также. - person BabelFish; 17.09.2011

Я бы сказал, что у вас есть свободный выбор, встраивать ли тесты в существующие проекты или создавать новый. Я выбираю первый подход с моими тестами cppunit, поскольку это означает, что вам не нужно создавать новые проекты, но с проектами C# я использую среду модульного тестирования Visual Studio, которая выполняет тяжелую работу по созданию и поддержке отдельного проекта.

У меня никогда не было проблем с тем, что мои блоки #ifdef не перекомпилируются - за этим следит проверка зависимостей (если вы выставили их в отдельной dll, а затем использовали экспорт, это было бы проблемой.

Я использую cppunit уже много лет, а gtest совсем недавно. Я бы сказал, что, хотя gtest очень богат функциями, существует довольно много структурных отличий, которые усложнили бы портирование. Если существующие тесты находятся в cppunit, я бы предложил продолжить их.

Одна вещь, которая мне нравится в cppunit, которая (насколько мне удалось найти) не поддерживается в gtest, заключается в том, что первый сбой в фикстуре приводит к сбою фикстуры, поэтому вы можете сделать это:

CPPUNIT_ASSERT(pointer!=NULL);
CPPUNIT_ASSERT(pointer->deferenceIt());  // if the pointer was null it would have returned above

gtest продолжит работу в этом экземпляре и вылетит во второй строке. Если тесты cppunit полагаются на это поведение, портирование будет еще более трудным.

person the_mandrill    schedule 12.09.2011
comment
Я знал о следующих gtests при возобновлении ошибок, но никогда не думал о недостатках. Ты делаешь доброе дело. - person BabelFish; 13.09.2011
comment
Кроме того, кто-то из другой команды в моей компании упомянул, что переход на gtest может потребовать больше работы, чем он того стоит, а также предложил мне просто остаться с cppunit. Приятно слышать, что другие согласны. - person BabelFish; 13.09.2011
comment
Я согласен. Мне нравится gtest, и я бы подумал об использовании его для новых проектов, но если есть существующий набор тестов cppunit, я бы придерживался его. - person the_mandrill; 13.09.2011
comment
Помните о разнице между ASSERT и EXPECT. При использовании макросов проверки класса ASSERT_ проверка останавливается на первой ошибке. Семейство EXPECT_ продолжит свое существование после несбывшихся ожиданий. - person Kjell Gunnar; 15.11.2011

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

person Tom Kerr    schedule 12.09.2011