Comentários

0%

Não pode faltar

Tipos de teste

Roque Maitino Neto

Como os testes são classificados? 

Os testes são classificados em funcionais, estruturais, voltados a aplicações móveis, e a aplicações orientadas a objetos.

Fonte: Shutterstock.

Deseja ouvir este material?

Áudio disponível no material digital.

Praticar para aprender

Prezada aluna, caro aluno, aqui estamos para mais uma seção dedicada aos testes de software. Depois de nosso primeiro contato com o assunto, é chegado o momento de avançarmos para temas mais específicos e relacionados a técnicas de teste. Em termos simples, uma técnica representa um jeito de se fazer e, durante nosso estudo, você entenderá o motivo de termos mais do que uma maneira de fazer testes. Aplicações imediatas das técnicas ajudarão no entendimento do que se pretende com cada uma delas. Depois dessa primeira abordagem, prosseguiremos com os testes para aplicações móveis, web e orientadas a objetos, como forma de esclarecermos as especificidades de cada um deles.

Durante nosso estudo da técnica funcional, alguns tipos de testes serão descritos e um exemplo prático de teste de componente será desenvolvido. No teste estrutural, trataremos de detalhar a transformação de um código-fonte simples em um grafo, elemento gráfico que o representará e permitirá que uma simulação de cobertura de testes seja feita. Já nas divisões de testes para aplicações móveis, web e orientadas a objetos, serão fornecidas particularidades dessas aplicações, as quais definirão como o procedimento de teste deverá ser conduzido. Com isso, esperamos prepará-lo para tomar decisões quanto a técnicas e tipos de teste a serem aplicados em diferentes ocasiões.

Com a intenção de expandir a frente de atuação em desenvolvimento e testes de sistemas, os gestores de uma determinada empresa de software decidiram que começariam a realizar procedimentos de testes para terceiros. Dessa forma, qualquer desenvolvedor que desejasse terceirizar o teste de seus produtos poderia procurar por essa empresa, e os testes seriam feitos mediante contrato e contrapartida financeira.

Na condição de um dos melhores profissionais dessa empresa, você foi destacado para assumir o primeiro projeto de teste e logo se deparou com um obstáculo: por força de cláusula contratual, você não teria acesso ao código-fonte daquela aplicação, que fora projetada para ser executada em computadores pessoais conectados em rede local.

O desenvolvedor que confiou os testes à empresa em que você atua mostrou-se absolutamente disponível para fornecer todos os elementos do sistema a você, exceto o código-fonte. Considerando esse cenário, você foi chamado a planejar o procedimento de teste e, com a finalidade de direcionar seus esforços, seu gestor apontou quatro itens que deveriam obrigatoriamente compor o planejamento:

Bom trabalho!

Dica

Quanto maior a sua dedicação ao aprendizado do assunto, maior será a afinidade conquistada com ele. E quanto maior a afinidade, maior será seu interesse. Como já sabemos, testar um produto de software está muito longe de apenas promover algumas execuções de um produto com algumas entradas escolhidas ao acaso. Ao invés disso, testar significa aplicar técnicas, melhores práticas e critérios para que a qualidade do produto atinja os níveis de excelência que todos desejam.

Siga conosco e bons estudos!

conceito-chave

Como já se sabe, um produto de software necessita de inúmeros elementos para oferecer ao seu usuário um funcionamento pleno. A adequação do hardware e da infraestrutura de rede são apenas dois desses elementos, e o dimensionamento incorreto de um deles terá o potencial de arruinar a experiência do usuário. Há, no entanto, um aspecto que sempre terá papel decisivo na percepção do usuário em relação ao sistema que utiliza: as suas funções. Afinal, será por meio delas que ele interagirá com o programa e será através delas que alcançará seus objetivos traçados lá na fase de requisitos. Funções mal projetadas ou defeituosas podem, inclusive, desestimular o uso do sistema. Com tamanha importância, a área de testes não poderia deixar de direcionar muita atenção às funções do sistema e o faz por meio da aplicação da Técnica de Teste Funcional e do Teste de Funcionalidades, assuntos que desenvolveremos na sequência.

Estratégias de testes

Entretanto, antes de abordarmos especificamente técnicas de teste, vale a pena as situarmos no contexto da estratégia de teste, a qual equivale a uma prática cujo objetivo é estabelecer um roteiro que descreve os passos a serem executados no processo de teste ou, em outras palavras, um modelo para os testes. Pressman e Maxim (2016) descrevem genericamente alguns elementos presentes em todas as estratégias adotadas para os testes:

O último item da estratégia de teste embasa nosso próximo assunto e, para entendermos as razões de uma técnica, vale uma breve digressão: os testes são realizados tendo em vista objetivos específicos e são projetados para verificar diferentes propriedades de um sistema. A depender da técnica escolhida, os casos de teste podem ser planejados, por exemplo, para verificar se as especificações funcionais estão implementadas corretamente. Em outros casos, eles são selecionados para averiguação da adequação do desempenho, da confiabilidade e a da usabilidade, por exemplo. Assim, abordagens diferentes de teste motivam a aplicação de técnicas também diferentes de testes (PRESSMAN; MAXIM, 2016).

Tipos de testes

Embora as técnicas de teste sejam de grande relevância, por remeterem mais diretamente a metodologias de aplicação de testes, esta é não a única dimensão que podemos identificar nesse contexto. Na verdade, podemos estabelecer outros tipos de relações entre um teste e seu objetivo e, para isso, basta fixarmos o momento, o objeto e, como já mencionado, a maneira (ou metodologia) da aplicação.

Parece complicado? Observe a Figura 3.7: ela posiciona os vários tipos de teste nas três dimensões que acabamos de mencionar: o “quando”, o “que” e o “como”.

Figura 3.7 | As três dimensões dos testes
 A imagem mostra as três dimensões dos testes: Primeira: Quando testar - Fase do desenvolvimento de software. Níveis de teste. Teste de unidade. Teste de integração. Teste de sistema. Teste de aceitação.  Teste de regressão. Segunda: O que testar - Tipo de teste. Teste de funcionalidade. Teste de interface. Teste de desempenho. Teste de carga (estresse). Teste de usabilidade. Teste de volume. Teste de segurança. Terceira: Como testar - Técnica de teste. Teste funcional. Teste estrutural. Teste funcional: Particion. de equivalência. Análise de valores-limite. Baseado em casos de uso. Critérios Teste estrutural: Teste de caminhos. Teste de comandos. Teste ramos. Teste de condições. Teste de cond. Múltiplas. Critérios.
Fonte: Braga (2016, p. 24).

Apesar de não termos tido contato com os testes apontados na figura, é possível destacar que o teste funcional está relacionado a uma maneira de se realizar um teste, daí ter sido posicionado na dimensão “Como testar”. Já o teste de funcionalidade – que também será abordado na sequência – guarda associação com “o que testar”. Feita essa contextualização, passamos à abordagem inicial da técnica de teste funcional e do teste de funcionalidade.

Técnica de teste funcional e teste de funcionalidade

Essa técnica baseia-se nas especificações do software para derivar os requisitos de teste. O teste é realizado nas funções do programa, daí o nome funcional. Não é seu objetivo verificar como ocorrem internamente os processamentos, mas se o algoritmo inserido produz os resultados esperados (BARTIÉ, 2002).

Uma das vantagens dessa estratégia de teste é o fato de ela não requerer conhecimento sobre detalhes da implementação do programa. Sequer o código-fonte é necessário. Observe uma representação dessa técnica na Figura 3.8:

Figura 3.8 | Visão do teste de caixa preta
A imagem mostra um caixa com o texto Casos de teste, dela sai  um seta que vai para o primeiro símbolo de um fluxograma dentro um retângulo grande azul, do último símbolo do fluxograma sai uma seta que vai para a caixa com o texto Resultados.
Fonte: Bartié (2002, p. 105).

A ideia ilustrada na figura nos faz entender que o testador não conhece os detalhes internos do sistema e baseia seu julgamento apenas nos resultados obtidos a cada entrada fornecida. A esse respeito, Pressman e Maxim (2016) afirmam que um produto de software pode ser testado caso o responsável conheça a função específica para a qual aquele software foi projetado e, com esse conhecimento, estará em condições de realizar testes que demonstrem que cada uma das funções é operacional, embora o objetivo final do teste seja o de encontrar defeitos no produto. Os autores concluem que essa abordagem de teste se vale de uma visão externa do produto e não se preocupa com a lógica interna do software, a qual é opaca ao testador. Por esse motivo, a técnica funcional também é conhecida como teste de caixa preta.

O planejamento do teste funcional envolve dois passos principais: identificação das funções que o software deve realizar (por meio da especificação dos requisitos) e a criação de casos de teste capazes de checar se essas funções estão sendo executadas corretamente. Apesar da simplicidade da técnica e apesar de sua aplicação ser possível em todos os programas cujas funções são conhecidas, não podemos deixar de considerar uma dificuldade inerente: não se pode garantir que partes essenciais ou críticas do software serão executadas, mesmo com um bom conjunto de casos de teste.

Um teste funcional não deve ser aplicado simultaneamente em todas as funções do sistema e nem em apenas uma única ocasião. Em vez disso, ele deve examinar elementos específicos em ocasiões previamente conhecidas, característica que levou esse tipo de teste a ser dividido em subtipos. Alguns exemplos ajudarão a esclarecer essa circunstância: quando aplicado para verificar funções de um módulo, função ou classe do sistema, ele recebe a denominação de teste de unidade. Já o teste de integração é executado quando se deseja avaliar como as unidades funcionam em conjunto ou integradas e o teste de regressão é um subtipo do teste funcional, que visa garantir que uma alteração feita em uma função não tenha introduzido outros problemas no código (PRESSMAN; MAXIM, 2016).

A menção ao quarto subtipo de teste funcional nos dará a oportunidade para o desenvolvimento de um exemplo prático. Quando testamos um componente do sistema de modo independente para verificar sua saída esperada, chamamos tal procedimento de teste de componentes. Geralmente, ele é executado para verificar a funcionalidade e/ou usabilidade de componentes, mas não se restringe apenas a eles. Um componente pode ser qualquer coisa que receba entradas e forneça alguma saída, incluindo uma página web, telas e até mesmo um sistema dentro de um sistema maior.

Como aplicação prática desse teste, imaginemos um sistema de vendas pela internet. Em uma análise mais minuciosa, seria possível identificar muitos componentes nessa aplicação, mas escolheremos apenas alguns, os quais estão representados na Figura 3.9.

Figura 3.9 | Componentes de um sistema de vendas pela internet
A imagem mostra  uma caixa com o texto:  Acesso à aplicação (Componente 1), dela saem duas setas, uma seta com sentido duplo que vai para Banco de dados, nela há os textos: Interface 1 e Validação do login, e a outra seta vai para a caixa com o texto: Navegação pelos produtos (Componente 2). Dela sai uma linha que liga a caixa com o texto: Adicionar ao carrinho (Componente 3), dela sai uma linha que liga a caixa com o texto: Pagamento (Componente 4), dela sai um seta de sentido duplo que vai para o texto Provedor de serviço de pagamento com o texto Interface 2 e também sai uma linha que liga a caixa com o texto: Confirmação (Componente 5). Os componentes 4 e 5, e o Provedor de serviço de pagamento estão dentro de um retângulo com linhas tracejadas.
Fonte: elaborada pelo autor.

O componente de login (identificado como componente 1) efetiva a validação de acesso do usuário ao sistema, usando, para isso, uma interface específica, que realiza a conexão com o banco de dados. Esse componente dá acesso à navegação pelos produtos, à inclusão de itens no carrinho, ao pagamento da compra e à sua confirmação. Para efetivação do pagamento, há uma interface que conecta o sistema em teste a um provedor de serviço de pagamentos. Considerando esse cenário, vejamos o que deve ser testado em específico no componente 1 (login):

Se considerarmos o componente 3 (adição do produto ao carrinho), o testador deverá verificar o que ocorre, por exemplo, quando o usuário coloca um item, o qual supostamente deseja comprar, e fecha aplicação em seguida. Um cuidado especial também deverá ser tomado com a comunicação entre o componente 4 e o provedor de serviço de pagamento.

Pelas suas características, o teste de componente nos prepara para o teste que vem a seguir. Se a técnica de teste funcional se preocupa com as funções do sistema, qual seria, então, sua diferença para o teste de funcionalidade? Os testes de funcionalidades priorizam interações com o usuário e a navegação no sistema e são executados para verificar se um aplicativo de software funciona corretamente, de acordo com as especificações do projeto, no que se refere à entrada de dados, validação de dados, funções de menu e tudo o que está relacionado à interação do usuário com as interfaces. Além das verificações mencionadas, um teste de funcionalidades deve se preocupar também em averiguar se funções de “copia e cola” funcionam corretamente e se os ajustes de padrões regionais estão de acordo com a localidade em que o software está sendo executado.

Exemplificando

Um sistema pode ter sido testado em todas as suas funcionalidades em um determinado país e, ao ser instalado e executado em outro, apresentar problemas nas mesmas funcionalidades já testadas. Isso ocorre devido às diferenças de formatos nos sistemas métricos e de data implementados em diferentes regiões do planeta. Um campo que exige a inclusão de uma data, por exemplo, será testado nos Estados Unidos considerando o formato “mm/dd/aaaa”. Na eventualidade de ser executado no Brasil, o programa deverá receber, no campo mencionado, uma data no formato “dd/mm/aaaa”, o que certamente causará inconsistência no processamento da informação recebida.

No escopo da qualidade de software, não há apenas uma acepção relacionada à funcionalidade. Existem as funcionalidades do sistema, que são objetos de teste, e a funcionalidade entendida como um atributo fundamental da qualidade. Neste segundo caso, trata-se do grau com o que o software satisfaz as necessidades declaradas pelo cliente, conforme indicado pelos subatributos de adequabilidade, exatidão, interoperabilidade, conformidade e segurança (PRESSMAN; MAXIM, 2016). Em outras palavras, a funcionalidade oferecida pelo sistema não pode ser confundida com o grau com que um programa atende a requisitos de adequação ao seu propósito, à sua exatidão e à facilidade com que opera com outros sistemas.

Técnica de teste estrutural

Se voltarmos um pouco no texto e observarmos novamente a Figura 3.7, encontraremos o teste estrutural posicionado na mesma dimensão do teste funcional. Essa dimensão, que chamamos de “Como testar”, agrupam técnicas (ou maneiras) de se realizar testes. Os testes estruturais (também chamados de caixa branca) são assim conhecidos por serem baseados na arquitetura interna do programa. Contando com o código-fonte e com a estrutura do banco de dados, o testador poderá submeter o programa a uma ferramenta automatizada de teste. Vale aqui a menção de que um teste funcional também pode (e deve) ser realizado de forma automática.

Há várias ferramentas capazes de realizar testes estruturais, mas não usaremos nenhuma em especial para o nosso propósito de detalhar esse teste. Em vez disso, nós nos apoiaremos em uma possível forma de representação do código do programa para construir um método de teste. Vamos considerar que, ao analisar o código do programa, nossa ferramenta construa uma representação dele, conhecida como grafo. De acordo com Delamaro (2004), em um grafo, os nós equivalem a blocos indivisíveis de código, o que, em outras palavras, significa que não existe desvio de fluxo do programa para o meio do bloco e, uma vez que o primeiro comando dele é executado, os demais comandos são executados sequencialmente. Outro elemento que integra um grafo são as arestas (ou arcos), e eles representam o fluxo existente entre os nós. Se considerarmos o código da aplicação que calcula o fatorial de um valor, exibido no Código 3.3, teremos que o trecho entre a linha 1 e a linha 8 obedece aos requisitos para se transformar em um nó do grafo.

Código 3.3 | Programa que calcula o fatorial de um número fornecido
#include <stdio.h>
main()
{
    int i = 0;
    valor = 0; 
    fatorial = 1;
    printf("Programa que calcula o fatorial de um valor informado pelo usuario\n");
    
    do {
    	printf("\nInforme um valor entre 1 e 10: ");
    	scanf("%d",&valor);
	} while ((valor<1) || (valor>10));
    for (i=1; i<=valor; i++)
        fatorial=fatorial*i;
    printf("\nO Fatorial de %d = %d", valor, fatorial);
    printf("\n");
}
Fonte: elaborado pelo autor.

O programa que usaremos para ilustrar um teste estrutural será aquele cujo código pode ser visto no Código 3.4. Sua função é a de verificar a validade de um nome de identificador fornecido com base nas seguintes regras:

Código 3.4 | Código em C que apura classes válidas e inválidas de identificadores

/* 01 */ {
/* 01 */ char achar;
/* 01 */ int length, valid_id;
/* 01 */ lenght = 0;
/* 01 */ printf ("Indentificador");
/* 01 */ achar = fgetc(stdin);
/* 01 */ valid_id = valid_s(achar);
/* 01 */ if (valid_id)
/* 02 */     lenght = 1;
/* 03 */ achar = fgetc (stdin);
/* 04 */ while (achar != '\n')
/* 05 */ {
/* 05 */     if (!(valid_f(achar)))
/* 06 */          valid_id = 0;
/* 07 */     lenght++;
/* 07 */     achar = fgetc (stdin);
/* 07 */ }
/* 08 */ if (valid_id && (length >= 1) && (lenght < 6))
/* 09 */     printf ("Valido\n");
/* 10 */ else
/* 10 */     printf ("Invalido\n");
/* 11 */ }

Fonte: Delamaro (2004, p. 20).

Quando analisado pela ferramenta de teste, o Código 3.4 será transformado no grafo da Figura 3.10. Note que cada trecho identificado com um número no código é representado em um nó no grafo gerado.

Figura 3.10 | Grafo gerado pela ferramenta de teste estrutural
A imagem mostra uma sequência de círculos numerados. Inicia com círculo com o número 1, ele aponta para o círculo com o número 2 e também aponta para o círculo com o número 3, o círculo de número 2 aponta para o círculo com o número 3, e ele aponta para o círculo com o número 4. Esses quatro círculos estão em sequência na vertical. No círculo de número 4 há dois caminhos, um à esquerda, onde ele aponta para o círculo de número 5, que aponta para o círculo de número 6 e também para o círculo de número 7. Esses três círculos estão em sequência na vertical. O Círculo de número 7 aponta de volta para o círculo de número 4. O outro caminho, à direita, onde ele aponta para o círculo de número 8, que também aponta para dois caminhos, à esquerda para o círculo de número 9 e à direita para o círculo de número 10, ambos apontam para o círculo de número 11.
Fonte: Delamaro (2004, p. 21).

Ao testador cabe selecionar casos de teste capazes de percorrer os nós, os arcos e os caminhos representados no grafo do programa. Apenas para fins de exemplificação, um caminho que pode ser percorrido pelo fluxo do programa é o formado pela sequência de nós 2,3,4,5,6 e 7. Casos de testes diferentes tenderão a exercitar sequências diferentes do grafo e, se considerarmos a existência de um conjunto infinito desses casos, teremos que as escolhas incorretas podem arruinar o teste. Ainda, se consideramos que os casos de teste são potencialmente infinitos, alguns critérios de cobertura do código devem ser previamente definidos, o que nos leva a uma reflexão.

Reflita

Se é certo que um teste, por melhor que seja sua execução e por melhor que tenham sido as escolhas para os casos de teste, não conseguirá assegurar que o programa é totalmente livre de defeitos, qual seria a indicação de que é chegado o momento de interrompê-lo? A resposta passa pelos critérios de parada da atividade, os quais foram estabelecidos previamente e que definiam taxa de cobertura de código e quantidade de casos de teste, por exemplo.

Feitas essas abordagens, avançamos rumo aos testes de aplicações móveis e web.

Testes de aplicações web e móveis

Houve um tempo em que códigos executáveis desempenhavam suas funções apenas em computadores de grande porte ou nos poucos computadores pessoais que existiam. Como os dispositivos móveis eram apenas um sonho, o planejamento e a execução dos testes eram atividades adequadas ao perfil dos programas da época e aos equipamentos que os executavam. Em nossos dias, no entanto, há dispositivos com uma ampla variedade de aplicações capazes de executar programas para as mais variadas finalidades e essa realidade exige algumas adequações nos procedimentos de testes aplicados nas plataformas mais comuns.

A fim de delimitar nosso estudo, trataremos aqui dos testes voltados a aplicações feitas para dispositivos móveis e dos testes executados em aplicações para a internet, nessa mesma ordem. Pressman e Maxim (2016) destacam o que consideram abordagens de teste especializadas para aplicativos móveis:

Essas considerações nos permitem criar um panorama dos testes de aplicações móveis, começando com sua definição: são atividades organizadas de teste, executadas com o objetivo de descobrir erros em aspectos fundamentais de seu funcionamento em um dispositivo móvel. Esses testes são realizados pelos profissionais técnicos, além dos usuários, do cliente e do gerente do projeto. Um teste típico começa por verificar as funções visíveis da aplicação para, então, voltar sua atenção para aspectos de infraestrutura e tecnologia. Normalmente, as etapas desse teste incluem testes de conteúdo, de interface, de navegação, de componente, de configuração, de desempenho e de segurança.

Assimile

O teste de aplicativos móveis é um conjunto de atividades relacionadas com um único objetivo: descobrir erros no conteúdo, na função, na usabilidade, na navegabilidade, no desempenho, na capacidade e na segurança do aplicativo móvel. Para tanto, deve ser executada uma estratégia de teste que abrange as revisões e o teste executável (PRESSMAN; MAXIM, 2016).

Como qualquer teste, temos aqui também a necessidade de apurar se o processo foi corretamente desempenhado. Como não é possível aplicar absolutamente todas as possibilidades existentes de entradas, nem apurar todas as situações que podem ocorrer durante o uso da aplicação, novamente os critérios de parada serão o parâmetro para o fim dos testes.

Outro elemento que demanda providências específicas durante o processo de teste são as aplicações web. Da mesma forma que em qualquer outro teste, aqui também estamos diante da missão de executar um sistema para encontrar e corrigir defeitos. No entanto, as aplicações web podem operar em conjunto com diferentes sistemas operacionais, navegadores, protocolos de comunicação e plataformas de hardware, o que pode representar dificuldades adicionais na busca por defeitos. Com essas especificidades, os seguintes elementos de qualidade devem ser testados (PRESSMAN; MAXIM, 2016):

Adicionalmente, desempenho, interoperabilidade e segurança também recebem atenção especial em um teste de aplicação web.

Testes de aplicações orientadas a objetos

Seguindo nosso caminho pelos testes feitos em aplicações ou paradigmas específicos, chegamos até as aplicações Orientadas a Objetos (OO). Por causa das características próprias dos programas OO, os testes aqui aplicados devem considerar a existência de subsistemas em camadas que encapsulam outras classes. De acordo com Pressman e Maxim (2016), é preciso testar um sistema OO em vários níveis diferentes, de modo que erros eventualmente ocorridos durante as interações entre as classes sejam descobertos. Ainda de acordo com os autores, três providências básicas são necessárias para se testar adequadamente um sistema OO:

Uma análise mais minuciosa da primeira providência pode nos levar a uma aparente inconsistência: como é possível que aspectos da análise orientada a objetos e modelos do projeto sejam testados? De fato, no sentido convencional, não podem. Ocorre que a criação de uma aplicação OO começa com a criação de modelos de análise e de projeto, os quais começam com representações quase informais dos requisitos e se tornam modelos detalhados de classes e de suas relações conforme o desenvolvimento avança. Por isso, em cada estágio da sua evolução, esses modelos devem ser revisados para que erros sejam descobertos logo em fases iniciais do desenvolvimento (PRESSMAN; MAXIM, 2016).

Entre os vários benefícios trazidos pela adoção da Orientação a Objetos para o desenvolvimento de software, está o fato de que esse paradigma reduz a necessidade de testes, segundo Schach (2009). O autor complementa que a reutilização de código via herança é um dos fatores que torna essa característica ainda mais forte: em tese, uma vez que a classe mãe tenha sido testada, as classes provenientes dela não precisam ser novamente testadas. Quando os desenvolvedores inserem novos métodos na subclasse de uma classe já testada, é natural que eles precisem ser testados. No entanto, métodos herdados não precisam de teste adicional.

Por mais lógicas e confiáveis que nos pareçam, essas afirmações precisam ser analisadas com um certo cuidado. Para começar, a classe é um tipo de dado abstrato e o objeto é a instância de uma classe. Esse fato nos induz ao raciocínio de que uma classe não tem uma realização concreta e que, portanto, não é possível aplicar testes baseados em execução (ou seja, aqueles que temos abordado nesta unidade) diretamente nela. Outra característica da Orientação a Objetos que tem efeitos em um teste é quantidade normalmente elevada de métodos em um objeto que, ao invés de retornarem um valor para o chamador, simplesmente alteram o estado do objeto ao modificarem seus atributos. Segundo Schach (2009), a dificuldade, nesse caso, é a de testar se a alteração de estado foi realizada corretamente.

Tomemos a seguinte situação como exemplo: uma aplicação bancária possui um método chamado deposito, cujo efeito é o de aumentar o valor da variável de estado chamada saldoDaConta. No entanto, como consequência do ocultamento de informações, a única maneira viável de se testar se o método deposito tem uma execução correta é pela invocação de um outro método, chamado determinarSaldo, tanto antes como depois da chamada do método deposito, a fim de verificar como a mudança do saldo se dá.

Outro aspecto a ser analisado é a necessidade de aplicação de um novo teste em métodos herdados. Observe a hierarquia de classes ilustrada no trecho de código contido no Código 3.5. Na primeira classe (ClasseArvoreComRaiz), são definidos dois métodos: o que exibe o conteúdo de um nó e a rotina de impressão, utilizada pelo método exibeConteudoNo.

Código 3.5 | Ilustração de uma hierarquia de classes em Java
class ClasseArvoreComRaiz {
	void exibeConteudoNo (No a);
	void rotinaImpressao (No b);
	// o método exibeConteudoNo usa o método rotinaImpressao 
}

class ClasseArvoreBinaria extends ClasseArvoreComRaiz {
	void exibeConteudoNo (No a);
	// o método exibeConteudoNo definido aqui usa 
	// o método rotinaImpressao herdado de ClasseArvoreComRaiz
}

class ClasseArvoreBinariaBalanceada extends ClasseArvoreBinaria {
	void rotinaImpressao (No b);
	// o método exibeConteudoNo (herdado de ClasseArvoreBinaria) 
	// usa essa versão local de rotinaImpressao dentro da classe
	// ClasseArvoreBinariaBalanceada
} 
Fonte: adaptado de Schach (2009).

Observe que a subclasse ClasseArvoreBinaria herda o método rotinaImpressao da classe mãe chamada ClasseArvoreComRaiz. Além disso, o método exibeConteudoNo é novamente definido nessa subclasse, o que anula o mesmo método definido na classe ClasseArvoreBinaria. Já a subclasse ClasseArvoreBinariaBalanceada herda o método exibeConteudoNo da superclasse ClasseArvoreBinaria. No entanto, nela é definido um novo método, o rotinaImpressao, que anula aquele definido em ClasseArvoreComRaiz. Quando o método exibeConteudoNo usa o método rotinaImpressao no contexto de ClasseArvoreBinariaBalanceada, as regras do Java especificam que a versão local de rotinaImpressao deve ser usada e, em consequência disso, o código real do método rotinaImpressao, executado quando exibeConteudoNo é chamado no contexto da instanciação da classe ClasseArvoreBinaria, é diferente daquele executado quando esse mesmo método é executado na instanciação de ClasseArvoreBinariaBalanceada. Esse fenômeno ocorre normalmente apesar de o método exibeConteudoNo ser herdado sem modificação, o que acarreta a necessidade do novo teste (SCHACH, 2009).

Também considerando características próprias de sistemas Orientados a Objetos, Masiero et al. (2015) dividem o procedimento de testes em três fases:

Este foi, portanto, o conteúdo preparado para esta seção. Durante seu desenvolvimento, você teve contato com as técnicas de teste funcional e estrutural e com outros tipos de testes específicos para determinadas aplicações e paradigmas de desenvolvimento. Tivemos a oportunidade de desenvolvermos juntos um exemplo de teste estrutural baseado na criação de um grafo, que representava o código apresentado. Embora simples, o exemplo nos mostrou como a técnica funciona e quão importante é a correta escolha dos casos de teste. Não deixe de se aprofundar neste assunto e torne-o logo uma boa referência em testes de software. Até a próxima!

Faça valer a pena

Questão 1

Ao executar o teste da caixa preta, o testador não levará em consideração o comportamento interno do sistema. Essa técnica leva esse nome por considerar o processamento do sistema de forma desconhecida e, por isso, apenas as entradas e as saídas do sistema serão avaliadas.

Um teste de caixa branca não poderá ser executado quando o testador não tiver a posse do:

Tente novamente...

Esta alternativa está incorreta, leia novamente a questão e reflita sobre o conteúdo para tentar novamente.

Tente novamente...

Esta alternativa está incorreta, leia novamente a questão e reflita sobre o conteúdo para tentar novamente.

Correto!

Um dos requisitos para a aplicação do teste estrutural (ou caixa branca) é o acesso ao código-fonte do sistema. Em oposição ao teste funcional – que executa testes apenas nas funções –, o teste estrutural preocupa-se com a estrutura da aplicação.

Tente novamente...

Esta alternativa está incorreta, leia novamente a questão e reflita sobre o conteúdo para tentar novamente.

Tente novamente...

Esta alternativa está incorreta, leia novamente a questão e reflita sobre o conteúdo para tentar novamente.

Questão 2

Se os usuários encontrarem erros ou dificuldades dentro de um aplicativo móvel, vão procurar o conteúdo e a função personalizados de que precisam em outro lugar. Por isso, você deve procurar e corrigir o máximo de erros possível antes que o aplicativo móvel seja colocado em uma loja ou repositório de aplicativos.

Considerando os testes de aplicações móveis, analise as afirmações que seguem:

  1. O procedimento geral de teste em uma aplicação móvel é totalmente diferente do procedimento aplicado em sistemas convencionais.
  2. Os objetivos do teste de aplicações móveis devem dar relevância maior às verificações de desempenho do que de interface, dada a natureza dessas aplicações.
  3. Além do corpo técnico de testadores, um procedimento de teste de aplicações móveis deve contar com a presença também dos usuários da aplicação.

É verdadeiro o que se afirma em:

Tente novamente...

Os testes de aplicações móveis não diferem, na essência, dos testes de aplicações convencionais. No entanto, as características próprias dessas aplicações devem ser refletidas em adequações no processo de teste.

Correto!

O procedimento de teste não deve ser conduzido apenas por profissionais técnicos. A presença do usuário será fundamental para a validação da usabilidade da interface. 

Tente novamente...

Embora o desempenho seja importante e deva receber atenção nos testes, será uma falha não encontrada na interface que terá o potencial de resultar em maior dano à qualidade da aplicação .

Tente novamente...

Os testes de aplicações móveis não diferem, na essência, dos testes de aplicações convencionais. No entanto, as características próprias dessas aplicações devem ser refletidas em adequações no processo de teste.

O procedimento de teste não deve ser conduzido apenas por profissionais técnicos. A presença do usuário será fundamental para a validação da usabilidade da interface. 

Tente novamente...

Embora o desempenho seja importante e deva receber atenção nos testes, será uma falha não encontrada na interface que terá o potencial de resultar em maior dano à qualidade da aplicação.

O procedimento de teste não deve ser conduzido apenas por profissionais técnicos. A presença do usuário será fundamental para a validação da usabilidade da interface. 

Questão 3

Uma questão clássica surge todas as vezes que se discute teste de software: “Quando podemos dizer que terminamos os testes – como podemos saber que já testamos o suficiente?” Há algumas respostas pragmáticas e algumas tentativas empíricas para essa questão.

Considerando o conceito de teste e as características de seu procedimento, assinale a alternativa que contém a sentença indicativa do momento em que o testador deve interromper um procedimento de teste.

Tente novamente...

Esta alternativa está incorreta, leia novamente a questão e reflita sobre o conteúdo para tentar novamente.

Tente novamente...

Esta alternativa está incorreta, leia novamente a questão e reflita sobre o conteúdo para tentar novamente.

Tente novamente...

Esta alternativa está incorreta, leia novamente a questão e reflita sobre o conteúdo para tentar novamente.

Correto!

Considerando que um procedimento de teste não dará ao testador a plena certeza de que o sistema estará completamente livre de defeitos, o fim desse procedimento estará atrelado ao cumprimento dos critérios de casos de teste e de cobertura estabelecidos durante o planejamento. Não se pode vincular o término dos testes a nenhum critério de cobertura total do código, nem de utilização de todos os casos de teste existentes (dado que esse número pode ser infinito), nem tampouco de alcance de qualidade total.

Tente novamente...

Esta alternativa está incorreta, leia novamente a questão e reflita sobre o conteúdo para tentar novamente.

Referências

BARTIÉ, A. Garantia da Qualidade de Software: As melhores práticas de Engenharia de Software aplicadas à sua empresa. Rio de Janeiro: Elsevier, 2002.

BRAGA, P. H. Testes de Software. São Paulo: Pearson Educational do Brasil, 2016.

COMO são feitos os testes de usuário? [S.l.: s.n.], 2018. 1 vídeo (4 min). Canal Alura Cursos Online. Disponível em: https://bit.ly/3sYiSlD. Acesso em: 24 dez. 2020.

DELAMARO, M. E. Introdução ao teste de software. Rio de Janeiro: Elsevier, 2004.

MASIERO, P. C., LEMOS, O. A. L, FERRARI, F. C., MALDONADO, J. C. Teste de software orientado a objetos: teoria e prática. ResearchGate, [S.l.], 2015. Disponível em: https://bit.ly/3iRA1ZR. Acesso em: 24 dez. 2020.

PRESSMAN, R.; MAXIM, B. Engenharia de Software: uma abordagem profissional. 8. ed. Porto Alegre: AMGH, 2016.

SCHACH, S. R. Engenharia de Software: os Paradigmas Clássico e Orientado a Objetos. 7. ed. São Paulo: McGraw-Hill, 2009.

TESTES de Integração e Teste de Sistema. [S.l.: s.n.], 2018. 1 vídeo (12 min). Canal Eduardo Engelharia de Software. Disponível em: https://bit.ly/39knSsX. Acesso em: 24 dez. 2020.

Bons estudos!

AVALIE ESTE MATERIAL

OBRIGADO PELO SEU FEEDBACK!