Статьи

Тестирование функциональных веб-сервисов стало проще с SoapUI — Часть 3

В первых двух частях ( часть 1 и часть 2 ) этой серии мы увидели, как использовать SoapUI для написания функциональных тестов для веб-сервисов, а также как использовать Groovy для настройки теста, передачи свойств и утверждений. Как мы уже говорили, тесты должны быть интегрированы с вашими сборками и должны быть в состоянии запускаться с ними. Если вы автоматизировали свои сборки, и они выполняются как часть вашей настройки непрерывной интеграции (CI) , SoapUI становится еще удобнее: вы можете запускать наборы тестов и созданные вами тесты, а также генерировать отчеты JUnit.

В этой части этой серии вы познакомитесь с пошаговыми инструкциями Ant для выполнения тестов, написанных с использованием SoapUI, создания отчетов JUnit, интеграции с CI и, в довершение всего, получения покрытия кода с помощью Cobertura . Закончив с этой частью, вы сможете воспользоваться преимуществами написания тестов, непрерывной интеграции и покрытия кода.

Мы будем использовать известный проект PetStore от Sun’s BluePrints . Мы будем использовать JPAToplink ) для уровня постоянства и сессионных компонентов для бизнес-уровня; добавив простые аннотации, мы опубликуем эти сессионные компоненты в виде веб-сервисов. Этот проект не имеет внешнего интерфейса. Он будет развернут на сервере справочных приложений JEEGlassFish . Это прототип, написанный для этой серии менее чем за час с использованием среды IDE NetBeans . Однако мы передадим детали создания проекта, чтобы не упускать из виду приз: использование SoapUI и Ant , создание отчетов JUnit, интеграция с CI и покрытие кода.

Исходный код для интерфейса сессионного компонента AccountManager:

package com.stelligent.biz.ws;

import java.util.Collection;

import javax.ejb.Remote;

import com.stelligent.ent.jpa.Account;
/**
*
* @author msubbarao
*/
@Remote
public interface AccountManager
{
public Account create(Account info);
public Account update(Account info);
public void remove(Account info);
public Account[] findAllAccounts();
public Account findByUsername(String username);
}

Класс реализации для Account Manager с аннотациями для веб-сервисов:

package com.stelligent.biz.ws;

import javax.ejb.Stateless;
import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.persistence.*;

import com.stelligent.ent.jpa.Account;

import java.util.*;
/**
*
* @author msubbarao
*/
@WebService(name="AccountManager", serviceName = "AccountManagerService", targetNamespace = "urn:AccountManagerService")
@SOAPBinding(style = SOAPBinding.Style.RPC)
@Stateless(name="AccountManager")
public class AccountManagerBean implements AccountManager
{
@PersistenceContext
private EntityManager manager;

@WebMethod
public Account create(Account info)
{
this.manager.persist(info);
return info;
}


/**
* Updates the Account entity.
*
* @param info the Account object used to update.
* @return the info object.
*/
@WebMethod
public Account update(Account info)
{
return this.manager.merge(info);
}

/**
* Removes the Account entity.
*
* @param info the Account object used to update.
*/
@WebMethod
public void remove(Account info)
{
this.manager.remove(this.manager.getReference(Account.class, info.getUserid()));
}

/**
* Retrieves all the Account entities as an array.
*
* @return the objects as a Account array.
*/
@WebMethod
public Account[] findAllAccounts()
{
Query query = this.manager.createQuery("SELECT o FROM Account o");
java.util.List<Account> accounts = new java.util.ArrayList<Account>();
java.util.Iterator<Account> iter = query.getResultList().iterator();
while (iter.hasNext())
{
accounts.add(((Account) iter.next()));
}
return (Account[]) accounts.toArray(new Account[accounts.size()]);
}



/**
* This method retrieves the Account entity info using the primary key.
*
* @param username the String
* @return the object as a AccountInfo or null if not found.
*/
@WebMethod
public Account findByUsername(final String username)
{
try
{
return (Account) this.manager.find(Account.class, username);
}
catch (Exception e)
{
return null;
}
}


}

 

Давайте рассмотрим каждый из них более подробно.

1. SoapUI и Ant
SoapUI предоставляет инструменты командной строки для запуска различных тестов. Для запуска функциональных тестов нам нужно использовать класс com.eviware.soapui.tools.SoapUITestCaseRunner , который принимает путь к файлу проекта SoapUI, содержащему тесты и ряд параметров:

Поскольку бегун запускается из командной строки, мы будем использовать задачу exec в Ant. SoapUI поставляется со сценариями, основанными на операционной системе, в которой вы его установили, testrunner.bat или testrunner.sh . (Если вы используете машину Windows, а ваша машина сборки использует другую операционную систему, например UNIX, вам нужно будет внести изменения в этот сценарий.)

Давайте начнем с того, что выписаем, что нам нужно добавить в файл сборки Ant, чтобы Запустите эти функциональные тесты на компьютере с Windows. Нам нужно определить цель, которая будет запускать тесты; для ясности мы также укажем свойства, которые прояснят смысл указанных местоположений файлов:

а. Укажите свойства для местоположения SoapUI и файла проекта

<property name="soapui-location" location="C:\\Program Files\\eviware\\soapUI-1.7.6\\bin"/>
<property name="soapui-project-xml-location" location="Weather-soapui-project.xml"/>

б. Определите цель для запуска функциональных тестов.

<target name="run-soapui-tests" description="runs all functional SoapUI  tests">
<exec dir="${soapui-location}" executable="cmd.exe" failonerror=”true”>
<arg line="/c testrunner.bat -j -f${reports} -r -a ${soapui-project-xml-location}"/>
</exec>
</target>

На этом этапе мы откроем командное окно и запустим soapui-тесты. Выход:

2. Отчеты JUnit При
добавлении параметра -j в приведенном выше аргументе Ant создаются отчеты XML. SoapUI отображает TestSuites на пакеты отчетов и TestCases, чтобы сообщать TestCases . Отчеты XML, сгенерированные из задачи Ant, могут быть дополнительно преобразованы с помощью задачи Ant junitreport:

<target name="generate-report" description="creates JUnit-compatible xml reports">
<junitreport todir="${reports}">
<fileset dir="${reports}">
<include name="TEST-*.xml"/>
</fileset>
<report format="frames" todir="${reports}\\html"/>
</junitreport>
</target>

Это производит вывод как это:

3. Интеграция с CI.
Непрерывная интеграция — это компиляция, тестирование, проверка и развертывание на сервере приложений при каждой фиксации. Преимущество CI простое: когда вы часто создаете программное обеспечение, вы рано обнаружите дефекты кода. Доступно множество CI-серверов, как с открытым исходным кодом, так и коммерческих. Hudson — это CI-сервер с открытым исходным кодом с очень простой настройкой, всего три шага (да, вы правильно меня поняли, всего три шага):
a. Загрузите последнюю версию Hudson.
б. Откройте окно командной строки и введите java -jar hudson.war
c. Откройте браузер и перейдите по ссылке http: // localhost: 8080
Это все, что вам нужно, чтобы настроить сервер CI менее чем за две минуты. Вы можете прочитать больше о настройке Hudson и загрузке всех плагинов и многое другое по ссылке здесь .

Как мы теперь увидим, очень просто запустить функциональные тесты, которые мы написали в этой серии, после того, как мы развернем наше приложение на сервере. Если все тесты будут выполнены, файл сборки будет генерировать отчеты JUnit; Эти отчеты могут быть интегрированы в нашу информационную панель CI. Если какой-либо из тестов не пройден, мы завершаем сборку, используя атрибут failonerror задачи Ant. В зависимости от того, как был настроен CI, каждый в команде может получить электронное письмо или текстовое сообщение в случае сбоя сборки.

Давайте посмотрим, как мы запускаем эти функциональные тесты и интегрируем их с CI.
После того, как вы установили и запустили Hudson, вы должны добавить свои проекты в Hudson в качестве Jobs, чтобы они могли отслеживать эти проекты. Мы собираемся создать одну работу, которая будет работать в полночь.

1. Перейдите на главную страницу Hudson и нажмите New Job. Это откроет страницу как таковую:

2.Введите описательное имя, так как это имя будет отображаться на панели управления Hudson. Выберите « Построить проект программного обеспечения свободного стиля ». Нажмите кнопку ОК, и вы увидите еще один экран

3. На этом экране выберите управление исходным кодом. Вам будет представлен подробный экран, основанный на вашем SCM. Заполните все детали. Хадсону нужна вся эта информация, чтобы извлечь все ресурсы исходного кода для создания проекта.

4. Hudson может быть настроен для построения вашего проекта по расписанию или периодически. В нашем случае работа должна выполняться в полночь. Итак, вот изменения, необходимые для выполнения работы на ночной основе.

5. Next step is to configure Hudson to properly build our project using Ant. As you can see from the image above, Hudson provides many ways for building your project. In the PetStore case, I am setting up some environment variables and therefore using a simple batch file.

6. In the Post-Build Actions section, we will select the Publish JUnit test result report option. We are generating the JUnit reports from SoapUI. Specify a location for where Hudson can find the XML files that JUnit produces when run through Ant.

7. Now, that we have Hudson setup. we will force the build. This will cause Hudson to checkout all the source code artifacts from SCM, and initiate a build. In my case the build failed; reason being SoapUI generates the JUnit reports with no package name, Hudson complains about the same and throws a NPE. A possible workaround to publishing the JUnit reports, is to use the Achive the artifacts option in Post-build Actions. Here are the Hudson screenshots and the output:

Hudson console output:

4. Code Coverage using Cobertura
There are many open source tools available to identify line and branch coverage. By using these, you can find areas in your test code that need more tests. In most cases, when a developer checks in something, the commit build runs, which in turn runs the unit tests and some integration tests. A secondary build, often run at night, can instrument your code for code coverage reporting, deploy to the application server, and run the available tests. This will create a detailed report that the team can see first thing in the morning.

Cobertura is a code coverage analysis tool for Java. You can use it to determine what percentage of your source code is exercised by your unit tests. Cobertura adds instrumentation directly to the bytecode and is easy to integrate with Apache Ant. It comes with its own Ant task definitions for you to use.

The steps to follow here are simple:
1. Change the build file to instrument the code. Here are the changes we need in the build file to instrument our source code:

<target name="instrument" depends="compile">
<cobertura-instrument datafile="${cobertura-data-dile}" todir="${classes.dir}">
<fileset dir="${classes.dir}">
<include name="**/*.class" />
</fileset>
</cobertura-instrument>
</target>

2. Deploy the instrumented code to GlassFish. Once the code is instrumented, deploy it your application server. The ant task provided here is for GlassFish V2 application server.

<target name="gf2-deploy-ear" depends="instrument">
<echo message="Deploying webservices-samples"/>
<taskdef name="sun-appserv-deploy" classname="org.apache.tools.ant.taskdefs.optional.sun.appserv.DeployTask"
classpath="${GLASSFISH_HOME}/lib/sun-appserv-ant.jar" />
<sun-appserv-deploy user="admin"
passwordfile="${passfile}"
host="localhost" port="8484"
file="${ear-file-name}" asinstalldir="${GLASSFISH_HOME}"/>
</target>

3. Generate a report. Cobertura stores coverage information to a file called cobertura.ser. Using the report task, Cobertura can generate coverage reports in either HTML or XML format.

<target name="coverage-report" depends="run-soapui-tests">
<cobertura-report datafile="${cobertura-data-dile}" srcdir="${src.dir}" destdir="${coverage.xml.dir}" format="xml"/>
<cobertura-report datafile="${cobertura-data-dile}" srcdir="${src.dir}" destdir="${coverage.html.dir}" />
</target>

5. Integrate these reports with Hudson using the Cobertura plug-in.

Installing a Hudson plug-in is as simple as installing Hudson. Download the latest version of the plug-in from here,
click the Manage Hudson link from Hudson’s homepage. Next, click the Manage Plugins link, where you can upload the plug-in archive file. Once the plug-in has been installed, you’ll have to restart Hudson. If everything goes well, you should be able to see a screen like:

Once you have downloaded and installed the cobertura plug-in, you need to configure your Job to use the reports generated. Click configure on PetStore_Nightly Job, this will display the Job configuration. Choose Publish Cobertura Coverage Report, and provide the file name pattern that can be used to locate the cobertura xml report files.

 

6. Finally, lets force a build and see the results.

PetStore Dashboard:

 

Cobertura Coverage Report in Hudson:

 

Since we also generated the HTML reports for cobertura within the Ant task, we can take a look at these as well:

P.S: I should mention that when deploying instrumented code using cobertura to an application server, cobertura doesn’t update the data file unless the application server is shutdown. So, I used the same workaround as mentioned in the cobertura web site, instead of stopping and starting the server each and every time. I placed the following code in one of the Session Beans, published this as a web service, added a test case for this method and this was the last test case called within SoapUI.

try {
String className = "net.sourceforge.cobertura.coveragedata.ProjectData";
String methodName = "saveGlobalProjectData";
Class saveClass = Class.forName(className);
java.lang.reflect.Method saveMethod = saveClass.getDeclaredMethod(methodName, new Class[0]);
saveMethod.invoke(null,new Object[0]);
} catch (Throwable t) {
}

In this part, you learned about the Ant tasks for running tests written using SoapUI, generating JUnit reports, integrating with CI, and getting code coverage using Cobertura. I’ve used some popular open source tools like Ant, Hudson, Cobertura and showed you how easy it is to set up a CI environment using these tools and run functional tests for your web services written using SoapUI.

You can go ahead start building web services with great confidence! Enjoy.