Chapitre 2: Quelle méthode pour rendre compte des dynamiques professionnelles de la
1. Une « demande » à façonner 68
1.2. Une recherche clinique de type ethnographique 76
Os testes de integração do núcleo envolvem exercitar a execução conjunta de objetos pertencentes a diferentes classes da LPS. Dessa forma, é possível verificar como está a colaboração entre os elementos (classes) que implementam a arquitetura base da linha de produto. Durante o desenvolvimento dos testes, é necessária a definição de Mock Objects para representar (simular) as variações que as classes do núcleo dependem. A Figura 44 ilustra um teste de integração que emprega um objeto mock.
Figura 44 - Classes envolvidas nos testes de ProdutoMBean.
A Figura 44 apresenta a classe de teste ProdutoMBeanTest. Essa classe depende de ProdutoMBean (alvo dos testes), elemento da camada de controle da LPS E-Commerce e que participa de operações como o cadastro de produto e adição de informações, bem como do processo de liberação de produtos. A classe ProdutoMBean interage com a classe de negócio ContextProdutoSBean, a qual utiliza a interface IProdutoSBean que faz parte da implementação do padrão Strategy usado na LPS (Seção 5.1.3). Nesse padrão pode existir a presença de classes reais que implementam IProdutoSBean e não estão representadas na figura, as quais são: ProdutoSBeanComAutorizacao (classe variável) e ProdutoSBeanSemAutorizacao (classe do núcleo). Contudo, para evitar o uso das instâncias concretas de IProdutoSBean, que podem estar disponíveis apenas na engenharia de aplicação, foi construído nos testes um mock com base na interface IProdutoSBean. A Figura 45 apresenta o código dos testes para a classe ProdutoMBean. Ela mostra no nível de código, a classe ProdutoMBeanTest. Nessa classe de teste é encontrado um atributo do tipo ProdutoMBean (linha 28) e outro atributo do tipo Mockery (linha 29). Além disso, é encontrado o construtor e o método suite() da classe de teste.
Figura 45 - Classe ProdutoMBeanTest.
A Figura 46 ilustra a definição dos métodos setUp() e tearDown() da classe ProdutoMBeanTest. No método setUp() é realizada a instanciação de ProdutoMBean e sobrescrito os métodos addMensagem() e cancelar() usados nessa classe, uma vez que os dois métodos citados acessam o contexto do
framework JSF quando existe uma aplicação real realizando operações como o
cadastro de produtos ou a liberação deles para estarem disponíveis na loja virtual. Por fim, no método setUp(), também é criado o objeto mock usado nos testes (linha 54).
A Figura 47 apresenta o método de teste testFinalizarCadastroProduto() da classe ProdutoMBeanTest. Esse método é responsável por testar a colaboração entre a classe ProdutoMBean e ContextProdutoSBean quando o método finalizarCadastroProduto() de ProdutoMBean é requisitado. O método de teste foi elaborado sabendo que no momento que é realizada a operação finalizarCadastroProduto() é usada uma instância da classe ContextProdutoSBean e o seu método cadastrar(). Em seguida, nesse método é empregado o método cadastrar() definido na interface IProdutoSBean. Dessa forma, caso nenhum problema ocorra durante a interação entre as classes ProdutoMBean e ContextProdutoSBean que depende de IProdutoSBean, o teste é realizado com sucesso.
Figura 47 - método testFinalizarCadastroProduto().
Como pode ser observado no método de teste, é criado um mock de nome “strategy” a partir da interface IProdutoSBean (linha 64) e a definição de que será possível criar mocks também com base em classes (linha 66). Com essa especificação, foi possível construir um mock para a classe Produto (linha 67). Em testFinalizarCadastroProduto(), é definido também um objeto do tipo
ContextProdutoSBean, repassando para o seu construtor o mock “strategy” no instante que é instanciado (linha 69). Sem o uso desse mock, seria necessário o uso de uma instância real de ProdutoSBeanComAutorizacao ou ProdutoSBeanSemAutorizacao, dependendo da estratégia escolhida, ou seja, se o produto precisa ou não de autorização após o seu cadastro. Na classe ContextProdutoSBean é empregado um objeto que implemente a interface IProdutoSBean para que, no momento do cadastro de um produto, possa ser usado o método cadastrar() definido nessa interface. No caso do método de teste analisado, é usado em ContextProdutoSBean o mock “strategy” que implementa IProdutoSBean. Para analisar o método cadastrar() dessa interface são definidas expectativas. No método de teste é informado que cadastrar() deve ser executado uma vez e receber como parâmetro uma classe CadastroDB (linhas 71 a 77). No caso dessas expectativas forem atendidas, significa que no momento que o método finalizarCadastroProduto() é requisitado, a classe ProdutoMBean conseguiu usar o método cadastrar() de ContextProdutoSBean que, por sua vez, conseguiu empregar o método cadastrar() da interface IProdutoSBean uma vez e pode receber como parâmetro um objeto do tipo CadastroDB. Para implementar as expectativas é usado o mock “strategy”, pois implementa a interface IProdutoSBean e, dessa forma, é possível
acessar o método cadastrar(). Além disso, o método
finalizarCadastroProduto() é chamado no método de teste (linha 77), assim como são verificadas as expectativas especificadas (linha 79). Por fim, com a classe ProdutoMBeanTest implementada, é possível executá-la de forma isolada ou em conjunto com outros casos de teste através do uso de uma suite de testes.
5.2.2.4 Testes de Sistema do Núcleo
Os testes de sistema para o núcleo não são executados durante a engenharia de domínio. Nessa fase existe apenas a construção dos testes, mas eles serão aplicados concretamente num produto derivado da LPS. A abordagem propõe a implementação dos testes de sistema através de templates que são usados para definir scripts de teste para a ferramenta Selenium IDE. Além disso, ela define que os templates podem: (i) conter código de teste que permanece inalterado para um
elemento (página de aplicação) mandatório ou (ii) podem apresentar uma parte fixa e outra parte variável que é customizada com base nas variabilidades selecionadas para um dado produto na engenharia de aplicação. A seguir, é encontrado um exemplo que ilustra a primeira forma de uso dos templates.
Figura 48 - Template TesteCadastroTipoProduto.xpt.
A Figura 48 apresenta o template TesteCadastroTipoProduto.xpt que contém o script de teste para um arquivo JSP chamado tipo_produto.jsp que é a página responsável pelo cadastro dos tipos dos produtos. Essa página é comum aos membros da LPS E-Commerce e não apresenta código variável. No template é observado o uso do método projectName() (linha 11), método criado para a
extensão do GenArch e que permite a inclusão do nome do projeto que conterá tanto o código referente à implementação de um produto (aplicação) como os seus testes. O nome do projeto fica armazenado na variável name (linha11) e aplicado num ponto específico do template (linha 12).
A Figura 49 apresenta um exemplo de template referente à segunda forma de implementação proposta na dissertação, isto é, os templates de teste apresentam trechos de código variável que são inseridos dependo das variabilidades escolhidas para um dado produto da LPS. Parte do código comum do template foi omitido por ser relativamente extenso, dificultando a visualização do script de teste. Na Figura 49 pode ser encontrado o uso do método projectName() para incluir o nome do projeto de um produto relacionado à LPS.
Figura 49 - Template TesteCadastroProduto.xpt.
É também usado no template o método featureConfigurations() que serve para recuperar as características relacionadas a uma característica. Esse método é usado duas vezes no script de teste. Na primeira, são recuperadas as características ligadas a ProductInformation (linha 17). No grupo de características obtidas existem as seguintes variabilidades: DetailedDescription, WarrantyInformation, Size, Weight e Availability. No método featureConfigurations() é analisado se certa característica foi selecionada (linha 19) e caso tenha sido selecionada é
verificado se o nome da característica é igual a WarrantyInformation (linha 20). Caso a condição seja verdadeira, é inserido no script final de uma aplicação derivada, o trecho para testar a definição da informação de garantia de um produto que será cadastrado (linhas 21 a 25). A verificação do nome da característica variável selecionada também é realizada para Size e Weight e caso elas estejam presentes num produto, são incluídos trechos de teste específicos referentes a cada uma delas no template. Por fim, o método featureConfigurations() é usado pela segunda vez (linha 31) para definir um trecho de código no script de teste caso a característica variável DetailedDescription esteja presente num membro da LPS.
5.2.2.5 Testes de Unidade e Integração de Produtos
Na abordagem deste trabalho é proposto que os testes de integração elaborados na engenharia de domínio da LPS sejam reexecutados como testes de regressão na engenharia de aplicação da linha de produto. Esse cenário requer que os casos de teste, originalmente voltados apenas para o núcleo, possam ser adaptados de maneira a permitir a aplicação de testes nos diversos produtos gerados na LPS, os quais são constituídos tanto por partes comuns como variáveis. A adaptação dos testes se caracteriza essencialmente pela retirada dos objetos
mock empregados nos testes do núcleo pelas implementações reais das variações
que dependem. Os testes de unidade elaborados durante a engenharia de domínio podem também ser reexecutados como testes de regressão. Caso seja necessário, novos testes de unidade podem ser criados para as classes que representam variantes concretas dos pontos de variação que possuem um papel crítico na LPS.
No que se refere à customização dos testes de integração, é apresentado na abordagem o uso de templates. A Figura 50 ilustra a implementação de um template baseado no teste de integração da classe ProdutoMBean do núcleo da LPS E-
Commerce (Seção 5.2.2.3). O template foi construído para atender a necessidade de
usar a implementação real referente à característica variável ContentApporval quando ela é definida para um produto da LPS. Caso essa característica não seja selecionada, o template gera uma classe de teste contendo, entre outras definições, o mock que garante a realização dos testes sem a necessidade de usar a classe que implementa a variação ContentApproval.
Figura 50 - (a) Template ProdutoMBeanProductTest.java.xpt.
A Figura 50 apresenta o template de teste
ProdutoMBeanProductTest.java.xpt. Nesse arquivo existe o uso do método
featureConfigurations() que é encontrado em várias partes do código e empregado para recuperar as subcaracterísticas da característica ContentManagement definidas para um produto. As subcaracterísticas possíveis são: ProductDatabaseManagement e PresentationOptions que são obrigatórias, como também ContentApproval que é opcional. No caso específico do template, a subacaracterísitca que interessa é apenas ContentApproval. Como pode ser observado, se essa característica variável for selecionada, a classe de teste herda da classe abstrata TestCase do JUnit. Caso contrário, o teste herda de MockObjectTestCase do jMock. Existem outros trechos que são definidos de acordo com a escolha de ContentApproval. Nesses trechos, a presença dessa variação num produto é analisada e se estiver presente é inserido, entre outras
definições, no código do método setUp(): (i) a instanciação de um objeto GenericDAOImpl para acessar diretamente operações do banco; (ii) a criação de um objeto Produto, assim como a definição de valores para seus atributos. Sem a presença da característica ContentApproval, é incluído no teste apenas a criação de um objeto do tipo Mockery para construção dos mocks, indicação de expectativas e a verificação delas. Embora não seja apresentado na figura, mas o template também garante a inclusão de pacotes específicos dependendo da presença ou não de ContentApproval num membro da LPS. Trechos de código comum referente a certos atributos e métodos como o suite() estão no template de teste.
Figura 51 - (b) Template ProdutoMBeanProductTest.java.xpt.
A Figura 51 ilustra outra parte importante relacionada ao template
ProdutoMBeanProductTest.java.xpt. Nela é encontrada a customização inicial do
método testFinalizarCadastroProduto(). Nessa parte do template é analisado se a subcaracterística ContentApproval faz parte de um produto da linha. Caso essa variação esteja presente é instanciado um objeto referente à classe ProdutoSBeanComAutorizacao. No caso de ContentApproval não for selecionado para um dado membro, é incluído o código referente à criação de um objeto mock a partir da interface IProdutoSBean, podendo, dessa forma, ser usado para substituir uma classe real que implemente essa interface como é o caso de ProdutoSBeanComAutorizacao. Além da criação desse mock, é incluído no teste a especificação que outros Mock Objects podem ser construídos a partir de classes, como também a construção de um mock para simular a classe Produto.
Figura 52 - (c) Template ProdutoMBeanProductTest.java.xpt
A Figura 52 apresenta a continuação da customização do método testFinalizarCadastroProduto(). O método featureConfigurations() é usado novamente para recuperar as subcaracterísticas de ContentManagement, sendo a que interessa no template é ContentApproval. No trecho de código existe a verificação da presença da subcaraterística ContentApproval e se ela foi selecionada na configuração de dado produto é incluído no método testFinalizarCadastro() os trechos de código referente: (i) ao cadastro de um produto da loja virtual pelo método finalizarCadastroProduto() de ProdutoMBean; (ii) a recuperação do produto cadastrado; (iii) a verificação se o produto foi realmente cadastrado na base de dados; e (iv) a exclusão do produto presente no banco, pois as operações que necessitavam desse elemento foram concluídas. Por outro lado, na situação em que ContentApproval não está na configuração de um membro da LPS, é inserido no teste o código referente à definição de expectativas através de um mock que torna possível os testes sem uma instância da classe ProdutoSBeanComAutorizacao.
5.2.2.6 Testes de Sistema de Produtos
Nos testes de sistema da abordagem deste trabalho é aplicado o Selenium
IDE. Os arquivos de entrada para essa ferramenta são constituídos por scripts em
formato HTML, os quais são gerados com base em templates desenvolvidos com o apoio dos recursos de criação e implementação de templates encontrados no GenArch. É necessário frisar que os testes de sistema das aplicações (produtos) da nossa abordagem, não precisam ser implementados manualmente, pois o conteúdo final dos scripts é gerado com base em templates. O trabalho envolvido está apenas na definição e preparação do conteúdo desses templates. A Figura 53 apresenta um exemplo de um script de teste de sistema para um produto da LPS E-Commerce.
Na Figura 53 é encontrado um script de teste para o Selenium IDE que foi criado a partir do template TesteCadastroProduto.xpt (Seção 5.2.2.4). Esse script está presente no projeto TestProduct, informação inserida no seu próprio código de teste (linha 8). Na configuração do produto derivado para o projeto TestProduct foram definidas as características variáveis WarrantyInformation e Size para permitir, no momento do cadastro de um produto, especificar as suas informações de garantia e o seu tamanho. Com base na presença de tais características, são inseridos trechos de código específicos no script de teste (destacado na figura).