Как я могу тестировать GUI?

155

Расчеты в моем коде хорошо проверены, но поскольку кода GUI так много, общий охват кода ниже, чем хотелось бы. Есть ли какие-либо рекомендации по модульному тестированию кода GUI? Это вообще имеет смысл?

Например, в моем приложении есть графики. Я не смог понять, как автоматизировать тестирование графиков. Для проверки правильности графика требуется человеческий глаз AFAIK.

(Я использую Java Swing)

Стив Маклеод
источник
1
Мартина Фаулера есть отличная статья о различных архитектурах графического интерфейса ( martinfowler.com/eaaDev/uiArchs.html ). Это описывает компромиссы архитектуры GUI с точки зрения модульного тестирования.
Роман Хван
1
В настоящее время этот вопрос лучше задать на сайте programmers.stackexchange.com (и, возможно, он не относится к теме переполнения стека, поскольку он слишком широкий), но старые вопросы перенести нельзя. Вопрос о том, принадлежит ли он здесь, проблема остается интересной и сложной.
Марк Эмери
1
Было бы здорово иметь пример с некоторым фрагментом кода GUI и JUnit.
Витольд Качурба
1
Я бы сказал, просто расслабься и не беспокойся. Усилия, введенные в модульные тесты, не всегда оказываются чистыми.
Codeulike
Старый вопрос все еще, вы можете проверить поток в GUI, используя Jubula
Abi

Ответы:

68

Такие конструкции, как MVP и MVC, обычно пытаются абстрагировать как можно больше логики от реального графического интерфейса. Одна очень популярная статья об этом - «Диалоговое окно смирения» Майкла Фезерса. Лично у меня был неоднозначный опыт в попытке вывести логику из пользовательского интерфейса - иногда это работало очень хорошо, а иногда это было больше проблем, чем оно того стоило. Хотя это несколько выходит за рамки моей компетенции.

Джон Скит
источник
??? «иногда это работало очень хорошо, а иногда это было больше проблем, чем оно того стоило» Очень странно, потому что большинство новых языков, как правило, ориентированы на MVC ... это логика вне графического интерфейса (Model-Visual) ...
Патрик Дежарден
14
Тем не менее, логика представления будет в графическом интерфейсе. Иногда это может быть далеко не тривиальным
Андреа
Обработка концепции Мартином Фаулером (в случае, если ваша сеть, например, моя, фильтрует archive.org): martinfowler.com/eaaDev/uiArchs.html#HumbleView
Кристофер Берман,
@ c24w спасибо, что вытащили это зеркало, вы настоящий MVP :)
Джон Бейкер
38

Конечно, ответ - использовать MVC и вывести как можно больше логики из GUI.

При этом я давно слышал от коллеги, что когда SGI портировал OpenGL на новое оборудование, у них было несколько модульных тестов, которые выводили бы набор примитивов на экран, а затем вычисляли сумму MD5 буфера кадров. Затем это значение можно сравнить с известными хорошими хэш-значениями, чтобы быстро определить, является ли API точным на пиксель.

dicroce
источник
3
Мне нравится этот подход. Громоздко настраивать и поддерживать, но это даст мне возможности регрессионного тестирования, которые мне нужны.
Стив Маклеод
7
данатель ты упустил суть. OpenGL - это API рендеринга графики с точностью до пикселя. Фреймворки GUI-приложений, такие как Qt, будут сильно зависеть от системного Chrome, поэтому хеширование кадрового буфера не очень хороший подход.
Боб Сомерс
1
MD5? Какое отношение имеет к этому криптографический хеш? Как это связано с безопасностью? Хеш, хорошо, это отличная идея для пиксельной графики, но криптографический хеш? Вы можете использовать более быстрые хэши, которые не являются криптографическими и вероятность столкновения которых незначительна. Вы уверены, что это был криптографический хеш, а не просто хеш? (в дополнение к этому, в наши дни и в эпоху параллельных вычислений алгоритм хэширования [используемый в некриптографических целях], который нельзя распараллеливать, следует рассматривать с подозрением)
SyntaxT3rr0r
24
@ SyntaxT3rr0r: Какую хеш-функцию вы бы порекомендовали в этом типе приложений, не связанных с безопасностью, и какой уровень производительности можно ожидать по сравнению с MD5?
Lèse Majesté
1
Вы отвечаете означает «никогда не создавайте графический интерфейс и, следовательно, не тестируйте его». Прохладно.
Дим
10

Вы можете попробовать UISpec4J - библиотеку функционального и / или модульного тестирования с открытым исходным кодом для Java-приложений на основе Swing ...

CMS
источник
2
Я начал использовать UISpec4J в течение месяца или около того для проведения проверки правильности требований на Java Swing GUI. До сих пор мне это нравилось.
Бассам
github.com/UISpec4J/UISpec4J утверждает, что ваша ссылка является официальным сайтом, но она не выглядит для меня такой официальной. Все, что я вижу, это блог о блогах
lucidbrot
7

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

Дэвид Роббинс
источник
7

Вы можете попробовать использовать Cucumber и Swinger для написания функциональных приемочных тестов на простом английском языке для приложений Swing GUI. Swinger использует библиотеку Джемми из Netbeans для управления приложением.

Cucumber позволяет писать тесты так:

 Scenario: Dialog manipulation
    Given the frame "SwingSet" is visible
    When I click the menu "File/About"
    Then I should see the dialog "About Swing!"
    When I click the button "OK"
    Then I should not see the dialog "About Swing!"

Взгляните на это демоверсию видео Swinger, чтобы увидеть его в действии.

Дема
источник
6

Вот несколько советов:

Попробуйте удалить как можно больше кода из GUI (иметь контроллер и объект модели), таким образом вы сможете протестировать их без GUI.

Для графики вы должны проверить значение, которое вы указываете в коде, который генерирует графику.

Патрик Дежарден
источник
6

Тестирование - это вид искусства. Я согласен, логика должна быть удалена GUI, насколько это возможно. Затем мы можем сосредоточить там наше тестирование. Как и все остальное, тестирование сводится к снижению риска. Вам не всегда нужно тестировать все, но часто лучше разбить различные тесты для разных областей.

Другой вопрос, что вы действительно пытаетесь проверить на уровне пользовательского интерфейса. Тестирование пользовательского интерфейса - самое дорогое тестирование, потому что оно обычно требует больше времени для создания, обслуживания и является самым хрупким. Если вы проверяете логику, чтобы узнать правильность координат, прежде чем пытаться нарисовать линию, что конкретно вы тестируете? Если вы хотите проверить график с красной линией. Можете ли вы дать ему набор заданных координат и проверить, являются ли определенные пиксели красными или не красными? Как было предложено выше, сравнение растровых изображений работает, Selenium, но моя главная задача - не чрезмерное тестирование графического интерфейса, а тестирование логики, которая поможет создать пользовательский интерфейс, а затем сосредоточиться на том, какая часть пользовательского интерфейса ломается или подозрительно, и сосредоточить несколько тестов. там.

Чарльз Смит
источник
3

Вы можете использовать JFCUnit для тестирования вашего GUI, но графика может быть более сложной. Я пару раз делал снимки моего графического интерфейса и автоматически сравнивал его с предыдущей версией. Хотя это и не дает реального теста, оно предупреждает вас, если автоматическая сборка не дает ожидаемого результата.

Стив Мойер
источник
3

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

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

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

Андреас Buykx
источник
2

Мой подход к тестированию GUI развивается, так же как и консенсус в отрасли. Но я думаю, что несколько ключевых методов начинают появляться.

Я использую один или несколько из этих методов, в зависимости от ситуации (например, какой это GUI, как быстро его нужно создать, кем будет конечный пользователь и т. Д.).

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

  2. Модульное тестирование. Вы пишете тесты для функций или небольших модулей поведения GUI. Например, вашим графикам может потребоваться рассчитать различные оттенки цвета на основе «базового» цвета. Вы можете извлечь это вычисление в функцию и написать для него модульный тест. Вы можете искать подобную логику в графическом интерфейсе (особенно многократно используемую логику) и извлекать ее в дискретные функции, которые легче тестировать модулем. Даже сложное поведение может быть извлечено и протестировано таким образом - например, последовательность шагов в мастере может быть извлечена для функции, и модульный тест может проверить, что, при вводе, возвращается правильный шаг.

  3. Компонент проводник. Вы создаете экран «проводника», единственная роль которого заключается в демонстрации каждого из повторно используемых компонентов, составляющих ваш графический интерфейс. Этот экран дает вам быстрый и простой способ визуально убедиться, что каждый компонент имеет правильный внешний вид. Компонент проводника более эффективен, чем ручной просмотр всего приложения, потому что A) вам нужно проверить каждый компонент только один раз, и B) вам не нужно углубляться в приложение, чтобы увидеть компонент, вы можете просто просмотреть и проверьте это немедленно.

  4. Автоматизация тестирования. Вы пишете тест, который взаимодействует с экраном или компонентом, имитирует щелчки мыши, ввод данных и т. Д., Утверждая, что приложение работает правильно с учетом этих манипуляций. Это может быть полезно в качестве дополнительного резервного теста для выявления потенциальных ошибок, которые могут пропустить другие ваши тесты. Я склонен резервировать автоматизированное тестирование для тех частей графического интерфейса, которые наиболее подвержены взлому и / или крайне критичны. Части, где я хочу знать как можно раньше, если что-то сломалось. Это может включать очень сложные интерактивные компоненты, которые уязвимы для взлома или важных главных экранов.

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

Вместо того, чтобы жестко использовать всевозможные виды тестов, я предпочитаю выбирать технику тестирования в зависимости от того, над чем я работаю. Таким образом, в одном случае я извлеку простую функцию и протестирую ее, но в другом случае я добавлю компонент в проводник компонентов и т. Д. Это зависит от ситуации.

Я не нашел охват кода очень полезным показателем, но другие, возможно, нашли его применение.

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

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

Все это основано на моем личном опыте и исследованиях, а также большую запись-вверх на тестах UI по Ham Vocke .

Джонатан
источник
1

Насколько я знаю, это довольно сложно и действительно зависит от языка - многие языки имеют свой собственный способ тестирования GUI, но если вам действительно нужно тестировать GUI (в отличие от взаимодействия модель / GUI), вам часто приходится имитировать фактическое нажатие кнопок пользователем. Например, инфраструктура SWT, используемая в Eclipse, обеспечивает SWTBot , JFCUnit уже упоминался, Mozilla имеет свой собственный способ симуляции этого в XUL (и из того, что я читал в их блогах, эти тесты кажутся довольно хрупкими).

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

Ким Салливан
источник
0

Если вы используете Swing, FEST-Swing полезен для управления вашим графическим интерфейсом и проверки утверждений. Это довольно просто проверить такие вещи, как «если я нажму кнопку A, должно отобразиться диалоговое окно B» или «если я выберу опцию 2 из выпадающего списка, все флажки должны быть сняты» .

Графический сценарий, который вы упоминаете, не так легко проверить. Довольно просто получить покрытие кода для компонентов GUI, просто создав и отобразив их (и, возможно, управляя ими с помощью FEST). Тем не менее, создание значимых утверждений является сложной частью (и охват кода без значимых утверждений является упражнением в самообмане). Как вы проверяете, что график был нарисован не в обратном порядке или слишком маленький?

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

Дэн Дайер
источник
0

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

ivan_pozdeev
источник