Собственно, на этот вопрос мы ответили ещё в конце этого поста:
1) нет фатальных ошибок – что бы ни случилось, тесты вращаются дальше с новыми ошибками;
2) логирование – в логах есть вся информация, но она совсем сырая, сложно обрабатывать;
3) уже можно немного запутаться в коде – мало комментариев;
4) никак не используется возможность выполнять тесты параллельно – у нас только один тест
и даже успели обсудить первую проблему.
Самое время заняться вторым вопросом – представлением и обработкой информации, полученной во время тестирования.
Вопрос, как должны выглядеть отчёты – а следовательно, что содержать логи – и как обеспечить удобную работу с ними, волновал нас уже давно.
Очень приятно, что твои тесты делают кучу рутинной работы по проверке элементов, но кто узнает об этом? Хочется, чтобы тесты подготавливали удобный отчёт о проделанной ими работе и найденных ошибках, а не текстовый файл, который и открыть-то страшно.
В версии 54, которую мы рассматривали, логи содержали практически всю информацию, которую можно было как-либо использовать для анализа ошибок. Но хранилась она в текстовом файле, и, честно говоря, постороннего человека могла скорее напугать, чем обрадовать. Кроме текстовых логов, делались скриншоты, а перед началом теста можно было установить уровень сообщений, которые будут записаны в лог (info, warn, error). Подробно об этом представлении логов написано здесь.
Нас волновали несколько вопросов, связанных с логами.
Кто будет пользоваться отчётами?
Надо рассчитывать как минимум на несколько типов пользователей наших отчётов.
Во-первых, это может быть человек, который должен будет контролировать, что периодические тесты выполнились без ошибок. В общем-то, всё, что ему надо увидеть – были ли ошибки во время теста, или нет.
Во-вторых, это может быть человек, который должен иметь возможность повторить все действия, которые привели к ошибке, чтобы описать их разработчику.
Во-третьих, это может быть человек, который тесты подготовил. Его задача – из отчёта убедиться, что нет ошибок в самих тестах (например, правильно ли указаны локаторы элементов).
Для каждого из этих типов пользователей отчёт должен выглядеть немного по-разному. Наша главная задача сейчас не в создании отчётов, а в сохранении в логах как можно более полной информации, по которой такие отчёты могут быть составлены.
Как представить последовательность действий, которые привели к ошибке?
Ещё одно требование к отчёту – понятное описание последовательности действий, которые приводят к ошибке. С точки зрения тестов действие – это не только, например, ввод значения в поле ввода или нажатие на кнопку.
Коротко говоря, каждому методу тестов может соответствовать своё действие. Например, проверка, что при KGV запись успешно сохраняется – метод GenericObject.checkIsRecordSavable() – это действие. Подсчёт количества отсутствующих элементов – метод missedElementsCount() – это тоже действие. Для простоты, если действие соответствует какому-то методу, будем называть такое действие именем метода.
Выходит, что действия могут включать в себя другие действия. Например, действие missedElementsCount для страницы Login с двумя полями ввода сейчас состоит из двух действий checkPresence, а в каждом из checkPresence используется действие isElementPresent, которое соответствует одноименному методу Selenium.
Таким образом, последовательность действий имеет иерархическую структуру. Это тоже необходимо учитывать при отображении.
Скриншоты
Идеально было бы иметь возможность посмотреть на скриншот до начала какого-то действия (ввода значения, нажатия на кнопку) и сразу после него. В версии 54 скриншоты делаются только после ошибки.
Тесты только собирают информацию
Стало очевидным, что генерация отчётов должна происходить уже после завершения тестов. Только тогда мы будем иметь необходимую информацию об общих результатах теста (сколько ошибок, сколько предупреждений, какие именно из действий и проверок нужно пометить, как фатальные или ошибочные). Кроме того, это позволит нам сделать генерацию различных отчётов независимой от выполнения тестов. То есть тесты сохранили информацию в сыром виде, а что с ней делать дальше – дело наше.
Поэтому мы считаем, что тесты в любом случае должны ориентироваться не на сохранение только данных об ошибках или предупреждениях, а о хранении всех действий, которые были выполнены.
Куда будет собираться информация во время тестирования?
Мы могли бы сохранять сырые данные в текстовый файл (как делали это в версии 54), в базу данных, в XML. Хотелось бы, чтобы выбранное хранилище позволяло представить иерархию действий, и определённые свойства для каждого из действий. С этой точки зрения нам подходит XML.
Однако мы решили “срезать угол” и не писать сейчас данные в файл вообще, а хранить действия (или “события”) в памяти в виде списка (ArrayList) объектов специального класса Event. Эти объекты будут хранить всю информацию о действии: имя действия, время начала действия, время его завершения, “цель” действия (локатор, например), применённое к цели значение (например, значение, введённое в поле ввода), ожидаемый результат действия, действительный результат, статус (ok, error, fatal), подробное сообщение об ошибке, сообщение, переданное в исключении (если во время действия было сгенерировано исключение), имена скриншотов до и после действия.
Когда всё устаканится, мы добавим запись из ArrayList в XML по окончании тестирования и чтение из XML в ArrayList перед генерацией отчёта.
Теперь перейдём к подробностям реализации.
Общий доступ к списку действий
С учётом списка действий, мы имеем три вещи, которые должны существовать для каждого теста в единственном экземпляре: драйвер Selenium, логгер log4j, список действий.
Чтобы не передавать каждому из объектов Java три ссылки при инициализации, вся работа с этими общими объектами ведётся через экземпляр seleniumActions. Он содержит в себе драйвер, список событий и логгер.
Работа с действиями
Собственно, как записать в список действие? Очень просто.
Действие можно открыть и закрыть в любой момент, но, как уже говорилось выше, действие, как правило, соответствует определённому методу. Логично было бы открывать действие в начале метода и закрывать при его завершении.
Так сейчас и делается. Рассмотрим для примера метод GenericElement.fillByNull().

Figure 1
В общем-то, открыть событие – значит просто создать новый объект типа Event, и заполнить некоторые его свойства, в частности, имя.
Метод action.typeText, который вызывается в этом действии, тоже является действием. Вот его код:

Figure 2
Скриншоты
В 54 версии тестов, о которой мы говорили раньше, скриншоты делались только в случае ошибок. Ошибки могли быть выявлены на разных уровнях (например, на нижнем уровне – при генерации драйвером Selenium исключения, или на более высоком уровне – при сравнении ожидаемого и реального значений), и поэтому скриншоты тоже делались на разных уровнях. При этом часто скриншоты дублировались, так как ошибка нижнего уровня приводила к ошибке более высокого уровня, а скриншот делался в обоих случаях.
Совершенно логичным оказалось перенести создание всех скриншотов в те несколько функций работы с драйвером Selenium, которые могут изменить страницу, и убрать из всех остальных функций. Это такие функции, как typeText, Click, waitForPageToLoad. То есть перед выполнением такого действия и по его завершению должен создаваться скриншот. При такой реализации мы создаём слишком много скриншотов, – даже те, которые не нужны, так как не связаны с ошибками. В этом случае мы можем после завершения каждого действия, если оно удачное, удалять ненужные скриншоты. Другое решение – удалять ненужные скриншоты по завершению тестирования.
Первый отчёт
После того, как было решено использовать Events, каждый метод, который можно было рассматривать как действие, был “научен” записывать информацию о себе в список действий.
Теперь всё было готово для того, чтобы генерировать какие угодно виды отчётов уже после завершения теста.
Пока что мы подготовили только один отчёт, но постарались сделать его универсальным: с одной стороны, он позволяет просмотреть всю полученную при тестировании информацию, а с другой – при необходимости скрыть ненужную.
Мы решили, что отчёт будет удобно представить с помощью HTML, потому что:
1. С помощью HTML и JS можно отобразить как простенький отчёт, так и очень сложный.
2. Сложный отчёт можно сделать интерактивным: показывать и скрывать иерархию действий, показывать или прятать отдельные типы ошибок, дополнительную информацию.
3. Рядом с каждым действием в отчёте можно поместить ссылку на скриншоты, которые можно будет сразу просмотреть.
Вот как он выглядит.
Figure 3
Кроме того, дополнительная информация может содержать сообщение о результатах действия и совет – как правило, в случае ошибок.
Figure 4
Вы можете скачать этот отчёт здесь и рассмотреть его попристальней.
Рвусь из сил и из всех сухожилий,
Но сегодня – опять, как вчера,-
Обложили меня, обложили,
Гонят весело на номера.




Loading...