• Nenhum resultado encontrado

2.4 Abordagens de teste de componentes

2.4.2 Metadados

O uso de metadados incorporados aos componentes tem o objetivo de fornecer ao usuário informações adicionais sobre o componente. Essas informações podem variar desde diagramas de análise, projeto, até informações detalhadas sobre testes realizados.

Para o uso de metadados em componentes, Orso et al. (2000b) definem três propriedades bá- sicas: o desenvolvedor do componente deve estar envolvido na produção dos metadados; os me- tadados devem ser empacotados com o componente; e o desenvolvimento e a apresentação dos metadados devem ser apoiados por ferramentas.

Bundell et al. (2000) propõem que se forneçam informações adicionais sobre o componente para apoiar as atividades de análise e teste. Sugerem também a preparação de especificações de teste que descrevam implementações do componente, interfaces fornecidas para cada implementa- ção e um conjunto de teste apropriado para testar as interfaces.

Um dos trabalhos encontrados na literatura propõe uma estratégia de teste na qual o desen- volvedor fornece ao cliente informações sobre a atividade de teste estrutural desenvolvida com o componente, uma vez que o cliente não possui o código fonte para fazer este tipo de teste. Para via- bilizar essa estratégia foi proposta a ferramenta FATEsC (Ferramenta de Apoio ao Teste Estrutural de Componentes)(Teixeira et al., 2007b), que é uma extensão da ferramenta JaBUTi (Vincenzi et al., 2006).

A ferramenta FATEsC possui duas perspectiva: a do desenvolvedor e a do cliente. Na pers- pectiva do desenvolvedor do componente é possível: criar casos de teste para cada método público do componente; definir, textualmente, para cada caso de teste as suas características, que poderão auxiliar o usuário do componente a obter a cobertura apontada; e empacotar com o código do com- ponente em um arquivo de extensão .JAR, as medidas de cobertura obtidas com a execução dos casos de teste e as descrições informais dos casos de testes (Teixeira et al., 2007a).

Na perspectiva do cliente do componente é possível: criar casos de teste para cada método pú- blico da aplicação no formato JUnit; comparar as medidas de cobertura obtidas com as fornecidas nos metadados; ver as descrições de cada caso de teste do desenvolvedor e, como apoio à análise de cobertura, marcá-los como não-executável (infeasible) se necessário (Teixeira et al., 2007a).

A proposta é que o desenvolvedor realize o teste estrutural e a ferramenta gere metadados sobre o teste. Os metadados produzidos pela ferramenta são: medidas de cobertura obtidas para cada caso de teste (por método público) para os critérios implementados pela ferramenta JaBUTi; e uma descrição informal para cada caso de teste (Teixeira et al., 2007a). Os metadados são então empacotados junto com o componente e disponibilizados aos clientes do componente.

O cliente deve criar sua aplicação utilizando componentes com os metadados disponíveis e desenvolver casos de teste para a aplicação completa. Ao executar os casos de teste, a ferramenta FATEsC gera um relatório com a cobertura de cada componente a partir dos testes da aplicação completa. O relatório inclui uma comparação com a cobertura alcançada pelo desenvolvedor do

CAPÍTULO 2. TESTE DE COMPONENTES DE SOFTWARE 16 componente. Essas informações devem auxiliar o usuário do componente a avaliar a adequação dos seus próprios conjuntos de testes em exercitar os requisitos estruturais do componente.

Pode haver situações em que alguns requisitos de teste estrutural dos componentes nunca serão cobertos com os casos de teste da aplicação, pois alguma restrição da aplicação limitou certos tipos de entrada. Neste caso, o cliente do componente pode selecionar o caso de teste relacionado a este requisito e marcá-lo como não-executável. Após fazer essa marcação, o relatório de cobertura será atualizado com a nova cobertura alcançada.

Briand et al. (2006) também apresentaram um trabalho relacionado ao uso de metadados para apoiar o teste de componentes. O desenvolvedor gera restrições CSPE (Constraints on Succeeding and Preceding Events) para as operações das interfaces do componente. O desenvolvedor tam- bém é responsável por implementar métodos embutidos para facilitar o controle e observação do componente.

As restrições CSPE são definidas como uma 3-tupla (operação precedente, operação sucessora, predicado), que indica que uma chamada a uma operação sucessora pode ser executada após a chamada à operação precedente. A 3-tupla (op1, op2, true), por exemplo, indica que a operação op2 sempre pode ser chamada após op1 (sempre válido). A 3-tupla (op2, op5, false) indica que a operação op5 nunca pode ser chamada após op2 (nunca válido). A 3-tupla (op3, op7, p) indica que a chamada de op7 após op3 é possível dependendo do valor do predicado p (possivelmente válido ou inválido). Com essas restrições é possível determinar sequências de pares de operações que podem ser invocadas e determinar sequências de teste de pares de operações para cobrir os critérios de cobertura sempre válido, sempre inválido, possivelmente válido e possivelmente inválido.

Considerando-se algumas operações de uma pilha, por exemplo, pode-se definir algumas res- trições CSPE. A restrição (init, push, true) indica que sempre é possível inserir um ele- mento na pilha após sua inicialização. A restrição (init, pop, false) indica que nunca é possível retirar um elemento da pilha após sua inicialização. Já a restrição (pop, pop, size) indica que retirar um elemento da pilha após um elemento já ter sido retirado pode ser possível ou não, dependendo do valor do predicado size que representa a quantidade de elementos da pilha. Se size for 0 então não é possível, se for maior do que 0 então é possível.

Algumas das abordagens de teste de componentes mencionadas anteriormente resolveram par- cialmente a limitação trazida pelo encapsulamento dos componentes, mas nem todas elas podem ser reusadas diretamente para o teste de serviços. Diversas abordagens baseiam-se na manipulação do código objeto do componente, como o bytecode Java, por exemplo, para apoiar o teste estrutural ou aumentar o controle e observação do estado interno do componente por meio da introdução de uma interface de teste. Essas estratégias, entretanto, não podem ser aplicadas no teste de serviços, mesmo os que estão escritos em Java, pois nem o bytecode está disponível para seus clientes. A invocação dos serviços é feita apenas remotamente e eles não são fisicamente integrados à aplica- ção.

CAPÍTULO 2. TESTE DE COMPONENTES DE SOFTWARE 17