Você está na página 1de 15

Teste de Software

A última etapa do desenvolvimento de um software é a fase de testes. A fase de testes


é de fundamental importância, pois através dela é possível detectar e solucionar erros no
software. No decorrer de todo o desenvolvimento, atividades de garantia de qualidade do
software são executadas, porém, a possibilidade de continuar encontrando erros é enorme,
mesmo depois de concluído o desenvolvimento do software.
Segundo Pressman (1995), na fase de testes, os engenheiros executam uma série de
atividades que consistem em varrer o software criado a procura de qualquer tipo de erro ou
falha na codificação, que possam vir a interferir no correto funcionamento do aplicativo. O
teste é responsável por detectar o maior número possível de erros, pois encontrar todos é
praticamente impossível. Os testes de software são responsáveis por executar o software
utilizando valores reais, com a finalidade de encontrar erros. Caso os testes sejam realizados e
nenhuma falha seja descoberta, provavelmente, os casos de testes não foram bem elaborados.
Seguindo o raciocínio de Pressman (1995), os casos de testes devem elevar a probabilidade de
detecção de erros, caso contrário, os testes não serão bem sucedidos. Pressman (1995)
defende ainda que o teste bem sucedido, além de apontar falhas ainda não constatadas, deve
fazer isso com o mínimo tempo e esforço.
Os testes são realizados com a inserção de dados atuais para que se possam obter os
resultados esperados de acordo com os requisitos e especificações previamente estabelecidos.
Se os dados de saída são os esperados, significa que as informações geradas pelo software são
legítimas e totalmente confiáveis.
Apesar de todos os esforços exigidos na fase de teste, é comum que o software não
funcione completamente sem a ausência de erros. Falhas fazem parte do código de
programação, isso muitas vezes acontece devido à complexidade do desenvolvimento de
software e da negligência dos desenvolvedores nas fases iniciais da elaboração de um sistema.
Mesmo que os testes, por mais eficazes que sejam, não consigam detectar e remover
todos os erros contidos no software, estes são indispensáveis pois aumentam o grau de
segurança, e consequentemente, a confiança no produto pelo desenvolvedor e pelo cliente.
Inthurn (2001) afirma que há um gasto frequente muito grande de tempo e dinheiro
em correções de software, em que o desenvolvimento não foi adequado e a fase de testes não
foi satisfatória. Assim, entende-se que os testes são importantes, também, para evitar
surpresas desagradáveis no futuro. Além disso, os testes são responsáveis por mostrar que o
software possui erros e que os mesmos devem ser corrigidos, mas isso não significa que a
partir das correções, o software estará imune a possíveis falhas posteriores. Novos erros
podem ser inseridos ao software no momento em que outros erros são corrigidos, através de
alterações realizadas no código a fim de corrigir os erros descobertos até o momento.
De acordo com Inthurn (2001), os testes bem sucedidos conseguem, em média,
corrigir aproximadamente 60% das falhas contidas no software. O custo dos testes realizados
dentro do processo de desenvolvimento é relativamente pequeno se comparado ao gasto com
manutenção corretiva do software pronto, sem mencionar que para, um software ter
qualidade, é necessário que haja uma rotina exaustiva de testes, que se estende por todo o
desenvolvimento do projeto.
Jamais a atividade de teste deve trabalhar de maneira isolada, mas sim de maneira
conjunta com as demais atividades e de forma iterativa. Os casos de teste devem testar as
partes produzidas em cada etapa do projeto e o produto completo ao final do projeto. Só
assim a qualidade do produto final é garantida. A atividade de testes é dividida de diferentes
maneiras por diversos autores. Por exemplo, segundo Peters (2001), a atividade de testes é
constituída das atividades chaves, planos de teste, projetos de teste, casos de teste,
procedimentos de teste, execução de teste e relatório de teste.
Já Pressman (1995) divide como técnicas de teste de software e estratégias de teste de
software. Segue os estudos das atividades de teste de software focando as definições deste
último autor.

Técnicas de teste de software


Segundo Pressman (1995), técnicas de teste de software consistem em elaborar casos
de teste capazes de varrer o software a procura de erros ainda não constatados. As atividades
de testes não visam culpar alguém por falhas ou, ainda, testar o software com finalidade
destrutiva. Os testes são realizados com o objetivo de encontrar as falhas e, posteriormente,
corrigi-las, garantindo assim a qualidade do mesmo.
Dentro das atividades de testes todos os resultados obtidos são avaliados, essa
avaliação é realizada comparando-se os resultados obtidos com os esperados. Caso sejam
encontrados erros, é feita a depuração.

Projeto de casos de teste


Um projeto de teste requer uma atenção especial dos engenheiros, pois os testes a
serem realizados devem possuir uma alta probabilidade de descobrir os erros ainda não
detectados, em um prazo relativamente curto e com esforços irrelevantes. Outro fato que
exige que o projeto seja bem elaborado é a questão dos valores, pois o custo de manutenção
para correção de erros após o término do desenvolvimento pode ser de 60 a 100 vezes mais
do o custo da manutenção realizada durante o desenvolvimento (PRESSMAN, 1995).
Um software pode ser testado de duas formas. A primeira, quando se conhecem as
suas funções e quais as saídas esperadas quando se recebem tais entradas, é popularmente
conhecida como teste de caixa preta. E a segunda, quando se conhece a estrutura e o
funcionamento interno, a maneira que os métodos estão interligados, quais as
responsabilidades de cada um deles, dentre outros detalhes, é chamada de teste de caixa
branca.
Segundo Inthurn (2001), um projeto de teste é responsável por gerenciar a fase de
teste identificando e descrevendo qual tipo de teste será aplicado em determinado momento.
O projeto de teste é dependente de um plano de teste, esse plano mostra as estratégias para a
execução do teste com base numa lista de casos de teste.

Plano de teste
Dentre outros objetivos, o plano de teste deve identificar os componentes do software
que serão testados e os recursos necessários para a correta execução dos mesmos,
recomendando e descrevendo as estratégias de teste a serem aplicadas. O plano de teste deve
conter e disponibilizar a documentação referente ao projeto em desenvolvimento, seus
requisitos funcionais e não funcionais, a fim de entender o que será testado no software. O
plano de teste deve conter as estratégias de teste, pois nela encontra-se a maneira como o
teste será realizado e quais técnicas e critérios serão utilizados. Listas contendo os tipos de
testes a serem aplicados, ferramentas, recursos de hardware e de pessoas disponíveis também
são parte do plano de teste. A cada teste realizado, informações sobre o que foi realizado, data
e hora de inicio e fim da atividade, nome do responsável pela mesma e resultados obtidos são
registrados (INTHURN, 2001).
Caso de teste
Um caso de teste pode ser definido como um documento que descreve as etapas a
serem seguidas para realização de um teste. Desde os dados de entrada, a atividade em
execução e o resultado de saída. É utilizado para observar se o resultado de saída é realmente
o esperado. Em caso positivo o teste foi realizado com êxito (INTHURN, 2001).
O caso de teste serve para verificar se o sistema segue as definições impostas no
projeto e se o mesmo foi devidamente construído. Segundo Bartié (2002), o caso de teste é o
documento que registra todo o planejamento dos testes, nele devem ser abordados os
seguintes itens:
 ƒ identificação das condições de testes;
 ƒ identificação do que será testado;
 ƒ definição de cada caso de teste identificado;
 ƒ detalhamento das classes de dados de entrada;
 ƒ detalhamento da saída gerada;
 ƒ responsáveis pela atividade de teste;
 ƒ definição de como será realizada a bateria de testes;
 ƒ cronograma das atividades.

Suíte de teste
É o documento que faz o detalhamento final dos testes, nele é identificado o
comportamento de cada caso de teste durante a execução. A suíte de teste estabelece a
ordem de execução e a maneira que cada caso de teste irá proceder (BARTIÉ, 2002).
O objetivo do conjunto de teste é auxiliar no exercício de verificar as especificações
dos requisitos funcionais e não funcionais do sistema, ou seja, constatar se o sistema procede
normalmente durante a execução das funções.

Teste estrutural ou teste de caixa branca


Pressman (1995) define o teste de caixa branca como um método de projeto de casos
de testes voltado a testar a estrutura interna do software. O teste de caixa branca, ao
contrário de teste de caixa preta, se preocupa em como o código fonte foi construído e a
lógica de programação utilizada no desenvolvimento dos métodos. O teste é totalmente
realizado na estrutura interna do software (INTHURN, 2001).
O teste estrutural visa confirmar ou se certificar de que a estrutura interna do software
esteja correta. Para isso, é preciso que o caso de teste percorra todos os caminhos internos
possíveis. A atividade de teste estrutural pode ser considerada complexa porque deve
abranger todos os níveis de hierarquia, no caso de classes com herança. O fato de um método
funcionar corretamente em uma classe não garante que o mesmo não apresente erros na
classe que a herde (INTHURN, 2001).
Teoricamente, um teste de caixa branca seria capaz de avaliar e classificar um
software como 100% correto, isso porque o teste de caixa branca percorre todos os caminhos
lógicos possíveis, o que resulta num teste exaustivo e complexo, pois mesmo em um programa
pequeno, os caminhos lógicos são muitos (PRESSMAN, 1995). O teste de caixa branca,
também, pode ser conhecido como testes de caixa de vidro, ou ainda, testes de caixa clara
(SOMMERVILLE, 2003).
Bartié (2002) aponta dificuldades em aplicar o teste de caixa branca em alguns casos.
O teste de caixa branca deve ser realizado por um profissional competente e extremamente
experiente, pois o responsável por aplicar o teste deve conhecer minuciosamente a estrutura
do software. O teste será executado pelos próprios desenvolvedores, e como os
desenvolvedores normalmente trabalham sob pressão, o software tem que ficar pronto
rapidamente. Este fato faz com que a preocupação do desenvolvedor seja maior com a
implementação, de forma que os testes acabam ficam em segundo plano.

Teste funcional ou teste de caixa preta


Segundo Inthurn (2001), o teste de caixa preta consiste em verificar na interface do
software se todas as funcionalidades estão operando corretamente. Este teste é aplicado com
a finalidade de encontrar: funções incorretas ou ausentes, erros de interface, erros nas
estruturas de dados ou no acesso ao banco de dados, erros de desempenho e, ainda, erros de
inicialização e término.
O teste funcional, como o próprio nome já diz, é realizado com base nos requisitos
funcionais do software, assim, é possível analisar as entradas e saídas de todas as unidades.
Para isso os dados de entrada devem ser normalmente aceitos pelo sistema e a saída deve ser
a esperada. Caso a saída não seja a esperada, o erro é constatado. Esse tipo de teste não se
preocupa em saber como o código fonte foi produzido e sim se o mesmo faz o que lhe foi
especificado.
As técnicas de caixa preta são responsáveis por garantir que todos os requisitos do
sistema funcionem de acordo com o especificado durante a elaboração do projeto. Cabe aos
testes de caixa preta averiguar que o sistema forneça todos os resultados esperados.
Uma vantagem do teste de caixa preta em relação ao teste de caixa branca é que
nesse não é necessário que a equipe de testes conheça ou entenda a estrutura interna, a
tecnologia utilizada e a maneira como foi implementado, e sim, que verifique se faz o que foi
proposto e se atenderá as necessidades do futuro usuário. No teste de caixa preta o
profissional responsável pela execução do teste necessita apenas entender os requisitos e
analisar os resultados produzidos (BARTIÉ, 2002).
O teste de caixa preta consiste em validar os requisitos funcionais do sistema, o
objetivo é encontrar erros de interface, erros relacionados ao desempenho, ao acesso ao
banco de dados, erros de inicialização e término, falha ou ausência de funções (PRESSMAN,
1995).
Este último autor define alguns tipos de teste de caixa preta, entre eles o
particionamento da equivalência e análise do valor limite. No primeiro, os dados de entrada
são divididos em classes de forma que os casos de teste possam ser derivados. O
particionamento de equivalência permite que seja definido um caso de teste capaz de
encontrar uma ou mais classes de erros. Um exemplo poderia ser um caso de teste que
identifique problemas sempre que um tipo específico de dado é utilizado. O particionamento
de equivalência é normalmente representado por um conjunto de dados de entrada, válidos
ou inválidos para o sistema.
Na segunda, análise do valor limite, a intenção do teste é colocar em prova os valores
fronteiriços, ou seja, analisar as extremidades do sistema. Difere-se um pouco do
particionamento de equivalência porque além de testar os dados de entrada, analisa também
os dados de saída. O teste pode ser feito da seguinte forma: se os parâmetros de entrada
devem respeitar o intervalo entre 0 e 4, inserir números normais, ou seja, entre 0 e 4, depois
um número abaixo do especificado e em seguida um número acima do especificado. Assim, é
possível testar se as condições de entrada estão sendo validadas. O mesmo critério deve ser
utilizado para analisar dos dados obtidos na saída.
Teste de caminho básico
O teste de caminho básico é conhecido como uma técnica de teste de caixa branca.
Através do teste de caminho básico é possível definir os diversos caminhos de execução do
software e garantir que cada um deles seja executado ao menos uma vez (PRESSMAN, 1995).
O número de caminhos é proporcional ao tamanho e complexidade do software. Devido aos
módulos não trabalharem sozinhos, ou seja, são apenas partes de um sistema, fica inviável a
utilização dos testes de estrutura. Dessa forma, testes de caminho básico são mais utilizados
nos testes de unidade (SOMMERVILLE, 2003).
Antes de executar o teste de caminho básico é importante criar o modelo de
representação do trecho de código a ser testado, para facilitar o entendimento do fluxo de
controle. Nessa representação são utilizados fluxogramas e grafos. A figura 01 mostra um
fluxograma simplificado de um teste de caminho básico.

Fluxograma de um teste do caminho básico


O fluxograma acima pode ser facilmente representado em forma de grafos de fluxo,
como mostrado a seguir.
Grafo de fluxo do fluxograma da figura 1.

As linhas do grafo traçam os possíveis caminhos. É importante que a cada laço o teste
utilize um caminho independente até que todos os caminhos sejam percorridos. Caminhos
independentes são aqueles que executam instruções que ainda não foram executadas
(PRESSMAN, 1995).
Para encontrar o número de caminhos independentes é necessário realizar o cálculo
da complexidade ciclomática do grafo de fluxo do programa, esse cálculo é feito através da
fórmula (SOMMERVILLE, 2003):
CC(G) = Número (ramos) – Número (nós) + 2
sendo as setas correspondentes aos ramos e os círculos correspondentes aos nós, para o grafo
de fluxo na figura 02, CC(G) = 11 – 9 + 2 = 4. Quatro é o número de caminhos independentes.
Caminhos independentes:
 Caminho 1: 1-11
 Caminho 2: 1-2-3-4-5-10-1-11
 Caminho 3: 1-2-4-6-8-9-10-1-11
 Caminho 4: 1-2-3-6-7-9-10-1-11
Caminho não independente:
 Caminho 5: 1-2-3-4-5-10-1-2-3-6-8-9-10-1-11
O caminho 5 não é independente porque todas as suas instruções já foram executadas
anteriormente, ou seja, não encontrou instruções ainda não executadas.
Pressman (1995) mostra duas outras maneiras de encontrar o número de caminhos
independentes, além da fórmula apresentada por Sommerville (2003). Uma é encontrando o
número de regiões (fechamento dos nós), que corresponde ao número de caminhos. A outra,
o número de nós predicativos (nó que apresenta condicional) mais um corresponde ao número
de caminhos independentes. De acordo com o grafo de fluxo:
CC(G) = Ramos – Nós + 2 = 11 – 9 + 2 = 4
CC(G) = Nós predicativos + 1 = 3 + 1 = 4
CC(G) = Regiões = 4

Genericamente, o teste de caminho básico não testa todas as combinações possíveis


de todos os caminhos do software, pois, devido ao grande número de laços de repetições
existentes, a quantidade de combinações de caminhos é infinita (SOMMERVILLE, 2003).
O teste de caminho básico é simples e eficaz, e ainda pode ser complementado por
outros tipos de testes, para, assim, encontrar e corrigir o maior número possível de falhas, são
eles o teste de condição, teste de fluxo de dados e o teste de laços (PRESSMAN, 1995).

Teste de condição
O teste de condição é um método de projeto de casos de testes responsável por
certificar que todas as condições lógicas de um módulo do programa funcionem corretamente.
Uma condição simples pode ser definida como duas expressões aritméticas separadas por um
operador relacional (PRESSMAN, 1995):
E1 <operador relacional> E2,
em que E1 e E2 são as expressões aritméticas e o operador relacional sendo qualquer um
desses (<, ≤, =, ≠, >, ≥) ou ainda operadores booleanos (OR, AND e NOT). Uma condição
composta é definida com a união de duas ou mais condições simples.
O teste de condição consiste em testar cada condição existente no programa à procura
de erros. Uma condição é considerada incorreta quando pelo menos um componente da
condição está incorreto, ou seja, operadores lógicos ou booleanos ausentes ou a mais. O
mesmo acontece com os parênteses, além de erros na própria expressão aritmética ou
operador relacional.
Para encontrar erros nos operadores relacionais, três testes são realizados,
considerando que as expressões aritméticas estejam corretas, a E1 deve receber valores,
maior, menor e igual a E2.

Teste de laços
Normalmente o número de estruturas de repetição, laços ou loops, como são
conhecidos, utilizados na implementação de sistemas é muito grande, mesmo em pequenos
softwares, isso porque essas estruturas são extremamente necessárias, ou melhor, é inviável a
construção de um sistema sem a utilização de estruturas de repetição.
O teste de laços consiste em validar a estrutura dos laços. Existem quatro classes de
laços: laços simples, laços concatenados, laços aninhados e laços não-estruturados
(PRESSMAN, 1995):
 ƒ Laços simples: cinco testes são realizados, 1) não entrando no laço; 2) somente uma
passagem pelo laço; 3) duas passagens pelo laço; 4) enquanto m<n passagens pelo laço; e
5) n-1, n, n+1 passagens pelo laço.
 Laços aninhados: deve-se testar primeiro o laço interno e iniciar com valores mínimos
todos os laços; execute os testes de laços simples no laço interno sem alterar os valores do
laço externo; continue realizando testes com valores inaceitáveis. Repita até que todos os
laços sejam testados.
 Laços concatenados: se os laços foram implementados de maneira individual, um
independe do outro, o teste realizado é o mesmo do mostrado anteriormente no laço
simples. Se os laços foram implementados de forma que um interaja com outro, ou seja, se
o contador do primeiro laço for utilizado como valor inicial para o segundo laço, o teste a
ser realizado é o mesmo mostrado anteriormente no laço concatenado.
 Laços não-estruturados: para facilitar o teste é necessário reprojetar os grupos de laços de
forma que os mesmos se assemelhem à programação estruturada.

Tipos de laços – retirada de (MARIATH, 2004).

Teste unitário
O teste unitário consiste em validar a menor unidade do projeto, uma classe de
métodos, funções isoladas e unidades lógicas. A partir disso, testam-se módulos integrados a
outros e outros, até que se tenha o sistema completo. O mesmo deve ser realizado diversas
vezes, dia a dia, isso porque as falhas sempre aparecem e fica mais fácil corrigir pequenas
falhas do que corrigir o sistema inteiro depois de construído (MEDEIROS, 2005).
Medeiros (2005) afirma que a importância do teste unitário se dá na prevenção de
futuros erros no sistema. A única maneira de saber se o código é realmente bom é testando
sua reação diante de uma bateria de testes exaustivos, esses testes validam situações normais,
que deveriam ser bem sucedidas e situações de erro.
O mesmo autor ainda cita um exemplo do mundo real: pensando na fundamental
importância do teste unitário, imagine o resultado dos testes em um avião ou mesmo em um
navio apenas após o término de sua construção. Se algo sair errado, os danos podem ser
irreparáveis. Nada mais apropriado para descrever o resultado, do que uma tragédia.

Testes de verificação e validação de software


Toda a fase de teste de um software refere-se ao (V&V) ou verificação e validação. A
verificação consiste em atividades que garantem que as funções do sistema tenham sido
implementadas corretamente, e a validação em verificar que o software corresponde às
expectativas do cliente (PRESSMAN, 1995). Segundo Sommerville (2003), os testes de
validação ou verificação são responsáveis por constatar se o sistema desenvolvido está
realmente de acordo com as especificações fornecidas pelo cliente e se satisfaz as suas
necessidades.
Os testes de validação devem evoluir de acordo com o desenvolvimento do software,
não sendo executados de maneira isolada, ou seja, sempre que um módulo ou uma classe é
desenvolvido, testes são realizados. Os testes são incrementados a cada etapa de
desenvolvimento, mais classes e funções implementadas, mais testes realizados.
Para que os erros sejam encontrados no início do processo, resumidamente
Sommerville (2003) divide os testes de validação em 5 (cinco) estágios, sendo eles teste de
unidade, teste de módulo, teste de subsistema, teste de sistema e teste de aceitação.
 Teste de unidade: tem como objetivo averiguar que um componente do sistema está
funcionando corretamente, para isso o teste é realizado em cada componente
separadamente.
 Teste de módulo: num sistema, um módulo corresponde a uma classe, um conjunto de
métodos ou funções interligadas, ou seja, dependentes uma da outra. O teste é realizado
visando verificar que o módulo todo está funcionando corretamente, se as conexões
entre os métodos estão corretas e produzindo o esperado. O teste de módulo, assim
como o teste de unidade, é normalmente executado por seus próprios desenvolvedores.
 Teste de subsistemas: responsabiliza-se basicamente por testar pequenos conjuntos de
módulos integrados, o objetivo é encontrar erros de interface de módulos e suas ligações.
 Teste de sistema: o sistema consiste na união coerente dos subsistemas, o teste de
sistema, por sua vez, consiste em descobrir possíveis falhas nas interações desses
módulos e, ainda, em verificar que todos os requisitos funcionais ou não, estejam
presentes.
 Teste de aceitação: o teste de aceitação é o último realizado antes da entregado do
software ao cliente. O teste é realizado utilizando valores reais vindos dos próprios
clientes. O teste de aceitação pode trazer à tona diversos tipos de erros anteriormente
não constatados, pois os dados reais criam situações não pensadas pelos
desenvolvedores. Através do teste de validação é possível perceber se o sistema é estável
e se possui um desempenho que corresponda às expectativas do cliente.
Segundo Inthurn (2001), o teste de sistema se subdivide em quatro outros tipos
envolvendo todas as partes do software: Teste de recuperação; teste de segurança; teste de
stress; e, por último, teste de desempenho.
 Teste de recuperação: consiste em provocar diversos tipos de falhas, o sistema, porém,
deve ser capaz de tolerar as mesmas, ou seja, um sistema tolerante a falhas é aquele
consegue se recuperar de falhas sem que essas atrapalhem o seu funcionamento. O
sistema deve se recuperar das falhas completamente num tempo relativamente pequeno
e com o mínimo de intervenção humana. A geração de um log detalhando as atividades
realizadas antes das falhas é interessante. Um dos objetivos do teste de recuperação é
averiguar a maneira como o sistema se recupera dos erros, os mais comuns são,
problemas no disco rígido, erros de interface e falhas referentes à falta de memória.
 Teste de segurança: é responsável por verificar se todos os recursos de defesa do sistema
realmente impedem os possíveis acessos indevidos. Esse tipo de teste deve ser realizado
por uma equipe que não tenha participado do desenvolvimento. O seu objetivo é garantir
que o sistema continue funcionando normalmente sob tentativas de acessos não
permitidos. O correto é que as políticas de segurança do próprio sistema se encarreguem
de protegê-lo desses acessos. Durante a execução dos testes, os responsáveis por ele
devem utilizar todos os métodos disponíveis para tentar, de alguma forma, acessar o
sistema indevidamente, neste caso, vale conseguir senhas ilegalmente, tentativas de
acesso durante o processo de recuperação do sistema, entre outras ocasiões de falhas
provocadas pelos próprios testadores.
 Teste de stress: é realizado com o objetivo de forçar o sistema, por exemplo, executar
várias buscas de dados no disco, abrir o maior número de janelas possível a fim de causar
falta de memória. Enquanto isso, deve-se analisar a queda de desempenho do sistema e a
maneira como ele se recupera, em caso de parada do sistema durante o processo, mais
testes de recuperação devem ser executados.
 Teste de desempenho: como o próprio nome já diz, é responsável por testar o
desempenho do sistema, pode ser realizado em conjunto com o teste de stress. O
objetivo desse tipo de teste é garantir que os requisitos de desempenho relatados
durante o planejamento sejam alcançados. O teste de desempenho analisa o tempo de
resposta das atividades, a capacidade do banco de dados, os momentos em que o sistema
perde mais desempenho em função de um grande número de processos executando,
dentre outros. Esse teste pode ser realizado executando alguma instrução inúmeras
vezes, assim, é possível observar se o desempenho cai ou não.

Teste de integração
Durante o desenvolvimento do sistema os gerentes decidem quem ficará responsável
por cada fase de teste, normalmente cada programador se encarrega de testar seu próprio
código, ao final, as partes desenvolvidas por cada programador são passadas a outra equipe
que irá unificar os códigos. Essa equipe realiza a integração do software e mais testes são
feitos. Os testes são realizados em partes separadas ou subsistemas e no sistema como um
todo, por fim o teste é detalhadamente documentado e arquivado (SOMMERVILLE, 2003).
Um dos objetivos do teste de integração é detectar problemas junto às interfaces, ou
seja, erros que aparecem com a junção das partes do sistema. Antes da junção são realizados
testes nos pedaços individuais do sistema, os erros encontrados são corrigidos, outros erros
aparentemente “menores”, nem são notados. Mais tarde, com as partes do sistema
integradas, aqueles erros “menores” podem se apresentar não tão pequenos assim, e causar
falhas inaceitáveis no sistema (PRESSMAN, 1995).
Basicamente, o teste de integração consiste em verificar se as partes testadas
individualmente funcionam também unidas umas as outras, (INTHURN, 2001).
Pressman (1995) define dois tipos de integração de sistemas: a não incremental e a
incremental. A primeira consiste em desenvolver todos os módulos do sistema, realizar a
junção dos mesmos, e só depois iniciar a fase de testes. Normalmente os erros são tantos e a
dificuldade de correção é tamanha que o resultado é um sistema completamente inaceitável.
O teste de integração incremental tende a assegurar que o sistema possua uma quantidade
menor de erros, isso se faz possível pelo fato de que cada módulo do sistema é testado
individualmente antes da junção com os demais módulos, com isso fica mais fácil detectar e
corrigir os erros existentes. Após a junção novos testes são realizados para detectar outros
erros que possam aparecer. Um módulo pode funcionar corretamente quando testado
sozinho, e não funcionar normalmente quando integrado a outros módulos, por isso a
importância dos testes antes e depois da integração.

Integração Top-down
É uma abordagem da integração incremental. Segue uma ordem hierárquica, de cima
para baixo. Os módulos mais importantes do sistema são desenvolvidos primeiro, depois os
menos importantes. Após desenvolvido, cada módulo é testado individualmente, integrado
aos outros módulos e testado novamente, assim, é possível conferir se a interface com os
demais módulos continua compatível.

Integração Bottom-up
A ordem de teste dos módulos é inversa à top-down, os módulos menos importantes,
ou de níveis mais baixos da hierarquia são desenvolvidos e testados primeiro, depois os
próximos níveis a cima na hierarquia até que o último módulo seja testado.

Depuração de software
A depuração ou debugging ocorre quando um caso de teste encontra e mostra erros
do sistema, ou seja, para que se faça a depuração é necessário que os testes realizados
tenham obtido êxito.
A depuração consiste em analisar os resultados obtidos com os esperados, e, no caso
de diferença entre eles, encontrar a causa, ou seja, encontrar o motivo da não
correspondência entre os dados reais e os esperados, e, por fim, corrigir o problema
(PRESSMAN, 1995). Em resumo, a depuração objetiva encontrar e corrigir a causa, ou causas,
dos erros no sistema.

Executando Testes de Software


A primeira classe possui três métodos a serem testados: fatorial(), maiorNumero() e
par(). O processo de teste utilizando a técnica do teste do caminho básico no primeiro método
é o seguinte: primeiro deve-se numerar o programa, como pode-se observar a seguir:
Código numerado:
O próximo passo consiste em desenhar o grafo para visualização dos
caminhos a serem executados:
Na sequência, deve-se calcular a complexidade ciclomática para se certificar que o
número de caminhos está correto. Ele pode ser feito de três maneiras:
CC(G) = Ramos – Nós + 2 = 12 – 9 + 2 = 5
CC(G) = Nós predicativos + 1 = 4 + 1 = 5
CC(G) = Regiões = 5
O resultado comum aos três cálculos indica maior probabilidade do grafo
estar correto.
Por último, deve-se descrever os possíveis caminhos e valores de entrada, como é
mostrado a seguir:
Caminhos Básicos
1. 1, 2, 9
2. 1, 3, 5, 9
3. 1, 3, 4, 5, 9
4. 1, 3, 4, 6, 9
5. 1, 3, 4, 6, 7, 8, ..., 6, 9
Entradas
1. valor = -2 -> -1 "Valor Negativo!!! Não é válido!!!"
2. valor = 0 -> 1
3. valor = 1 -> 1
4. Inválido. Deveria entrar no “while”
5. valor = 5 -> 120
Dessa forma, encontram-se e percorrem-se todos os possíveis caminhos do método. A
próxima etapa consiste em automatizar os testes, por exemplo, utilizando o JUnit.

Os métodos de asserções consistem em afirmar que suas instruções são verdadeiras,


como se observa nas linhas de 16 a 19, ou seja, se o valor inserido no método for negativo o
retorno é “-1”, se for 0 ou 1, o retorno é “1”, e se for um número positivo maior que 1 o
retorno é seu fatorial. Neste caso, o fatorial de 5 é 120, então o resultado do teste deve ser
positivo, caso não seja, o método possui erros.
O próximo método maiorNumero() foi implementado e numerado:
O grafo referente código exibido anteriormente é:
CC(G) = Ramos – Nós + 2 = 11 – 9 + 2 = 4
CC(G) = Nós predicativos + 1 = 3 + 1 = 4
CC(G) = Regiões = 4
Caminhos Básicos
1. 1, 4, 7, 8, 9
2. 1, 2, 3, 8, 9
3. 1, 4, 5, 6, 8, 9
4. 1, 2, 4, 5, 6, 8, 9
Entradas
1. v1 = 33, v2 = 33, v3 = 99 -> 99
2. v1 = 99, v2 = 33, v3 = 51 -> 99
3. v1 = 33, v2 = 99, v3 = 51-> 99
4. v1 = 51, v2 = 99, v3 = 33 ->99

Você também pode gostar