Avançar para a área de conteúdo

ir para o conteúdo principal

developerWorks Brasil  >  Rational  >

Modos de usar o IBM Rational Functional Tester de forma mais eficiente

Estenda a estrutura de Engenharia de Software de Qualidade para melhorar a produtividade e facilitar a manutenção

developerWorks
Opções de documento

Opções de documento que necessitam de JavaScript não são exibidas


Classificar esta página

Ajude-nos a melhorar este conteúdo


Nível: Intermediário

Gou Nakashima, Yamato Software Development Laboratory (YSL), IBM Japan
Masahiro Ohkawa, Yamato Software Development Laboratory (YSL), IBM Japan

16/Jul/2009

O IBM Rational Functional Tester fornece recursos pelos quais os usuários podem automatizar os testes de seus aplicativos GUI de forma eficiente. A equipe de Engenharia de Software de Qualidade (QSE) IBM apresentou uma estrutura hierárquica, conhecida como estrutura QSE, para facilitar a manutenção. Essa estrutura usa o recurso de reconhecimento de objeto do Rational Functional Tester. Este artigo mostra como estender a estrutura QSE e usar os recursos do Rational Functional Tester para melhorar a produtividade também. Veremos também dicas para testes de aplicativos que suportam de forma eficiente múltiplos idiomas.

Introdução

O IBM® Rational® Functional Tester fornece recursos para automatizar testes. Para usar o recurso de gravação, grave uma atividade de teste e salve-a como script de teste. Depois, é possível executar o script de teste sempre que quiser executar o mesmo teste.

Se quiser inserir dados durante o teste, use o recurso de conjunto de dados de teste durante a gravação. Se for usado o recurso de conjunto de dados de teste, será possível mudar os dados de entrada antes de executar o script de testar, sem regravar a atividade de teste. Pode-se usar o recurso de ponto de verificação, pelo qual o Rational Functional Tester compara os valores reais com os valores esperados e depois gera um relatório com informações detalhadas que mostram se você obteve os resultados esperados ou não. Contudo, uma possível preocupação ao usar o recurso de gravação é que talvez seja necessário regravar a atividade de teste quando o aplicativo a ser testado é alterado.

Para minimizar seus esforços, a equipe de Engenharia de Software de Qualidade (QSE) IBM apresentou uma estrutura hierárquica, conhecida como estrutura QSE. A estrutura QSE isola os objetos GUI com etapas de teste. O Rational Functional Tester fornece o recurso Mapa de Objeto de Teste pelo qual podem ser obtidos objetos GUI. Pode-se executar ações no GUI usando os métodos dos objetos GUI. A estrutura QSE consiste nas três camadas seguintes.

  • A pasta appobjects contém os objetos GUI obtidos pelo recurso de mapa de objeto de teste.
  • A pasta tasks contém programas para executar ações GUI usando objetos na pasta appobjects. As ações GUI podem ser categorizadas e implementadas como tarefas. Por exemplo, o processo de login pode ser implementado como tarefa.
  • A pasta testcases contém programas que podem ser usados para executar casos de teste usando programas na pasta tasks e para registrar os resultados.

É possível usar a estrutura QSE para melhorar a sustentabilidade. Para obter mais informações sobre a estrutura QSE, consulte o item Estrutura Orientada a Objetos para o IBM Rational Functional Tester na seção Recursos.

Este artigo mostra como automatizar os testes de forma mais eficiente estendendo a estrutura QSE e utilizando os recursos do Rational Functional Tester, como conjunto de dados de teste e pontos de verificação. Este artigo também lhe dá algumas dicas sobre como testar aplicativos que suportam múltiplos idiomas.



Voltar para parte superior


Fornecer o método de controle de GUI

Analise o teste de aplicativo mostrado na Figura 1.


Figura 1. GUI de Aplicativo
Database Relationship Analyzer

Clique para ampliar

Nessa GUI, é possível selecionar os itens de menu Ações > Criar Conjunto, como mostrado na Figura 2. Esses objetos podem ser obtidos pelo recurso Mapa de Objeto de Teste.


Figura 2. Menus de aplicativo
menu command

Com o arquivo JAR fornecido com a estrutura QSE, é possível definir os métodos mostrados na Figura 3 e Listagem 1 para obter objetos GUI obtidos pelo recurso Mapa de Objeto de Teste.


Figura 3. Objetos de teste e programa para obter objetos GUI
code on left, Script Explorer on right

Clique para ampliar


Listagem 1. Programa para obter objetos GUI
 package appobjects;

import resources.appobjects.MainGUIHelper;
import ibm.widgets.*;
import ibm.widgets.ancestors.*;
import ibm.widgets.swt.*;

import com.rational.test.ft.*;
import com.rational.test.ft.object.interfaces.*;
import com.rational.test.ft.script.*;
import com.rational.test.ft.value.*;
import com.rational.test.ft.vp.*;

public class MainGUI extends MainGUIHelper {

  public ToggleWidget getActions() {
    TestObject to = actions(ANY, NO_STATE);
    return new ToggleWidget(to);
  }

  public ToggleWidget getActionsCreateNewSet() {
    TestObject to = actionsCreateNewSet(ANY, NO_STATE);
    return new ToggleWidget(to);
  }

  public ToggleWidget getConfigureGroupDiscoveryOptions() {
    TestObject to = configureGroupDiscoveryOptions(ANY, NO_STATE);
    return new ToggleWidget(to);
  }

  public ToggleWidget getCreateNewView() {
    TestObject to = createNewView(ANY, NO_STATE);
    return new ToggleWidget(to);
  }

  public SubitemWidget getGrdTree() {
    TestObject to = grdTree(ANY, NO_STATE);
    return new SubitemWidget(to);
  }

  public ToggleWidget getRunGroupDiscovery() {
    TestObject to = runGroupDiscovery(ANY, NO_STATE);
    return new ToggleWidget(to);
  }

  public ToggleWidget getRunTraceAnalyzer() {
    TestObject to = runTraceAnalyzer(ANY, NO_STATE);
    return new ToggleWidget(to);
  }

  // -----------------------------------------

  public void testMain (Object[] args) 
  {
     // O teste da unidade pode vir aqui
     // (será excluída na próxima vez que o ClasGenerator for executado)
  }
}

O programa na Listagem 2 simula o clique no menu Ações e depois no submenu Criar Conjunto.


Listagem 2. Exemplo de programa para clicar em um item de menu
 MainGUI mainGui = new MainGUI();
mainGui.getActions().click();
mainGui.getActionsCreateNewSet().click(); 

Como este exemplo mostra, é possível manipular facilmente seu GUI usando objetos GUI. Contudo, pode ser difícil descobrir que método é usado para executar uma ação GUI. A Figura 4 mostra um exemplo: pense no caso em que se dá um clique com o botão direito do mouse no nó da árvore.


Figura 4. Menu suspenso de um nó de árvore
right click TRACE_ANALYSIS

No caso de uma árvore, não é possível obter cada nó de árvore como objeto. Como mostrado na Figura 5, é preciso obter o objeto de árvore e usar um dos métodos para dar um clique com o botão direito do mouse em um nó da árvore.


Figura 5. Captura de um objeto de árvore
Capture a tree object

Se você não sabe como uma ação GUI é executada com um objeto GUI (como nesse exemplo), pode usar o recurso de gravação e então se referir ao programa gerado. Nesse exemplo, quando damos um clique com o botão direito do mouse sobre o nó enquanto gravamos, obtemos um programa como o mostrado na Listagem 3.


Listagem 3. Programa gerado para simular o clique com o botão direito do mouse sobre o nó da árvore
 public void testMain(Object[] args) 
{
	
	// Frame: Database Relationship Analyzer
	grdTree().click(RIGHT, atPath("SAMPLE->ORDER->TRACE_ANALYSIS"));
} 

Não é eficiente gravar esse tipo de programa na pasta tasks sempre que precisar dele. Em vez disso, é bom gravar um método genérico em uma classe para simular a ação acima, que herda a classe de objeto GUI na pasta appobjects. Esse tipo de classe não precisa ser criado como script do Rational Functional Tester: basta criá-lo como classe ™ Java. Crie uma pasta, como uma chamada apputils, para guardar esse tipo de classe. O programa na Listagem 4 mostra um método genérico para dar um clique com o botão direito do mouse sobre o nó da árvore. A classe MainGUIUtil herda a classe MainGUI. A classe MainGUI contém os objetos GUI na janela principal e é colocada sob a pasta appobjects. O método grdTree usado anteriormente para obter o objeto de árvore foi substituído por aquele definido na classe MainGUI, que é o método getGrdTree nesse exemplo.


Listagem 4. Exemplo de programa para simular clique com o botão direito do mouse sobre o nó da árvore
 public class MainGUIUtil extends MainGUI {
	public void rightClickView(String dbName, String setName, String viewName) {
		String s = dbName + "->" + setName + "->" + viewName;
		getGrdTree().click(RIGHT, atPath(s));
	} 

Usando métodos como esses, os programas na pasta tasks podem ser implementados intuitivamente com ações GUI.



Voltar para parte superior


Automação eficaz do processamento de entrada de dados

Com a estrutura QSE, as etapas para entrada de dados são as seguintes.

  1. Capture cada campo de entrada para obter seu objeto GUI usando o recurso Mapa de Objeto de Teste.
  2. Defina métodos para obter os objetos GUI.
  3. Determine os valores de entrada usando os métodos dos objetos GUI.

É possível executar com eficiência as ações de entrada de dados usando o recurso Datapool de Teste. Por exemplo, a Figura 6 mostra um GUI com vários campos de entrada. Considere a entrada de dados nessa GUI.


Figura 6. GUI de aplicativo com campos de entrada
Run the Trace Analyzer window

Após abrir esse GUI, comece a gravar, depois capture essa janela selecionando Inserir Comandos Acionados por Dados. Após isso, pause a gravação, dê entrada em dados simulados para ativar o botão OK, continue a gravação, clique em OK e pare a gravação. Ao fazer isso, é gerado o programa mostrado na Figura 7 e Listagem 5. Se quiser aplicar essa técnica com um assistente que consiste em múltiplos painéis, insira um comando acionado por dados em cada painel de modo a parametrizar todos os campos de entrada.


Figura 7. Programa gerado com o recurso Datapool de Teste
code on left, Script Explorer on right

Clique para ampliar


Listagem 5. Programa gerado
 package recordingobjects;
import resources.recordingobjects.RunTraceAnalyzerGUIRecordingHelper;
import com.rational.test.ft.*;
import com.rational.test.ft.object.interfaces.*;
import com.rational.test.ft.object.interfaces.SAP.*;
import com.rational.test.ft.object.interfaces.WPF.*;
import com.rational.test.ft.object.interfaces.dojo.*;
import com.rational.test.ft.object.interfaces.siebel.*;
import com.rational.test.ft.object.interfaces.flex.*;
import com.rational.test.ft.script.*;
import com.rational.test.ft.value.*;
import com.rational.test.ft.vp.*;

public class RunTraceAnalyzerGUIRecording extends RunTraceAnalyzerGUIRecordingHelper
{
  public void testMain(Object[] args) 
  {
    // Código Orientado por Dados inserido em 28/02/2009
    
    // 
    schemaName().setText(dpString("SchemaName"));
    tableName().setText(dpString("TableName"));
    startDate().setText(dpString("StartDate"));
    startTime().setText(dpString("StartTime"));
    endDate().setText(dpString("EndDate"));
    endTime().setText(dpString("EndTime"));
    ok().click();
  }
} 

Se for definido um método que contenha esse programa, outros programas poderão invocar o método. Quando se invoca o método, os valores definidos no datapool de teste são configurados nos campos apropriados. Como se vê na Figura 7 e Listagem 5, o método dpString é usado para obter um valor do datapool de teste.

Se for alterado o método de passar valores de entrada via argumentos de método, o método pode ser usado de forma genérica. Nesse exemplo, se usarmos os valores do datapool de teste para o horário de início e de término, e determinarmos outros valores de entrada dinamicamente por meio de argumentos de método, o método é definido como mostrado na Listagem 6.


Listagem 6. Exemplo de programa para dar entrada em dados de forma dinâmica
 public void runTraceAnalyzer(String schema,
			String table,
			String startDate,
			String endDate)
{
	schemaName().setText(schema);
	tableName().setText(table);
	startDate().setText(startDate);
	startTime().setText(dpString("StartTime"));
	endDate().setText(endDate);
	endTime().setText(dpString("EndTime"));
	ok().click();
} 



Voltar para parte superior


Automatizar a verificação de resultados

Caso sejam exibidos alguns resultados no GUI, é fácil comparar os valores reais com os esperados usando o recurso de ponto de verificação.

Verificação estatística de resultados

Por exemplo, se for esperado obter a tabela descrita na Figura 8, capture a tabela como ponto de verificação após começar a gravação e então pare a gravação. Isso produz o programa descrito na Figura 9 e na Listagem 7.


Figura 8. Tabela com alguns resultados
Table with 6 rows and two columns

Figura 9. Programa gerado com o recurso de ponto de verificação
Code on left, Script Explorer on right

Clique para ampliar


Listagem 7. Programa gerado
 package verificationpoints;
import resources.verificationpoints.TestResult1Helper;
import com.rational.test.ft.*;
import com.rational.test.ft.object.interfaces.*;
import com.rational.test.ft.object.interfaces.SAP.*;
import com.rational.test.ft.object.interfaces.WPF.*;
import com.rational.test.ft.object.interfaces.dojo.*;
import com.rational.test.ft.object.interfaces.siebel.*;
import com.rational.test.ft.object.interfaces.flex.*;
import com.rational.test.ft.script.*;
import com.rational.test.ft.value.*;
import com.rational.test.ft.vp.*;

public class TestResult1 extends TestResult1Helper
{
  public void testMain(Object[] args) 
  {
    table().performTest(ResultTableVP());
  }
}

Copie o programa acima para criar o método mostrado na Listagem 8. Se invocarmos o método, o Rational Functional Tester vai comparar automaticamente os valores reais com os esperados.


Listagem 8. Exemplo de método para verificar resultados
 public void verifyResult() {
	table().performTest(ResultTableVP());
} 

Verificar resultados dinamicamente

Se quiser mudar os valores esperados dinamicamente, use o método IFtVerificationPoint vpManual(java.lang.String vpName, java.lang.Object expected, java.lang.Object actual).performTest. O método vpManual tem três argumentos. O primeiro argumento é para definir o nome do ponto de verificação exclusivo para o projeto, o segundo, para definir um objeto esperado e o terceiro, para definir um objeto real. Se quiser comparar valores em uma tabela como nesse exemplo, use o objeto de classe com.rational.test.ft.vp.impl.TestDataTable no segundo e terceiro argumentos do método vpManual. É possível criar o objeto esperado como mostrado na Listagem 9. Também é possível especificar a regiãoa ser comparada, o que é feito com o método setComparisonRegions.


Listagem 9. Exemplo de programa para criar uma tabela de resultados esperados
 TestDataTable tbl = new TestDataTable();
tbl.setColumnHeader(0, "Table Name");
...
tbl.insert(new String[7], 0);
tbl.setCell(0, 1, "CUSTINFO");
...
TestDataTableRegions regions = new TestDataTableRegions();
regions.addRegion(TestDataTableRegion.allCells());
tbl.setComparisonRegions(regions.getRegions()); 

No exemplo seguinte, use o objeto de ponto de verificação como objeto esperado, que foi criado capturando a tabela GUI como ponto de verificação no exemplo anterior. Isso cria um objeto esperado. A seguir, modifique um valor do objeto. Para obter os valores reais, é possível usar o método getTestData(String testDataType) do objeto da tabela obtido pelo mapa de objeto de teste, como mostrado na Listagem 10. O argumento testDataType tem o valor do tipo de propriedade exibido na janela do ponto de verificação. É possível vê-lo na Figura 10. Nesse caso, esse valor é o "conteúdo visível".


Listagem 10. Exemplo de método para verificar um resultado de tabela
 Public void verifyResult() {
	TestDataTable tbl = (TestDataTable)ResultTableVP().getBaselineData();
	tbl.setCell(0, 1, "CUSTHIST2");
	vpManual("VP1", tbl, table().getTestData("visible contents")).performTest();
} 

Nesse programa, "CUSTHIST2" é definido em uma célula onde ficava "CUSTHIST". Executar esse método resulta em erro, e as informações mostradas na Figura 10 são obtidas.


Figura 10. Resultado de detalhe em um ponto de verificação (Tabela)
table of properties on left, values on right

Clique para ampliar

O exemplo anterior analisa o objeto da tabela. Os outros objetos podem ser comparados como mostrado na Tabela 1.


Tabela 1. Objetos que podem ser comparados
Tipo de GUIClasse
Árvorecom.rational.test.ft.vp.impl.TestDataTree
Listacom.rational.test.ft.vp.impl.TestDataList
Barra de menuscom.rational.test.ft.vp.impl.TestDataTree
Sequência de caracteresSequência

No caso do objeto de árvore, a Listagem 11 mostra um programa para adicionar um nó a um objeto de árvore capturado como ponto de verificação.


Listagem 11. Exemplo de método para verificar um resultado de árvore
 public void verifyResult() {
	TestDataTree tree = (TestDataTree)GRDTreeVP().getBaselineData();
	TestDataTreeNodes nodes = (TestDataTreeNodes)tree.getTreeNodes();
	TestDataTreeNode node = (TestDataTreeNode)nodes.getRootNodes()[0];
	node = (TestDataTreeNode)node.getChild(0);
	node = (TestDataTreeNode)node.getChild(0);
	node = (TestDataTreeNode)node.getChild(0);
	
	TestDataTreeNode node2 = new TestDataTreeNode();
	node2.setNode("GROUP2");
	
	TestDataTreeNode[] n = new TestDataTreeNode[2];
	n[0] = (TestDataTreeNode)node.getChild(0);
	n[1] = node2;
	node.setChildren(n);
	
	vpManual("TreeVP1", tree, grdTree().getTestData("tree")).performTest();
} 

Ao executar esse programa, obtemos as seguintes informações (Figura 11).


Figura 11. Resultado de detalhe em um ponto de verificação (Árvore)
table on left, tree view on right

No caso de lista, a Listagem 12 mostra um programa para adicionar um item a um objeto lista capturado como ponto de verificação.


Listagem 12. Exemplo de método para verificar um resultado de lista
 public void verifyResult() {
	TestDataList list = (TestDataList)TestListVP().getBaselineData();
	TestDataElementList elemList = (TestDataElementList)list.getData();
	
	TestDataElement elem = new TestDataElement();
	elem.setElement("list3");
	
	elemList.add(elem);
	
	vpManual("ListVP1", list, list().getTestData("list")).performTest();
} 

Quando executamos esse programa, obtemos as seguintes informações (Figura 12).


Figura 12. Resultado de detalhe em um ponto de verificação (Lista)
table on left, values on right


Voltar para parte superior


Teste de aplicativo que suporta múltiplos idiomas

Para testar um aplicativo em múltiplos idiomas, use os arquivos de recursos que contenham chave e pares de valores ([KEY]=[VALUE]), nos quais os valores sejam exibidos como GUI. Um exemplo de arquivo de recursos é aquele usado na classe ResourceBundle do Java. As etapas para configurar isso são as seguintes.

  1. A seguinte propriedade no arquivo ivory.properties do diretório bin do Rational Functional Tester está ativado (por padrão, é comentado.)
    # Quando ativada, essa propriedade
    permite busca de sequência em uma tabela da sequência localizada, se disponível
    rational.test.ft.services.enable_localization=true

  2. Arquivos de recursos do aplicativo que consistem em chave e pares de valores copiados sob a pasta de recursos do projeto do Rational Functional Tester após a mudança do nome base do arquivo para o nome do projeto do Rational Functional Tester. Naturalmente, não há problema em, em vez disso, criar o arquivo. O formato do nome do arquivo de recursos é:
    • [nome do projeto do Rational Functional Tester]_[idioma].properties
    Por exemplo, no caso do nome do projeto do Rational Functional Tester "DRAProject", o nome do arquivo de recursos em japonês é:
    • DRAProject_ja.properties
  3. Reinício do Rational Functional Tester.
  4. Abra o mapa de objeto de teste e mude os valores da propriedade que são valores de exibição GUI para nomes de chave dos arquivos de recursos. Alguns nomes de propriedade, como o seguinte, têm valores de exibição GUI.
    • accessibleContext.accessibleName
    • .captionText
    • name
    • text
    No caso do submenu, algum valor da propriedade é concatenado com o nome do menu pai separado por sublinhado ("_"). Nesse caso, mude o peso para 0.

Por exemplo, copie o arquivo de recursos em inglês para o japonês e acrescente alguns caracteres japoneses diante de cada valor. Faça isso no GUI mostrado na Figura 13.


Figura 13. GUI de aplicativo para o japonês
tree view on left, details on right

Clique para ampliar

Abra o mapa de objeto de teste e mude os valores de propriedade que são valores exibidos GUI a nomes de chave do arquivo de recursos, como mostrado na Figura 14.


Figura 14. Insira um nome de chave do arquivo de recursos no mapa de objeto de teste
tree view on top, tabs and details below

Clique para ampliar

Quando pressionar a tecla Enter, o nome de chave é alterado para o valor real no arquivo de recursos apropriado, como mostrado na Figura 15. O nome de chave é armazenado dentro e o valor é alterado dinamicamente com base nos ajustes de idioma. Ao dar um clique duplo no valor da propriedade para alternar de novo para o modo de edição, é possível ver o nome da chave do arquivo de recursos. Quando mudamos alguns valores do arquivo de recursos e depois reiniciamos o Rational Functional Tester, vemos os valores alterados no mapa de objeto de teste.


Figura 15. Mudança automática do nome de chave para o valor no arquivo de recursos
tree view on top, details below

Clique para ampliar

A seguinte propriedade de nome tem seu valor concatenado com o nome do menu pai, separado por sublinhado ("_"). Assim, seu peso é alterado para 0 (Figura 16).


Figura 16. Mudança do peso de uma propriedade para localizar um objeto GUI
tree view on top, details below

Clique para ampliar



Voltar para parte superior


O que aprendemos

Este artigo descreveu o que fazer se não sabemos que método é usado para manipular o GUI e como usar de forma eficaz o datapool de teste e o ponto de verificação. Quando não sabemos que método é usado para manipular o GUI, simulamos a ação GUI durante a gravação. Depois, consultamos o programa gerado e fornecemos subclasses (com nomes de método entendíveis), conforme a necessidade. Isso permite que eles sejam usados facilmente a partir de outros programas. Usar o datapool de teste e o ponto de verificação também lhe permite dar entrada em dados e verificar os resultados do teste.

O Rational Functional Tester também fornece um recurso para aplicativos que suportam múltiplos idiomas. Esse artigo explicou algumas dicas sobre esse recurso. O Rational Functional Tester pode usar arquivos de recursos para múltiplos idiomas que contenham chave e pares de valores para valores de exibição no GUI, de modo que é possível testar também aplicativos que suportam múltiplos idiomas.



Recursos

Aprender

Obter produtos e tecnologias

Discutir


Sobre os autores

Gou Nakashima photo

Gou Nakashima is a member of the database tooling development team in the Yamato Software Development Laboratory (YSL), IBM Japan.


Masahiro Ohkawa é membro da equipe de desenvolvimento do conjunto de ferramentas para banco de dados do Yamato Software Development Laboratory (YSL), da IBM Japan.




Avalie esta página


Reserve um instante para completar este formulário para nos ajudar a servi-lo melhor.



 


 


Não
são úteis
Extremamente
úteis
 





IBM, Rational e o logotipo da IBM são marcas registradas da International Business Machines Corporation nos Estados Unidos e/ou em outros países. Java e todas as marcas registradas e logotipos baseados em Java são marcas registradas da Sun Microsystems, Inc. nos Estados Unidos e/ou em outros países. Outros nomes de empresas, produtos e serviços podem ser marcas registradas ou marcas de serviço de terceiros.