Как организовать тестовые приложения C ++ и связанные файлы? - PullRequest
8 голосов
/ 09 октября 2008

Я работаю над библиотекой C ++, которая (помимо прочего) имеет функции для чтения конфигурационных файлов; и я хочу добавить тесты для этого. Пока что это привело меня к созданию множества допустимых и недействительных конфигурационных файлов, каждый из которых содержит всего несколько строк, которые тестируют одну конкретную функциональность. Но теперь это стало очень громоздким, так как существует очень много файлов, а также множество небольших тестовых приложений C ++. Почему-то мне это кажется неправильным :-) так что у вас есть советы, как организовать все эти тесты, тестовые приложения и тестовые данные?

Примечание: публичный API библиотеки сам по себе не легко тестируем (в качестве параметра требуется файл конфигурации). Сочные, подверженные ошибкам методы для фактического чтения и интерпретации значений конфигурации являются частными, поэтому я не вижу способа проверить их напрямую?

Итак: вы бы продолжили тестирование на реальных файлах; и если да, то как бы вы организовали все эти файлы и приложения, чтобы их можно было поддерживать?

Ответы [ 7 ]

5 голосов
/ 09 октября 2008

Возможно, библиотека могла бы принимать какой-либо поток ввода, чтобы вы могли передать строковый объект и избежать всех входных файлов? Или, в зависимости от типа конфигурации, вы можете предоставить функции «get / setAttribute ()» для прямого, публичного изменения параметров. Если это на самом деле не цель дизайна, тогда не берите в голову. Модульные тесты, управляемые данными, в некоторых местах не одобряются, но это определенно лучше, чем ничего! Я бы наверное выложил код так:

  project/
          src/
          tests/
                test1/
                      input/
                test2
                      input/

В каждом каталоге testN у вас есть файл cpp, связанный с файлами конфигурации во входном каталоге.

Затем, при условии, что вы используете тестовую библиотеку в стиле xUnit ( cppunit , googletest , unittest ++ или что-либо еще), вы можете добавить различные testXXX () функции к одному классу, чтобы проверить связанные группы функциональности. Таким образом, вы можете вырезать часть проблемы «много-мало-программ», сгруппировав хотя бы несколько тестов.

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

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

1 голос
/ 09 октября 2008

Часть 1.

Как предположил Ричард, я бы взглянул на тестовую среду CPPUnit . Это определенным образом определит местоположение вашей тестовой среды.

Ваши тесты могут находиться в параллельном каталоге, расположенном на высоком уровне, как в примере с Ричардом, или в подкаталогах или каталогах тестов, параллельных области, которую вы хотите протестировать.

В любом случае, будьте последовательны в структуре каталогов по всему проекту! Особенно в случае, если тесты содержатся в одном каталоге высокого уровня.

Нет ничего хуже, чем поддерживать мысленное отображение исходного кода в таком месте, как:

/project/src/component_a/piece_2/this_bit

и иметь тест (ы), расположенные где-нибудь, такие как:

/project/test/the_first_components/connection_tests/test_a

И я работал над проектами, где кто-то делал это!

Какая трата циклов мокрой посуды! 8-O Поговорим о нарушении Александром концепции качества без имени.

Гораздо лучше, если ваши тесты будут последовательно расположены в w.r.t. расположение тестируемого исходного кода:

/project/test/component_a/piece_2/this_bit/test_a

часть 2

Что касается конфигурационных файлов API, сделайте локальные копии эталонного конфига в каждой локальной тестовой области как часть тестовой среды. Настройка, которая запускается перед выполнением теста. Не разбрасывайте копии конфигурации (или данных) по всему дереву тестов.

НТН.

ура

Rob

Кстати, очень рад, что вы спрашиваете об этом сейчас, когда настраиваете!

0 голосов
/ 13 апреля 2009

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

Так что да, пойдите для тестирования юнитов, но не используйте CppUnit.

0 голосов
/ 09 октября 2008

Предполагая, что у вас есть контроль над дизайном библиотеки, я ожидал бы, что вы сможете провести рефакторинг так, чтобы отделить внимание к фактическому чтению файла от интерпретации его как файла конфигурации:

  1. класс FileReader читает файл и создает входной поток,
  2. класс ConfigFileInterpreter проверяет / интерпретирует и т. Д. Содержимое входного потока

Теперь для тестирования FileReader вам понадобится очень небольшое количество реальных файлов (пустых, двоичных, простого текста и т. Д.), А для ConfigFileInterpreter вы должны использовать заглушку класса FileReader, которая возвращает поток ввода для чтения. Теперь вы можете подготовить все различные конфигурации в виде строк, и вам не нужно будет читать столько файлов.

0 голосов
/ 09 октября 2008

Для таких вещей у меня всегда есть небольшой служебный класс, который загружает конфигурацию в буфер памяти, и оттуда она подается в фактически конфигурационный класс. Это означает, что реальный источник не имеет значения - это может быть файл или БД. Для модульного теста это жестко запрограммированный тест в std :: string, который затем передается в класс для тестирования. Вы можете легко смоделировать данные currup! Pte3d для тестирования путей сбоев.

Я использую UnitTest ++ . У меня есть тесты как часть дерева src. Итак:

solution/project1/src <-- source code
solution/project1/src/tests <-- unit test code 
solution/project2/src <-- source code
solution/project2/src/tests <-- unit test code 
0 голосов
/ 09 октября 2008

Я согласен с тем, что сказал @Richard Quirk, но вы также можете сделать свой класс тестового набора другом класса, который тестируете, и протестировать его частные функции.

0 голосов
/ 09 октября 2008

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...