В прошлой статье мы рассказали, как устроен процесс тестирования КОМПАС-3D. Продолжаем тему. Сегодняшний пост посвящен тому, как были автоматизированы регрессионные проверки и разработана собственная программа для тестирования не только интерфейса, но и других модулей КОМПАС-3D.



Рассказывает инженер по тестированию Екатерина Родина.

Ключевым элементом версии КОМПАС-3D v17 стал новый интерфейс. Его разработка велась в отдельной ветке, и каждые два-три дня наработки сливались в основную ветку продукта, чтобы ими могли пользоваться другие команды. Но прежде чем отдать, нужно проверить.

Интерфейс менялся очень активно. Случалось так, что из-за нововведений «ломалось» сделанное ранее. Чтобы не упустить такие моменты, мы делали ручные регрессионные проверки. Перед каждым сливом в общую ветку помимо тестирования нового кода выполняли проверку старого. Со временем работа тестировщиков превратилась в бесконечный день сурка, как в одноимённом фильме: каждый рабочий день начинался с ручного прогона всех тест-кейсов.

Первое время проверка занимала всего полчаса. По мере накопления функционала, работающего с новым интерфейсом, длительность регрессионной проверки увеличивалась, приближалась к целому рабочему дню, и это был не предел. Всё меньше времени оставалось на тестирование новой функциональности; программисты стояли в очереди в ожидании проверки своей работы. Возник вопрос: «Что делать?» Ответ напрашивался сам собой: регрессионное тестирование должно быть автоматизированным!

Первая задача — выбор инструмента. Нужно ли для этого нам «изобретать велосипед»? Или можно использовать имеющиеся и хорошо себя зарекомендовавшие программы автоматизированного тестирования?

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

В итоге было принято решение доработать КОМПАС, чтобы он тестировал сам себя, используя для этого собственные модули. При таком подходе решаются основные проблемы, не позволившие использовать для регрессионного тестирования сторонние продукты.

1. Не мешает постоянно изменяющееся окружение.
2. Полностью имитируются действия пользователя в окне с 3D-графикой.

Задача по созданию модуля автоматизированного тестирования КОМПАС-3D для наших программистов была новая и непривычная, а потому интересная. Воодушевления хватило на весь период разработки и позволило довести эту сложнейшую работу до внедрения. «Магнитофон» (так был назван получившийся модуль) стал основным инструментом регрессионного тестирования v17. Конечно, далеко не всё было гладко, но мы справились!

Как мы работаем с «Магнитофоном»


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

Запись осуществляется по принципу рекордера. Нажать кнопку Play –выполнить руками сценарий тесткейса — нажать Stop. Тесткейс полностью описывает действия пользователя с проверяемым элементом: открытие программы, выполнение построения, закрытие программы. В определенные моменты времени создаются контрольные точки. Файл с тестом готов, теперь возможно его использование для автоматизированного тестирования.

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

Сценарий теста пишется в xml-файл с возможностью ручного редактирования тестировщиком либо программистом.

Программно КОМПАС-3D разделен на модули: интерфейсный, модуль 3D-моделей, модуль чертежей. Соответственно разделены на модули и автотесты.

Интерфейс


Запись интерфейсного теста основана на привязке событий к логическим объектам интерфейса. Есть имя кнопки и есть событие, которое с ней происходит. Интерфейсная контрольная точка состоит из двух элементов — снепшота и скриншота.

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

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


Визуализация отличий в снепшотах

Какие проблемы пришлось решать:


1. Большой размер снепшотов

Хотелось обладать всей полнотой информации о том, в каком состоянии находится система, поэтому снепшоты занимали слишком много места. 100 тестов — 28 ГБ.

Первое, что было сделано для уменьшения объёма — удалены элементы, не влияющие на внешний вид. Если пользователь не видит каких-либо элементов, то на данный момент информация о них не нужна, и нет необходимости записывать её в снепшоты. Затем весь интерфейс был разбит на составляющие с возможностью выбора: хочешь — записывай информацию о всех элементах, или об одном-двух, с которыми в данный момент работаешь.


Выбор элементов для сравнения

Такой подход позволил сократить место, занимаемое на жестком диске, в 50 раз. Сейчас 100 тестов занимают 0,5 ГБ. Время выполнения тестов сократилось в три раза — с 30 секунд в среднем на тест до 10 секунд.

2. Большое количество ошибок

Часто после слива очередных изменений интерфейса в результате прогона автотестов наблюдался вал ошибок (1000 ошибок в одном тесте). К примеру, изменилась длина панели и изменилась длина всех контролов, которые расположены на этой панели. Тестировщик воспринимает это как одну ошибку, программа — как десяток. Такие ошибки были объединены в блоки с добавлением проверки между родительскими и дочерними элементами. Если в дочернем элементе возникала такая же ошибка, как и в родительском, она исключалась из результатов, считалось, что эта ошибка уже учтена в тестах.

3. Отделение ошибок от доработок

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


Игнорирование по образцу

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

4. Работа с наборами тестов

На каждый тест навешивается определенное количество тэгов для того, чтобы легко их отсортировать.


Использование тегов

Рабочая область 3D


Тест для рабочей области принципиально отличается от интерфейсного. События привязаны к трехмерным координатам (x, y, z) модели. Мы создаем растровое изображение, которое сравнивается с эталоном. Для этого используется сторонняя программа ImageMagick, все отличия подсвечиваются красным цветом.


Пример выполнения теста

Тесты для разных модулей можно записывать как совместно, так и отдельно друг от друга. В тесте из видео для наглядности была специально заложена ошибка: установлено неверное расстояние между колесом и тормозным диском. При сравнении растровых изображений мы видим, что колеса подсветились красным — они расположены неправильно.

Какие сложности возникли здесь:


1. Масштабируемость

На мониторах с разным разрешением (разным масштабом) возникала ситуация, когда курсор кликал-кликал и вдруг начинал промахиваться. Это происходило из-за пересчета на другой масштаб. Возникающая погрешность в какой-то момент становилась критичной. Решили эту проблему очень просто — принудительным заданием разрешения и масштаба во всех тестах. Не важно, на каком мониторе вы запускаете тест, окно программы автоматически подгонится под размер нужного разрешения. Естественно, это работает с меньшего масштаба на больший. В обратную сторону не получится. Просто мы договорились, на каком масштабе монитора пишем тесты.

2. Производительность

К примеру пользователь выполняет действие за две секунды, а программа — за десять секунд, в пять раз дольше. Какие же это автотесты? Начали разбираться и выяснили. Запись координат курсора производилась следующим образом: бралась 2D-координата курсора на мониторе, конвертировалась через видеокарту в 3D-координату, которая находится в модели, и после этого происходило событие. Конвертация постоянно дергала перерисовку на видеокарте, модель постоянно перерисовывалась. Если попадалась объемная модель с большим количеством деталей, лежащих внутри, то перерисовка происходила достаточно долго. Мы вообще отказались от конвертации и сразу стали записывать в трехмерных координатах модели. Исключили видеокарту из этой цепочки.

3. Реализация моделей на разных видеокартах

Как ни крути, на разных видеокартах растровое изображение одной и той же модели будет различным. Однако, отличия незначительные, и мы решили назначить величину погрешности в 1%. Если модель совпадает вплоть до 1%, то модель верная. Если больше 1%, значит возникла ошибка. Сейчас на разных видеокартах модели совпадают до 0,01.

4. Контроль заднего плана

Решение для этой проблемы есть, но пока не реализовано. Допустим, у нас есть фотография 3D-модели, но по этой фотографии вы не узнаете, что расположено на «спине» модели, пока не повернете ее спиной и не сфотографируете. Планируется использовать систему уточненного контроля — разбивать модель на отрезки, вершины, грани и сравнивать свойства по указанным элементам.

Применение на практике


В процессе разработки КОМПАС-3D v17 автоматически регрессионные проверки выполнялись каждые 2-3 дня. У нас появилось больше времени на тестирование нового функционала, меньше времени уходило на обработку тестов. Изначально рекордер задумывался, чтобы разгрузить группу интерфейса, но он нашел применение и в тестировании других модулей КОМПАС-3D.

Мы не собираемся останавливаться на достигнутом. В планах — расширение применения автотестов (в идеале — охватить всю функциональность КОМПАС), наращивание базы тестов. И, конечно, применение «Магнитофона» для стабилизации последующих обновлений и сервис-паков КОМПАС-3D v17.

Екатерина Родина, инженер по тестированию интерфейса.
Поделиться с друзьями
-->

Комментарии (8)


  1. vasily-v-ryabov
    17.05.2017 10:09

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

    Просто если вы работаете только под Windows, странно, что не использовали инструменты на основе accessibility технологий, чтобы заскриптовать тесты в читабельном текстовом формате (а не координатами). Скриншоты — разумеется, для отдельных элементов интерфейса. Как же иначе-то.

    Вопрос: как часто бывает, что небольшие отличия в отрисовке не являются багом? И приходится обновлять все или большую часть эталонных картинок. Надо же просмотреть все отличающиеся пары изображений, вдруг реальную багу пропустишь! А их на 100 тестов, скажем, тысяча пар картинок.


    1. vasily-v-ryabov
      17.05.2017 10:15

      В моём предыдущем проекте мы тоже тестировали приложение с развесистой графикой. И там как раз небольшие изменения в отрисовке часто не являлись багом. Мы, конечно, сделали в HTML логах ссылочки типа «обновить эталон» (или как это ещё называют «обновить голдЫ»), но всё равно сотню картинок обновлять тупым кликерством напрягало. Была ещё мысль, а можно ли сделать авто аналитику для картинок, чтобы сказать «обнови все похожие изменения во всех эталонах». Но вопрос дальше не исследовали.


      1. vasily-v-ryabov
        17.05.2017 10:19

        Пороговые значения мы тоже применяли. Но случалось часто, что какой-нибудь большой 3D объект смещался на небольшую величину (потому что отрисовку осей координат улучшили, например). И тут 1% разницы не обойтись.


      1. kompas_3d
        17.05.2017 12:18

        всё равно сотню картинок обновлять тупым кликерством напрягало

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


    1. kompas_3d
      17.05.2017 11:42

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

      Мы не записываем координаты. Такие тестовые сценарии пришлось бы переписывать (перекликивать) заново, если в результате аналитического решения, скажем, кнопка переедет в другое место панели. Мы используем схему именования логических объектов в интерфейсе. Она проста и даёт тестовым сценариям необходимую устойчивость.
      Вопрос: как часто бывает, что небольшие отличия в отрисовке не являются багом? И приходится обновлять все или большую часть эталонных картинок. Надо же просмотреть все отличающиеся пары изображений, вдруг реальную багу пропустишь! А их на 100 тестов, скажем, тысяча пар картинок.

      Растровые снимки (как результат тестов) используются только для сравнения рабочих областей. Снимки же интерфейса хранятся в xml-файлах, а картинки используются лишь для удобства тестировщика при обработке результатов. В условиях активной разработки ситуация когда отличия не являются багом возникает регулярно. Для её решения придуман и механизм правил для игнорирования ошибок.


      1. vasily-v-ryabov
        17.05.2017 16:09

        Значит, для testability у вас реализован собственный тестовый back door (если так можно назвать), через который вы получаете имена объектов в интерфейсе? Некоторые, например, делают служебный TCP сервер в приложении для подобных вещей. Интересно, какой подход у вас?


        1. kompas_3d
          17.05.2017 18:42

          Часть Магнитофона, отвечающая за запись и воспроизведение тестов, интегрирована в интерфейсный модуль КОМПАСа.

          Другая часть (внешнее приложение) используется для удобного управления процессом запуска тестов и обработки результатов. В частности, она выполняет запуск КОМПАСа со специальными ключами командной строки.


    1. kompas_3d
      17.05.2017 12:24

      Рабочая область(это часть экрана, где модель отображается) хоть и работает с координатами, но не с координатами на экране, а с собственными трехмерными координатами внутри программы (х,y,z).