• Nenhum resultado encontrado

Passo 5: Repetir

3.3 Teste do comportamento Excepcional

3.3.3 Framework

Esta seção tem por objetivo apresentar a ferramenta desenvolvida com o objetivo de

dar suporte a abordagem proposta. Para isto, foi desenvolvida uma extensão do JUnit

framework chamada JUnitE.

O JUnitE permite a definição de fluxos excepcionais esperados em termos do local

onde a exceção é lançada, os locais intermediários onde passam antes de atingir o seu

tratador e o local onde a exceção é tratada. Também permite a verificação em tempo

de excecução os resultados obtidos nos testes do comportamento excepcional de uma

aplicação. A extensão também permite a verificação de transformações de exceções

mesmo que não haja o encapsulamento da exceção original na nova exceção.

A figura

3.11

mostra a estrutura do JUnitE. A classe principal é a JunitETestCase

nesta, estão concentradas as adaptações para fornecer meios para a verificação dos tes-

tes excepcionais. Para a criação de um teste excepcional o caso de teste deve estender

diretamente de JunitETestCase. O aspecto ExceptionLogAspect é responsável por moni-

3.3. TESTE DO COMPORTAMENTO EXCEPCIONAL

Figura 3.11 Visão jUnite tool

torar e a classe FileWriterUtil de salvar o log de execução dos fluxos excepcionais para a

posterior verificação. As anotações @PartialSequencialMode e @FullSequencialMode

indicam o tipo de verificação desejada no teste excepcional seguindo o modelo da seção

3.3.1onde @PartialSequencialMode indica a possibilidade de omissão de elementos do

fluxo excepcional e @FullSequencialMode indica que tanto o fluxo excepcional definido

quanto o obtido pela execução caso de testes devem ser iguais contrário, o teste deverá

falha. Caso um caso de teste não seja anotado por nenhuma destas duas, o modo de

verificação parcial é utilizado por padrão. As anotações @ForceException e @Force-

ExceptionOnContructor indicam que um teste excepcional deve forcar o lançamento de

uma exceção e devem ser usadas em conjunto com a anotação @Test do JUnit. Através

do pré-processamento na classe AspectGenerator estas anotações são utilizadas para a

3.3. TESTE DO COMPORTAMENTO EXCEPCIONAL

geração de aspectos que forçam o lançamento de uma exceção de acordo com os parâ-

metros fornecidos.

A Figura

3.12

podemos observar um exemplo de teste excepcional escrito para o

JUnitE. Neste exemplo, a definição do fluxo excepcional esperado é definido como um

array de string (linhas 13-18) que segue algumas convenções para indicar o tipo de

exceção (linha 14), o local onde a exceção é levantada (linha 15), locais intermediários

por onde a exceção é propagada (linha 16) e o local onde é tratada (linha 17). A or-

dem dos elementos nesta matriz indica a ordenação deste fluxo, desde o local onde a

exceção é levantada, até o local do tratamento desta exceção. Os métodos exception,

raiseSite, intermediateSite e handlingSite fazem parte da sintaxe para

a definição do fluxo excepcional. O método exception indica o tipo da exceção es-

perada, raiseSite indica o local onde a exceção é lançada, intermediateSite

é utilizado para indicar os locais intermediários e handlingSite para indicar o local

onde a exceção é capturada. Após definido o fluxo excepcional, o array definido deve

ser passado como parâmetro ao método setExceptionPath(String[]) antes da

execução do caso de teste.

O método testEHFlowDAOServlet (linha 10) implementa o caso de teste uti-

lizando a anotação @Test do JUnit (linha 9). Como em qualquer abordagem de teste

funcional, o teste é responsável por desencadear a condição de erro que resultará na exce-

ção esperada, no nosso exemplo a chamada ao método myServlet.service (linha

25).

Em alguns casos torna-se necessário redefinir o comportamento do resultado de um

teste. Por exemplo, podemos ter uma determinada situação em que o testador descobre

um erro devido à ocorrência de uma exceção não tratada que ocasiona a interrupção de

forma não esperada da execução do sistema. Neste caso ele poderá especificar o fluxo

excepcional indesejado para que, ao longo da evolução do sistema, seja possível verificar

se este fluxo inesperado ainda ocorre. Para isso deve-se especificar um teste com o fluxo

excepcional não esperado e o método result deverá ser redefinido da seguinte forma:

//Método da superclasse, o override é opcional.

//Use para modificar o resultado do teste.

public void result() {

//Ex: se uma exceção especificada ocorrer,

//o teste não deverá passar

assertTrue(!verifyResults());

}

3.3. TESTE DO COMPORTAMENTO EXCEPCIONAL

1 - public class MyTestCase extends JuntETestCase {

2-

3-

//This annotation forces an exception

4-

//to be trigged

5 -

@ForceException(exception="java.io.IOException",

6 -

method = "MyDAO.insertData",

7 -

methodReturnType = "void",

8 -

methodParType = "java.lang.String")

9 -

@Test

10-

public void testEHFlowDAOServlet() {

11-

12-

//Specifies the desired exception path

13-

String[] trace = new String[]{

14-

exception("java.io.IOException"),

15-

raiseSite("MyDAO.insertData "),

16-

intermediateSite("myFacade.insertData"),

17-

handlingSite("myServlet.service")

18-

};

19-

20-

//Sets the exception path

21-

super.setExceptionPath(trace);

22-

23-

//Calls the element that should handle

24-

//the exception

25-

myServlet.service();

26-

}

27-}

Figura 3.12 Exemplo de caso de teste

a execução de um caso de teste.

O JUnitE também permite a geração de um arquivo de log após a execução de testes.

Abaixo temos um exemplo ilustrativo do arquivo gerado:

1 - #pkg.MyException

2 - pkg.raisingSite

3 - pkg.intermediateSite1

4 - pkg.intermediateSite2

5 - @pkg.catchingSite

Neste arquivo, o símbolo # representa o tipo de exceção (linha 1), na linha subse-

quente (linha 2) temos o local onde a exceção foi levantada, neste caso

pkg.raisingSite. Sempre a linha após a exceção define o local onde a exceção

3.3. TESTE DO COMPORTAMENTO EXCEPCIONAL

foi levantada. Nas linhas 3 e 4 temos a definição dos locais intermediários por onde

a exceção trafega. Por fim, temos na linha 5 o local onde a exceção é tratada definida

pelo símbolo @. Caso este símbolo não apareça em um fluxo excepcional significa que

a exceção não foi capturada ocasionando o término da execução do caso de teste. Em

um mesmo arquivo de log podemos ter vários blocos similares ao exemplo. Isto indica

a presença de múltiplos fluxos excepcionais durante a execução do teste. Este arquivo

contém todas as informações do fluxo de exceção produzido pela execução do caso de

teste. Esta informação é importante pois com ela é possível acompanhar as mudanças

entre as versões de um sistema.

Figura 3.13 Resultado de um caso de teste.

Porém a verificação manual do log é opcional para a abordagem proposta. Para um

teste passar não é necessária avaliação manual deste arquivo. Está avaliação é realizada

automaticamente pelo JUnitE e a apresentação do resultado do teste é similar ao JUnit

o qual representa um teste que passou através de uma barra verde e barra vermelha para

testes que falharam. Na figura

3.13podemos observar o resultado de um teste no JUnitE.

Uma falha ocorre quando o fluxo excepcional, que é registrado no log de execução,

não for igual ao fluxo excepcional especificado. Esta verificação é realizada automatica-

mente comparando-os durante a execução do caso de teste.

O JUnitE também permite a criação de casos de teste que verifiquem o remapea-

mento de exceções de um tipo para outro como no exemplo da Figura

3.14. Esta figura

mostra a execução dos métodos a, b e c nesta ordem. O método c lança uma exceção

3.3. TESTE DO COMPORTAMENTO EXCEPCIONAL

Figura 3.14 Transformação de tipo uma exceção.

do tipo IOException e a propaga até o método b. O método b captura essa exceção

e a remapeia em uma exceção do tipo MyException que é posteriormente capturada

pelo método a. Infelizmente o JUnit não suporta este tipo de definição.

Documentos relacionados