Статьи

Тестирование Java EE 6 Galleria


Время двигаться дальше с примером Vineet Java EE 6 Galleria. После
небольшого вступления , базового
руководства  по началу работы с GlassFish и
развертыванием WebLogic 12c, пришло время погрузиться в тестирование. Я пропустил эту часть в предыдущих постах по двум причинам. Первое, очевидно, было то, что я хотел написать отдельный пост об этом. Вторым было то, что нужно было поработать, чтобы запустить и запустить последнюю версию GlassFish 3.1.2. Vineet и его команда проделали отличную работу, выпустив Arquillian GlassFish Remote Container CR3 несколько дней назад, который теперь также охватывает GlassFish 3.1.2. Пора начать с тестирования Galleria Example.

Что вы собираетесь проверить

Galleria была разработана для обеспечения всестороннего охвата тестов за счет использования модульных и интеграционных тестов, написанных в JUnit 4. Модульные и интеграционные тесты для EJB и модель предметной области основаны на API контейнера EJB 3.1. Интеграционные тесты для уровня представления опираются на проект Arquillian и его расширение Drone (для выполнения тестов Selenium).

Пожалуйста, не забудьте обновить последние источники из
проекта Galleria, потому что Vineet обновил контейнер Arquillian GlassFish до CR3 и Selenium для поддержки новейшего браузера FireFox.

Юнит-тестирование уровня домена

Тесты для доменного уровня делятся на пять отдельных категорий. Первые три (тесты Bean Verification, тесты взаимной регистрации, тесты для конструктора, методы equals и hashcode) покрывают основные потребности практически любого приложения на основе JPA. Если вы прогуляетесь по источникам galleria-ejb \ src \ test, вы увидите их в пакете info.galleria.domain. Каждый объект домена покрывается классом набора, который включает все три вида модульных тестов.

Давайте начнем с рассмотрения тестов Bean Verification. Поведение, связанное с методами получения и установки в свойствах JavaBeans, довольно легко проверить. Все, что нужно сделать, это сначала вызвать установщик, затем получатель и проверить, равен ли экземпляр, возвращаемый получателем, экземпляру, переданному установщику. Для этого в проекте используется класс BeanVerifier ( в
корневом каталоге src / tests / java модуля galleria-ejb). Тест AlbumBeanVerifier просто является параметризованным тестом, который проверяет каждое отдельное свойство. Единственным исключением в этом случае является свойство coverPhoto, которое имеет особое поведение помимо простого шаблона JavaBean.

Далее в списке идут тесты для методов конструктора, equals и hashcode. Конструкторы для сущностей домена проверяются путем простого создания новых экземпляров классов, в то же время утверждая валидность свойств, которые будут установлены конструктором. Методы equals и hashcode проверяются с помощью класса EqualsVerifier из
проекта EqualsVerifier .

Последняя категория более базовых тестов — это тесты  взаимной регистрации  (PDF). Вы просто хотите проверить, действительно ли изменения в отношениях между сущностями приводят к изменениям как родительских, так и дочерних свойств. Смотрите всестороннюю вики-страницу для более подробной информации о реализации. Все они выполняются на этапе модульного тестирования и охватываются классами ** / * Suite.java.
В дополнение к базовым тестам вы также найдете одноразовые тесты, написанные для конкретных случаев, когда базовые тестовые модели недостаточны или непригодны. В таких случаях одноразовые тесты проверяют такое поведение с помощью рукописных утверждений. Вы найдете их в классах ** / * Tests.java в том же пакете.
Тесты на уровне домена заканчиваются тестами репозитория JPA. Каждый из классов * RepositoryTest.java тестирует поведение CRUD обработанных доменных объектов. Общий AbstractRepositoryTest обрабатывает тестовые данные и сбрасывает базу данных после каждого запуска теста. Само создание базы данных обрабатывается плагином maven-dbdeploy. Взглянув на файл pom.xml, вы увидите, что он связан с двумя фазами жизненного цикла Maven (process-test-resources и pre-интеграция-test), что обеспечивает его повторный вызов дважды. Первый раз перед юнит-тестами и второй перед интеграционным тестированием (сравните ниже).
Все эти юнит-тесты выполняются безошибочно. Если вы выполните тест mvn для проекта galleria-ejb, вы увидите, что в общей сложности прошло 138 тестов. Это четыре теста ** / * Suite, четыре ** / * RepositoryTests и два дополнительных теста. Если вы кратко посмотрите на вывод консоли, то увидите, что все это происходит в среде Java SE. Контейнерные тесты до сих пор не проводились.

Интеграционное тестирование уровня домена
Так что это действительно охватывало только основы, которые каждый должен делать и, вероятно, знает. Проведение интеграционного тестирования — другая история. Это делается с помощью тестов ** / * IntegrationSuite. Имя намеренно не использует соглашения об именах по умолчанию, чтобы предотвратить их запуск на этапе модульного тестирования Maven. Чтобы подключиться к этапам тестирования интеграции Maven, в примере Galleria используется  плагин Maven Failsafe., Вы можете найти комплект интеграционных тестов в пакете info.galleria.service.ejb. AbstractIntegrationTest заботится об обработке тестовых данных (сравнимых с тем, что AbstractRepositoryTest) делал для юнит-тестов. Набор содержит * ServiceIntegrationTest для каждого объекта домена. Вы можете пройти отдельные тесты в каждом * IntegrationTest и почувствовать, что здесь происходит. ServicesIntegrationSuite заботится о запуске и остановке EJBContainer с помощью AbstractIntegrationTest.startup () ;. Этот метод сравнительно не впечатляющий и простой:

logger.info("Starting the embedded container.");
Map<String, Object> props = new HashMap<String, Object>();
props.put("org.glassfish.ejb.embedded.glassfish.installation.root",
  "./glassfish-integrationtest-install/glassfish");
container = EJBContainer.createEJBContainer(props);
context = container.getContext();
datasource = (DataSource) context.lookup("jdbc/galleriaDS");

Наиболее важным моментом здесь является то, что встраиваемый EJBContainer настраивается через существующий домен GlassFish, который можно найти непосредственно в папке galleria-ejb \ glassfish -grationtest-install. Если вы посмотрите на glassfish \ domains \ domain1 \ config \ domain.xml, то увидите, что все настройки для вас уже выполнены. Но откуда происходит развертывание? Это легко ответить. По умолчанию встраиваемый EJBContainer ищет в вашем classpath jar-файлы или папки ejb-jar и развертывает их. Если вы хотите увидеть более подробный вывод из EJBContainer, вы должны предоставить файл customlogging.properties в src / test / resources и добавить в него несколько простых строк: 

handlers=java.util.logging.ConsoleHandler
java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter
java.util.logging.ConsoleHandler.level=FINEST
#add some more packages if you need them
info.galleria.service.ejb.level=FINE

добавьте следующее в раздел конфигурации maven-failsafe-plugin вашего pom.xml: 

<systemPropertyVariables>
<java.util.logging.config.file>${basedir}/src/test/resources/customlogging.properties</java.util.logging.config.file>
</systemPropertyVariables>

Интеграционные тесты должны успешно завершиться, и maven должен напечатать что-то похожее на следующее:

Tests run: 49, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 61.726 sec

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

Интеграционное тестирование уровня представления Уровень
домена покрыт тестами. Чего не хватает, так это уровня представления. Вы можете найти тесты презентационного уровня в проекте galleria-jsf. Начните с изучения pom.xml. Вы найдете пару новых зависимостей здесь. А именно Аркиллиан, Селен и Дрон.

Сначала снова немного настроек. Прокрутите вниз до раздела профиля, чтобы увидеть профиль интеграционного теста, в котором используется плагин maven-glassfish-plugin и который управляет контейнером, для которого настроено несколько свойств. Добавьте определение в раздел свойств в верхней части pom:

<galleria.glassfish.testDomain.user>admin</galleria.glassfish.testDomain.user>
<galleria.glassfish.testDomain.passwordFile>D:/glassfish-3.1.2-b22/glassfish3/glassfish/domains/test-domain/config/local-password</galleria.glassfish.testDomain.passwordFile>
<galleria.glassfish.testDomain.glassfishDirectory>D:/glassfish-3.1.2-b22/glassfish3/glassfish/</galleria.glassfish.testDomain.glassfishDirectory>
<galleria.glassfish.testDomain.domainName>test-domain</galleria.glassfish.testDomain.domainName>
<galleria.glassfish.testDomain.adminPort>10048</galleria.glassfish.testDomain.adminPort>
<galleria.glassfish.testDomain.httpPort>10080</galleria.glassfish.testDomain.httpPort>
<galleria.glassfish.testDomain.httpsPort>10081</galleria.glassfish.testDomain.httpsPort>

Вы можете скопировать это из профиля разработки проекта galleria-ejb, как описано в части 2 . Вы также должны уже иметь домен на месте. Далее вы увидите, что плагин maven-surefire-plugin следует тем же правилам, что и проект galleria-ejb. Но, глядя на тестовые классы, вы видите, что здесь нет ни одного юнит-теста. Таким образом, вы можете перейти непосредственно к maven-failsafe-plugin, который обрабатывает интеграционные тесты. Существует один единственный AllPagesIntegrationTest, который охватывает полное тестирование. Пойдем туда.
Это Arquillian Testcase, который выполняется как клиент против удаленного экземпляра. Помимо определения развертывания (@Deployment) вы также снова видите несколько методов setUp и tearDown, которые выполняют некоторую инициализацию и уничтожение. Одна вещь должна быть обработана отдельно. Вы также видите там метод writeCoverageData (), который, очевидно, подключается к какому-либо сокету и считывает данные из него. Это хук JaCoCo (Java Code Coverage Library), который может создать набор данных покрытия тестов. Для этого вам нужно скачать пакет и распаковать его в любое место по вашему выбору. Затем перейдите в свой тестовый домен GlassFish \ config \ domain.xml и откройте его. Найдите server-config — java-config и добавьте туда следующее:

<jvm-options>-javaagent:D:\path\to\jacoco-0.5.6.201201232323\lib\jacocoagent.jar=output=tcpserver</jvm-options>

Это позволяет агенту покрытия для GlassFish. Все настройки сделаны сейчас. Возвращаясь к NetBeans, выберите профиль интеграционного теста (в NetBeans вы можете сделать это, выбрав запись из выпадающего списка рядом с небольшим молотком в области значков или используя -Pintegration-test в качестве переключателя командной строки maven. Консоль Выходные данные сообщают вам, что домен GlassFish запущен и запущен info.galleria.view.AllPagesIntegrationTest. Имейте в виду, что во время этого запуска появляется экземпляр FireFox, а расширение Arquillian Drone управляет вашими тестами Selenium.

Seeing a browser remote controlled in this way looks and feels weird if you haven’t seen this before. If everything works you should now see this in the console output:

Tests run: 30, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 138.014 sec

 

If you are using another locale than en for your browser you may have completely failed tests. So there is additional need to configure Drone to support it. Drone allows you to specify a Firefox profile via arquillian.xml. You can create a Firefox profile that is configure to send accept-language headers with en/en-US as the value.
To create a new profile, start Firefox Profile manager with the following command (you might need to close all running instances): firefox -profilemanager (on Windows you need to execute the command «d:\complete\path\to\firefox.exe» -profilemanager) in a cmd shell. Remember the location on the disc where this profile is created — you’ll need it later. To configure the created profile, in Firefox, go to Options (menu) -> Content (tab) -> Languages (fieldset) -> Choose to add the English language (and move it top, as the preferred one). Now navigate the galleria-jsf\src\test\resources\arquillian.xml, you can then add a property:

<extension qualifier="webdriver">
<property name="implementationClass">org.openqa.selenium.firefox.FirefoxDriver</property>
<property name="firefoxProfile">location of the Firefox profile for English</property>
</extension>

All done now. You should be able to run the complete clean and build process now without any test failing. A big «green bar» ?