Friday, March 23, 2012

Расширяем JUnit. Декларативные предусловия.

Нам довольно часто приходится писать тесты, в которых по мере разработки сценариев мы выносим общую логику в setUp. Это хорошая практика, но с увеличением количества тестовых сценариев setUp может разрастись до довольно больших размеров. Мне приходилось сталкиваться с такими тестами. Причем принцип Парето в них зачастую соблюдается так: 80% всех тестов используют 20% функциональности, находящейся в setUp. Кроме сложного setUp каждый тест еще обычно создает свои специфические предусловия. Это довольно сильно усложняет понимание такого теста, т.к. приходится постоянно помнить, что находится в setUp и, к тому же, понимать какие предусловия дополнительно создаются для каждого теста.

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

Итак, предположим нам нужно разработать фильтр для файлов, аналогичный тому, который мы используем в файловых менеджерах. Например если наложить фильтр *.txt, то должен вернутся список текстовых файлов.

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

А было бы легче работать с тестом, который написан таким образом?


Как такое может заработать?


Самый простой вариант - это реализовать свой ранер, наследник от базового класса org.junit.runner.Runner и указывать его в качества "запускальщика":



Полный текст кода класса FileFilterRunner


Что здесь интересного
1. Наследуемся от BlockJUnit4ClassRunner
2. Перекрыт метод runChild. В нем перед вызовом тестового метода создаем временную директорию и заполняем ее тестовыми файлами, имена которых берем из нашей аннотации Given. Для работы с файлами использую библиотеку Apache Commons IO
3. Перекрыт метод validatePublicVoidNoArgMethods. Это позволяет запускать тестовые методы с параметрами
4. Перекрыт метод methodInvoker. Этот метод вызывается JUnit фреймворком для каждого тестового метода
5. Класс ParameterizedInvoker - это наша реализация "вызывальщика" тестовых методов. Мы вызываем тестовый метод с параметром testFolder

Вот сама аннотация Given:


Что получили?


1. Тест стал более читабелным за счет того, что мы вынесли инициализацию предусловий в документирующую аннотацию Given.
2. Реализованный ранер можно легко использовать в других тестах.
3. Если развивать этот подход, то уменьшится необходимость создавать суперкласс для тестовых классов, в котором хранить общую логику для всех наследуемых тестов. Все в аннотациях.
4. Нету setUp/tearDown в тесте
5. Инициализируем только то, что нужно для теста. Если нам, например, понадобится набор папок, то мы добавим в аннотацию параметер folders. Если пользователь с именем "Вася", то - параметр users.
6. Можем ужесточать или ослаблять предусловия. Что если, например, параметр files станет обязательным? Мы уберем инициализацию по умолчанию default {}, тем самым тесты, которые не использовали обязательные параметры перестанут компилироваться и мы их сразу обнаружим
7. Если видишь, чем хорош или плох этот подход - пиши комент, дополню список

Идеи развития


Аннотированные параметры тестового метода. Если есть необходимость передавать разные параметры в тестовый метод, то мы можем их именовать с помощью анотаций, имеющих тип @Target(ElementType.PARAMETER):


Например, нам в тесте понадобился список созданных файлов и путь к корневой директории:


Полный текст исходников и проекта находится здесь качать

Thursday, March 08, 2012

Automation testing dojo - настройка проекта на Java

Ответ на вопрос "Готов ли я участвовать в Automated testing dojo?" дает следующий тест:


Given installation manual below
When I run sample tests from the template
Then I see green line


Как только этот тест PASSED, то можно присоединяться к участникам соревнования, имея большие шансы набрать наибольшее количество баллов ;). Если тест FAILED, то всегда есть у кого попросить помощи в настройке (мой email указан в профайле).

Руководство по установке


Для того, чтобы настроить проект потребуется средство сборки и управления зависимостями Maven. Скачать можно отсюда. Инструкция по установке здесь.
Проверить правильность установки мавена можно запустив из командной строки команду mvn -version. В случае успешной установки на консоль выведется версия Maven и Java.

Скачиваем шаблон проекта. Качать здесь. Распаковываем в папку на диске. В моем случае это c:\workspace\projects\template-java.
Ниже инструкции настройки проекта для Инструкция для IDE IntelliJ IDEA и Инструкция для Eclipse. Немного проще настраивать в IntelliJ IDEA, т.к. там встроена хорошая поддержка Maven проектов.

Инструкция для IDE IntelliJ IDEA


Инструкция для IntellJ IDEA 11 Community Edition, скачать которую можно здесь.
После запуска IDE выбираем File->New Project... или выбираем значок Create New Project из панели Quick Start:


Выбираем Import Project from external model и жмем Next. Обратите внимание, что если у вас версия IDEA ниже 11, то пункт "Import project from external module" будет последним в списке.


Проект Maven, Next


Указываем путь к папке, в которую распаковали шаблон проекте (в моем случае это c:\workspace\projects\template-java), нажимаем Next


Должен обнаружиться мавеновский проект:


Название проекта и расположение оставляем как есть и жмем Finish


Немного подождем, пока загрузятся нужные библиотеки и посмотрим на структуру проекта.


Как видим, в проекте один тестовый класс, в котором будем кодить наши автоматизированые сценарии.


Попробуем скомпилировать и запустить тест. Запустить можно по правой кнопки мыши и выбрать Run "SampleAutomationTest" или сочетанием клавиш <ctrl>+<shift>+F10.


Вы получили ответ на вопрос "Готов ли я участвовать в Automated testing dojo?". Если тест зеленый, то готов! Приходи на dojo, регистрируйся и начинай автоматизировать! К инструкции как регистрироваться


Инструкция для Eclipse


Инструкция для Eclipse IDE for Java developers. Скачать можно здесь. Выбрана именно эта конфигурация Eclipse потому что она интегрирована с Maven.


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


После запуска IDE выбираем File->Import... и в появившемся окне выбираем Maven->Existing Maven Projects и жмем Next


Затем выбираем папку, в которой находитдя шаблон проекта. В моем случае это c:\workspace\projects\template-java. Нажимаем Finish


Немного подождем, пока скачаются все зависимости, после чего смотрим на структуру проекта:


Как видим, в проекте один тестовый класс, в котором будем кодить наши автоматизированые сценарии.


Запустим тест. Правой кнопкой мыши Run As->JUnit Test из окна с исходным текстом или в окошке Outline.


Вы получили ответ на вопрос "Готов ли я участвовать в Automated testing dojo?". Если тест зеленый, то готов! Приходи на dojo, регистрируйся и начинай автоматизировать! К инструкции как регистрироваться

Регистрация и логи


Прежде чем зарегистрироваться нужно указать в тесте адрес сервера в анотации @ReportTo. Заменим http://127.0.0.1:8080 на реальный адрес приложения, которое будем автоматизировать. После чего укажем имя, под которым на сервер будут отсылаться отчеты о успешности выполнения теста. Заменим JohnDoe на свое уникальное имя.
Важно - имя должно быть написано латинскими буквами без пробелов и спец символов.
Важно2 - Регистр имеет значение. Так JohnDoe и johndoe - это 2 разных пользователя

Открываем браузер и вводим такой URL: http://<server address>/register. Где <server address> - это IP адрес сервера. В тест боксе Player name вводим имя игрока


Если вы ввели уникальное имя, то выведется страничка с результатами запуска тестовых сценариев

Где в столбце
  • Scenario - номер сценария
  • Score - количество очков, полученные за результат выполнения (или бездействия) автоматизированного тестового сценария
  • Test result - прошел тест или нет (true/false)
  • Description - краткое описание за что начислили (или отобрали) баллы
  • Log type - То как система распознала отчет автоматизированного теста

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


    Теперь можно автоматизировать сценарии, описание которых можно увидеть, если перейти по линку на страничке логов или ввести URL http://<server address>/scenarios