Labs SD >

Web Services Tests

Objetivos

Projeto:

 

Web Service Tests

Para garantir a qualidade do código do Web Service, é necessário produzir testes que incidem sobre diferentes módulos e aspetos:

Vamos então analisar as ferramentas de teste utilizadas.

 

JUnit

O JUnit é uma biblioteca Java para escrever testes ao código.

O Maven já vem preparado para executar testes unitários, na fase test do ciclo de vida,
mas é necessário adicionar a dependência para a biblioteca JUnit:

    ...
    <!-- JUnit -->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
      <scope>test</scope>
    </dependency>

As classes de testes são aquelas cujo nome, por omissão, termina com Test. Devem ser arrumadas na pasta src/test/java do projeto.

Uma classe de testes tem a seguinte estrutura:

package example.test;

import org.junit.*;
import static org.junit.Assert.*;

/** Test suite */
public class ExampleTest {

    // static members

    // one-time initialization and clean-up
    @BeforeClass
    public static void oneTimeSetUp() {
    }

    @AfterClass
    public static void oneTimeTearDown() {
    }

    // members

    // initialization and clean-up for each test
    @Before
    public void setUp() {
    }

    @After
    public void tearDown() {
    }

    // tests
    @Test
    public void test() {

        // assertEquals(expected, actual);
        // if the assert fails, the test fails
    }
}

No JUnit 4 são utilizadas anotações para definir qual o papel dos métodos. Os métodos anotados com @Test são testes individuais.
@Before e @After são executados antes e depois de cada teste. @BeforeClass e @AfterClass são executados apenas uma vez para o conjunto de testes da classe.

As funções de assert permitem verificar o resultado do teste: assertEquals(expected, actual); expected é o valor esperado, actual é o valor que resultou da execução

O plug-in de Maven que corre os testes chama-se Surefire.
Os exemplos seguintes mostram como correr os testes e como controlar quais os testes a executar.

// to compile and execute all tests
$ mvn test

// to execute only a specific test class
$ mvn test -Dtest=PingIT

// to execute only a specific test
$ mvn test -Dtest=PingIT#testPing

// you can also use wildcards (the example below will match classes starting with P)
$ mvn test -Dtest=P*

// to skip integration tests
$ mvn package -Dtest.skip=true
Para mais informação sobre JUnit, consultar:

 

Testes de Integração

Os testes de integração (integration tests) verificam o comportamento de vários componentes do sistema.
Por outras palavras, verificam se os componentes se integram bem uns com os outros.

No contexto dos Web Services, os testes de integração são um programa cliente que faz invocações remotas a um programa servidor, verificando o contrato das operações remotas definidas no WSDL.
Assume-se que todos os Web Services já foram previamente lançados antes de correr os testes de integração.

O JUnit é também ser usado para fazer testes de integração.

O Maven executa os testes de integração na fase verify do ciclo de vida. É necessário configurar um plug-in da forma ilustrada abaixo:

    ...
            <plugin>
                <artifactId>maven-failsafe-plugin</artifactId>
                <version>2.19.1</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>integration-test</goal>
                            <goal>verify</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

Por convenção, as classes de testes de integração terminam com (IT). Devem ser também arrumadas na pasta src/test/java do projeto.

Uma vez que os testes de integração efetuam invocações remotas, necessitam de criar um Stub de invocação do serviço. O excerto de código abaixo mostra a criação de chamado port. Este objecto, dado que é um membro da classe, estará acessível em todos os métodos de teste.

    ...

    // static members

    private static CalcPortType client;


    // one-time initialization and clean-up

    @BeforeClass
    public static void oneTimeSetUp() {
        client = new CalcClient(uddiURL, wsName);
    }

    @AfterClass
    public static void oneTimeTearDown() {
        client = null;
    }

    ...

    @Test
    public void testPing) {
        final int result= client.sum(1, 2);
        assertEquals(3, result);
    }

    ...

No exemplo acima o endereço do serviço (endpoint address) é obtido de forma dinâmica a partir do UDDI, que se assume ser consultado pelo construtor do objeto cliente.

 

Testes com exceções

Os testes de integração terão que lidar com exceções dos Web Services, quer as geradas na aplicação, quer as geradas na comunicação.

Para implementar testes de exceções existem duas abordagens: com expected na anotação @Test ou não.

    ...

    @Test(expected=ExampleException.class)
    public void testExceptionWithAnnotation() throws Exception {

        // ... code that must throw an exception

        // JUnit expects the exception declared in the annotation
        // if it is not thrown, the test fails
    }

    ...

    @Test
    public void testExceptionWithoutAnnotation() throws Exception {
        try {

            // ... code that must throw an exception

            fail();
        } catch (Exception e) {
            // expected
            // check message of exception etc
        }
    }

    ...

Testes com objetos simulados por JMockit

O JMockit é uma biblioteca Java para gerar dinamicamente objetos mock para testes (mock pode-se traduzir por fictício ou simulado).
Os objectos mock têm um comportamento pré-determinado e substituem objectos reais que são muito "caros" de obter ou configurar para determinadas situações. Por exemplo, os objectos mock podem ser usados para simular o servidor UDDI ou para lançar erros de Web Services que são difíceis de causar na prática.

Mais informação:

 


Resumo

Para testar componentes individuais, fazer testes unitários (Test) com JUnit.
Para simular objectos remotos ou outras dependências externas em testes unitários, usar JMockit.

Para testar a integração de componentes, fazer testes de integração (IT) com JUnit.
Dado o seu objetivo de verificar o comportamento do sistema como um todo, os testes de integração não devem usar objectos simulados.

 


Exercício

O objetivo é construir testes para um dos serviços do Projeto.

  1. Testes unitários
  2. Testes de integração

Bons testes! :)


© Docentes de Sistemas Distribuídos, Dep. Eng. Informática, Técnico Lisboa