Избегание зависимостей увеличивает количество проектов в моем решении VS
Я работаю в C++; Я новичок в Visual Studio и все еще пытаюсь понять, как эффективно его использовать.
Моя проблема в том, что у меня есть небольшой, не сложный проект, но я все больше и больше добавляю Проекты в Решение, и управление ими становится громоздким и разочаровывающим.
- Проект зависит от устройства, поэтому я определил
DeviceInterface
и у меня естьFakeDevice
а такжеRealDevice
реализация интерфейса. - Мой основной проект
Foo
Я написал это статическая библиотека, определенная с помощьюDeviceInterface
,Foo
библиотека не знакома ни с одной из конкретных реализаций. - У меня есть несколько тестовых исполняемых файлов, давайте назовем их
TestExe1
,TestExe2
, и так далее. Эти тесты имеют общий код,FooTestUtils
, - С помощью
RealDevice
требует некоторой инициализации и демонтажа до и после использования. Это не относится к реализации интерфейса; клиентский код естественно несет ответственность за это.- Это означает, что исполняемый тест может работать только с использованием
RealDevice
если я положу в сильной зависимости отRealDevice
и ресурсы init/teardown. Который мне не нужен или не нужен для тестов с использованием Fake. - Мое настоящее решение состоит в том, чтобы разделить исполняемые файлы теста - один для
FakeDevice
другое дляRealDevice
который выполняет инициализацию, а затем отправляет и вызывает тот же тестовый код.
- Это означает, что исполняемый тест может работать только с использованием
TL; DR: базовая библиотека
Foo
, в зависимости отDeviceInterface
, который имеет несколько реализаций. Несколько тестовых исполняемых файлов, большинство из которых могут работать с любой реализациейDeviceInterface
, но одна из этих реализаций требует дополнительной настройки в клиентском коде.
Это кажется мне разумным уровнем сложности. Но это приводит к такому большому количеству проектов:
- Статические библиотеки:
Foo
RealDevice
реализацияFooTestUtils
(примечание: включает в себяFakeDevice
реализация)gtest
(используется для некоторых испытаний)- Библиотека из другого решения, необходимого для
RealDevice
использование
- исполняемые:
- 2
TestExe$i
проекты для каждого исполняемого файла теста, который я хочу
- 2
В среде *nix, к которой я привык, я бы разделил код на разумное дерево каталогов, и многие из этих "проектов" были бы просто одним объектным файлом или одним.cpp с некоторым клиентским кодом для основная логика.
Это разумное количество проектов для решения этой области? Мне кажется, это очень много. Часто я нахожу некоторые настройки, которые мне нужно изменить в полдюжине разных проектов, и мне становится все труднее ориентироваться. В настоящее время этим все еще можно управлять, но я не вижу, как это останется работоспособным, поскольку я приступаю к более крупным и более сложным проектам. Могу ли я организовать это лучше?
(Опять же, я новичок в Visual Studio, поэтому проблема может заключаться в том, что я не знаю, как управлять несколькими связанными проектами, а не просто количеством самих проектов.)
1 ответ
Хотя то, что вы делаете, довольно стандартно - и для небольшого проекта, который вы описываете, ваше решение кажется совершенно стандартным. Однако Visual Studio предоставляет некоторые способы минимизировать влияние этих проблем для опытных разработчиков:
build-конфигурации и листы свойств:
Короче, зачем нужен проект для fakeDevice и RealDevice?
Создайте проект для "Устройства", который в зависимости от выбранной конфигурации создает источники fakeDevice или RealDevice. Это также позволяет вам запускать ваш проект в "тестовой" конфигурации и автоматически загружать fakeDevice, при этом выбор "Debug" или "release" предоставит RealDevice.
Обратите внимание, что оба проекта, а также все решение могут иметь конфигурации независимо друг от друга, что позволяет быстро создавать пакетные конфигурации конкретных конфигураций.
пример из реального мира
Моя компания выпускает плагин для Adobe-Illustrator, существует семь поддерживаемых версий Adobe (каждая со своим собственным SDK), а также 32- и 64-битные варианты, а также дальнейшие сборки отладки и выпуска (и снова удваиваем это до 28+ вариантов, так как есть). две почти идентичные фирменные версии плагина). Мое решение заключается в следующем: Plugin-Solution
[Debug][Release] / (win32/x64)
Plugin
[Debug AI4][Debug AI5][Debug AI6][Debug AI7][Release AI4]
[Release AI5][Release AI6][Release AI7] / (win32/x86)
{libraries with similar setups...}
В своей повседневной работе я просто "нажимаю на воспроизведение" в конфигурации отладки, однако, когда приходит время выпуска (или требуется тестирование конкретной версии), я "Пакетная сборка" - правильная комбинация проектов для отладки или упаковки.
Это фактически означает, что, хотя у меня (включая общие библиотеки) около 30 двоичных файлов, создаваемых для выпуска, в моем решении было только три проекта.
тестирование исполняемых файлов
Что касается исполняемых модулей модульного тестирования, я бы порекомендовал создать отдельное решение для них - Visual Studio не имеет проблем с несколькими открытыми одновременно решениями - у меня, однако, есть один совет
Создайте отдельное решение и создайте в нем все свои модульные тесты, затем в основное решение добавьте простой проект "тесты", в его событии после сборки запустите сценарий powershell/batch.
Затем этот сценарий может вызвать набор инструментов MSVCC для решения модульных тестов, а затем запустить тесты, сопоставляя результаты (если вы в правильной конфигурации). Это позволит вам создавать / запускать свои тесты из одного проекта, даже если вам нужно нажать alt+tab для создания нового модульного теста.
Персональный (самоуверенный) совет
Разработанный в системах 'Nix, Windows и Apple, вот хороший метафора макета. "Nix ожидает, что вы создадите свои собственные make-файлы и макет папки, он предполагает, что вы точно знаете, что делаете (в терминале!), И макет станет вашей игрушкой (с достаточным количеством скриптов).
Студия Windows/Visual предназначена для пользователей любого уровня, восьмилетних обучающих программ на Visual Basic или опытного разработчика C++, создающего аппаратные драйверы. Как таковой, интерфейс разработан так, чтобы быть очень расширяемым - "проекты" в "решениях" являются основной идеей (многие начинающие не понимают, что у вас может быть несколько проектов. Однако, если вам нужно больше вариантов, есть один способ сделать это: Что касается MS (в данном случае, конфигураций и таблиц свойств) - если вы пишете make-файл или создаете макет, вы "делаете это неправильно" (в любом случае, на взгляд Microsoft).
Если вы взглянете на то, как за последние несколько лет возникли проблемы с встраиванием в экосистемы окон, вы, как правило, поймете проблему. На 'nix иметь несколько десятков разделяемых библиотек из пакета apt/yum, установленного как зависимость, это нормально! Однако Windows (кажется, что) с несколькими DLL - плохая идея. Там нет менеджера пакетов, так что либо положитесь на.Net, либо поставьте один пакет надстройки вместе с вашим продуктом. (именно поэтому я предпочитаю статические ссылки на окнах).
РЕДАКТИРОВАТЬ:
Когда у вас есть несколько конфигураций, выбор того, что источники делают и не строят для каждого, может быть сделан двумя способами.
один: вручную
Щелкните правой кнопкой мыши по любому исходному файлу в обозревателе решений и выберите свойства. В разделе "Общие" вы можете выбрать "Исключено из сборки" (это работает, если вы выбираете группу и также щелкаете правой кнопкой мыши).
два: магия XML
Если вы откроете файл vcxproj, у вас получится хорошо сформированный макет XML-файла! Хотя обработка точных условий управления включениями, исключениями и даже другими параметрами выходит за рамки этого поста, основные подробности можно найти в этом хорошо сформулированном вопросе о переполнении стека, а также в документации по инструментальной цепочке MDSN.