Модульное тестирование приложений пользовательского интерфейса MFC?

StackOverflow https://stackoverflow.com/questions/107591

Вопрос

Как провести модульное тестирование большого приложения пользовательского интерфейса MFC?

У нас есть несколько крупных приложений MFC, которые находятся в разработке уже много лет. Мы используем некоторые стандартные автоматизированные инструменты контроля качества для запуска базовых сценариев для проверки основных функций, открытия файлов и т. д.Они управляются группой контроля качества после ежедневной сборки.

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

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

Среда: C++/C/FORTRAN, MSVC 2005, Intel FORTRAN 9.1, Windows XP/Vista x86 и x64.

Это было полезно?

Решение

Это зависит от структуры приложения.Если логика и код графического интерфейса разделены (MVC), тестирование логики упрощается.Взгляните на Майкла Фезерса «Скромное диалоговое окно» (PDF).

РЕДАКТИРОВАТЬ:Если подумать:Вам следует очень тщательно провести рефакторинг, если приложение не структурировано таким образом.Другого метода проверки логики не существует.Скрипты, имитирующие щелчки, — это всего лишь поверхностное исследование.

На самом деле это довольно просто:

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

  1. Выполните рефакторинг так, чтобы в списке отображался отдельный список с элементами.Элементы хранятся в списке и не извлекаются из источника, откуда поступают ваши данные.Код, который составляет список элементов списка, знает только о новом списке.
  2. Затем вы создаете новый объект контроллера, который будет содержать логический код.Метод, обрабатывающий нажатие кнопки, вызывает только mycontroller->ButtonWasClicked().Он не знает ни о списке, ни о чем-то еще.
  3. MyController::ButtonWasClicked() выполняет то, что необходимо для предполагаемой логики, подготавливает список элементов и сообщает элементу управления об обновлении.Чтобы это работало, вам необходимо разделить контроллер и элемент управления, создав интерфейс (чистый виртуальный класс) для элемента управления.Контроллер знает только объект этого типа, но не элемент управления.

Вот и все.Контроллер содержит логический код и знает управление только через интерфейс.Теперь вы можете написать обычный модульный тест для MyController::ButtonWasClicked(), имитируя элемент управления.Если вы понятия не имеете, о чем я говорю, прочитайте статью Майклса.Дважды.И снова после этого.
(Примечание для себя:надо научиться не болтать так много)

Другие советы

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

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

  • Сначала вам понадобится поддержка руководства, чтобы новые исправления заняли немного больше времени.Убедитесь, что все понимают, почему.
  • Далее купите копию Книга ВЕЛК.Прочтите его от корки до корки, если у вас есть время ИЛИ, если у вас затруднения, просканируйте указатель, чтобы найти симптом, который проявляет ваше приложение.Эта книга содержит много полезных советов и является именно тем, что вам нужно, когда вы пытаетесь протестировать существующий код.alt text
  • Затем для каждого нового исправления/изменения потратьте некоторое время и поймите область, над которой вы собираетесь работать.Напишите несколько тестов в выбранном вами варианте xUnit (доступном бесплатно) для проверки текущего поведения.
  • Убедитесь, что все тесты пройдены.Напишите новый тест, который проверяет необходимое поведение или ошибку.
  • Напишите код, чтобы пройти этот последний тест.
  • Безжалостно проводите рефакторинг в тестируемой области, чтобы улучшить дизайн.
  • Повторите эти действия для каждого нового изменения, которое вам придется внести в систему.Никаких исключений из этого правила.
  • Сейчас земля обетованная:Вскоре начнут появляться постоянно растущие островки хорошо протестированного кода.Все больше и больше кода будет подпадать под набор автоматизированных тестов, и вносить изменения станет все проще.И это потому, что медленно и верно лежащий в основе проект становится более тестируемым.

Самый простой выход был в моем предыдущем ответе.Это трудный, но правильный выход.

Я понимаю, что это устаревший вопрос, но для тех из нас, кто все еще работает с MFC, платформа модульного тестирования Microsoft C++ в VS2012 работает хорошо.

Общая процедура:

  1. Скомпилируйте проект MFC как статическую библиотеку.
  2. Добавьте в свое решение новый проект собственного модульного тестирования.
  3. В тестовом проекте добавьте свой проект MFC в качестве ссылки.
  4. В свойствах конфигурации тестового проекта добавьте каталоги Include для файлов заголовков.
  5. В компоновщике параметры ввода добавляют ваш MFC.lib;nafxcwd.lib;libcmtd.lib;
  6. В разделе «Игнорировать определенные библиотеки по умолчанию» добавьте nafxcwd.lib;libcmtd.lib;
  7. В разделе «Общие» добавьте местоположение экспортированного файла библиотеки MFC.

А https://stackoverflow.com/questions/1146338/error-lnk2005-new-and-delete-already-define-in-libcmtd-libnew-obj содержит хорошее описание того, зачем вам нужны nafxcwd.lib и libcmtd.lib.

Еще одна важная вещь, на которую следует обратить внимание в устаревших проектах.В общих свойствах конфигурации убедитесь, что оба проекта используют один и тот же «набор символов».Если ваш MFC использует многобайтовый набор символов, вам также понадобится MS Test.

Хотя это и не идеально, лучшее, что я нашел для этого, — это AutoIt. http://www.autoitscript.com/autoit3

«AutoIt v3 — это бесплатный язык сценариев, подобный BASIC, предназначенный для автоматизации графического интерфейса Windows и общих сценариев.Он использует комбинацию симулированных нажатий клавиш, движений мыши и манипулирования окнами/элементами управления для автоматизации задач способом, который невозможен или надежен с другими языками (например,VBScript и SendKeys).AutoIt также очень маленький, автономный и сразу же работает на всех версиях Windows, не требуя раздражающих «времен выполнения»!»

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

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

Я считаю, что при разработке нового приложения я бы настаивал на последовательном способе подачи сигнала «ГОТОВО».Это было бы полезно как для пользователей-людей, так и для тестовых сценариев!Это может быть проблемой для устаревшего приложения, но, возможно, вы сможете внедрить его в проблемные места и постепенно распространить на все приложение по мере продолжения обслуживания.

Хотя он не может обрабатывать часть пользовательского интерфейса, я тестирую код MFC с помощью библиотеки Boost Test.Существует статья Code Project о начале работы:

Проектирование надежных объектов с помощью Boost

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

  • Мы используем Рациональный робот для проведения дымовых тестов и тому подобного.
  • Другой подход, который имел некоторый успех, заключается в создании небольшого языка, специфичного для продукта, и тесты сценариев которые используют VBScript и некоторую шпионскую магию управления.Превратите обычные действия в команды.напримерOpenDatabase будет командой, которая, в свою очередь, будет вставлять необходимые блоки сценария, чтобы щелкнуть Главное меню > Файл > «Открыть...».Затем вы создаете таблицы Excel, которые представляют собой серию таких команд.Эти команды также могут принимать параметры.Что-то вроде FIT Test..но больше работы.Как только вы определите большинство общих команд и подготовите сценарии.Это выбор и сборка сценариев (помеченных CommandID) для написания новых тестов.Специалист по тестированию анализирует эти листы Excel, объединяет все небольшие блоки сценариев в тестовый сценарий и запускает его.

    1. OpenDatabase "C: ests\MyDB"
    2. OpenDialog «Добавить модель»
    3. ДобавитьМодель "M0001", "МояМодель", 2.5, 100
    4. Нажмите ОК
    5. Сохранить базу данных

ХТХ

На самом деле мы использовали Rational Team Test, затем Robot, но в недавних обсуждениях с Rational мы обнаружили, что у них нет планов поддерживать собственные приложения x64, уделяя больше внимания .NET, поэтому мы решили перейти на инструменты автоматического контроля качества.Это здорово, но затраты на лицензирование не позволяют нам включить эту функцию для всех разработчиков.

Все наши приложения поддерживают COM API для написания сценариев, которые мы тестируем с помощью VB, но при этом тестируется API, а не приложение как таковое.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top