Antes que uma exceção seja capturada, em algum local do código do programa ou
fora dele, é necessário que esta exceção seja lançada. A exceção lançada pode ser prove-
niente do seu próprio componente, de um componente externo ou até mesmo da máquina
virtual Java. Independentemente de onde a exceção é originada, esta é lançada através da
instrução throw. O trecho de código abaixo demostra o lançamento de uma exceção do
tipo InvalidUserException na linha 5. Um método pode lançar uma exceção ao
encontrar uma situação a qual não possa lidar, ou seja, o método propaga a exceção até
achar um tratador adequado para a exceção lançada. Para isso o método deve informar
o tipo de exceção ao qual deseja propagar. Na linha 1 do exemplo abaixo, a exceção
do tipo InvalidUserException é repassada para o método que fez a chamada a
requestUserInfo.
1- public void requestUserInfo() throws InvalidUserException{
2-
if (user.activeUser()) {
3-
user.showInfo();
4-
else {
5-
throw new InvalidUserException();
6-
}
7- }
Exceções podem ser levantadas em qualquer ponto de um programa e, se não fo-
rem capturadas, podem ser propagandas de forma transparente ao ponto de entrada do
programa, fazendo com que a o programa encerre a sua execução de forma inesperada.
2.4 Teste de Software
A construção de um sistema computacional pode ser uma tarefa bastante complexa, de-
pendendo das suas características e dimensões [46]. Devido a este fator, um sistema
computacional está sujeito a diversos tipos de problemas tornando-o diferente do que
foi originalmente projetado. Diversos problemas podem estar relacionados, o mais co-
mum é o fator humano [46]. As atividades de engenharia de software dependem muito
das habilidades e conhecimento técnico dos engenheiros de software bem como a inter-
pretação da especificação, e por fim, a implementação gerada a partir do entendimento
da especificação.
Teste de software é um processo que consiste em executar um sistema com o objetivo
de encontrar defeitos [35]. Atividades de validação, verificação e testes de sistemas são
utilizadas com o objetivo de obter um produto mais próximo ao que foi especificado.
2.4. TESTE DE SOFTWARE
Durante a construção, as suas partes assim como o sistema como um todo são testados
com o objetivo de verificar a sua conformidade com a sua especificação. Se o sistema
exibe algum tipo de divergência, torna-se necessária a realização de correções no sistema,
no processo do desenvolvimento ou na sua especificação.
2.4.1 Estratégia de teste
Uma estratégia de teste deve lidar com testes de unidades visando verificar se uma pe-
quena parte do código escrito foi desenvolvida de acordo como especificado, com testes
que envolvem a integração de partes do sistema e com testes para o sistema como um
todo, para validar os requisitos do cliente. As estratégias podem ser divididas em quatro
fases distintas: teste de unidade, teste de componentes, teste de integração e teste de
sistemas [7].
Teste de Unidade
Teste de unidade verifica se uma porção do código fonte realiza adequadamente a funcio-
nalidade proposta isoladamente do restante do sistema[46]. Devido a esta característica
geralmente necessita de drivers e stubs. Um driver é um elemento que aplica os casos
de teste. Ele é responsável por fornecer os dados de entrada, coletar os dados de saída
e apresentá-los ao usuário. Já o stub serve para substituir os módulos necessários que
não estejam disponíveis, com o objetivo de simular o seu comportamento, para a exe-
cução da unidade. Isso permite que o código relativo à unidade a ser testada possa ser
verificado isoladamente.
Teste de Componente
Um componente é uma unidade de composição com interfaces bem definidas. Nesta
fase o componente é testado de acordo com as especificações das funcionalidades e de
sua estrutura [36]. Para esta técnica a utilização de drivers e stubs pode ser necessária.
Teste de integração
Uma vez testados os componentes individuais, estes devem ser integrados para criar sis-
temas parciais ou completos. Este processo de integração envolve construir o sistema e
testá-lo quando a problemas relacionado a sua integração. Nesta fase são realizados tes-
tes de integração a fim de testar erros decorrentes deste cenário. Estes visam descobrir
erros arquiteturais relacionados às interfaces dos componentes[46]. As três abordagens
2.4. TESTE DE SOFTWARE
principais de testes de integração são: big bang, top-down e botton-up. No big bang, to-
dos os componentes são integrados de uma só vez não sendo necessário o uso de drivers
e stubs. Porém nesta abordagem torna-se difícil a localização das falhas. Na aborda-
gem top-down os componentes são integrados a partir do bloco principal do programa,
não sendo necessários os drivers, porém stubs podem ser necessários. Na abordagem
bottom-up, os componentes são integrados a partir dos componentes independentes, dis-
pensando o uso de stubs. Neste caso novos drivers devem ser criados a cada integração.
Teste de Sistemas
Teste do sistema é o processo com o objetivo de verificar se o programa, como um
todo, não atende aos seus objetivos. Tem utilidade limita se não existe um conjunto
de objetivos mensuráveis para o produto[36]. Os testes de sistemas se baseiam nos
requisitos funcionais e não funcionais do sistema.
2.4.2 Teste estrutural
A técnica estrutural estabelece os requisitos de teste com base em uma dada implemen-
tação, requerendo a execução de partes ou de componentes elementares do programa
[36]. Esta técnica baseia-se na estrutura do programa e permite que seja examinada a
sua estrutura interna. Nessa técnica os aspectos de implementação são fundamentais
na escolha dos casos de teste. Em geral, a maioria dos critérios da técnica estrutural
utiliza uma representação de Grafo de fluxo de controle CFG [36]. Um grafo de fluxo
de controle G = (N,E,s) é um grafo dirigido que consiste de um conjunto N de nós, um
conjunto E de arestas dirigidas e um nó de entrada s. Os nós representam comandos
ou uma coleção de comandos sequenciais e as linhas ou arestas representam o fluxo de
controle. O grafo de fluxo possui nós de entrada, nos quais a computação começa, e nós
de saída cuja, terminando a computação.
Os critérios pertencentes a esta técnica são classificados com base na complexidade,
no fluxo de controle e no fluxo de dados [46]. Os Critérios baseados no fluxo de con-
trole utilizam informações do grafo de fluxo de controle para derivar os requisitos de
testes. Os critérios baseados em fluxo de controle mais conhecidos são Todos-Nos,
Todas-Arestas e Todos-Caminhos. O critério baseados em fluxo de dados utiliza in-
formações do fluxo de dados pra derivar os requisitos de teste. Para isso é necessário
adicionarão grafo de fluxo de controle informações a respeito do fluxo de dados, carac-
terizando o Grafo Def-Uso [67] . Os principais critérios baseados em fluxo de dados
2.4. TESTE DE SOFTWARE
são [67]: Todas-Definições, Todos-C-Usos, Todos-P-Usos, Todos-Uso, Todos-C-Usos,
Todos Caminhos-DU, Todos-Caminhos-DU, Todos-Potenciais-Uso.
2.4.3 Teste Funcional
Esta técnina checa se um programa está de acordo com a sua especificação, independen-
temente do código fonte. Teste funcional é também conhecido como teste caixa-preta ou
teste comportamental. Ao se testar um sistema computacional (S) são escolhidos alguns
pontos específicos do domínio do sistema D(S) para a execução de (S) [46]. Idealmente,
os testes devem ser realizados para todos os elementos do domínio do sistema. Porém
esta ação torna-se bastante custosa. Devido a esta limitação, faz-se necessária a adoção
de critérios de seleção dos elementos do D(S) com o objetivo de obter um conjunto re-
duzido com alta probabilidade de revelar uma falha. Estes critérios visam estabelecer
condições que devem ser satisfeitas no decorrer dos testes.
Os critérios de teste funcionais são utilizados para se projetar casos de testes os quais
o programa ou sistema é considerado caixa preta [46]. Os detalhes internos não são con-
siderados na execução dos casos de teste. Para testar o sistema, são fornecidas entradas e
avaliadas as saídas geradas para verificar se estão em conformidade com a especificação.
As fontes utilizadas pelos testes funcionais são as especificações de requisitos e de pro-
jeto. As abordagens mais conhecidas desta técnica são: Particionamento de equivalência,
Análise do Valor Limite, Grafo Causa-Efeito e Error-Guessing.
Particionamemnto de equivalência
Técnica utilizada para a escolha de dados de entrada para testes[46]. O domínio de
entrada é dividido em classes de equivalência, que representam um conjunto de valores
válidos ou inválidos para as condições de entrada.
Análise do Valor Limite
Técnica utilizada para escolha de dados de entrada, combinada com a técnica de parti-
cionamento de equivalência. Como grande número de erros tende a ocorrer nos limites
dos valores de entrada, a técnica de análise de valores limite determina que os dados de
entrada escolhidos sejam valores limite de cada uma das classes de equivalência[46].
No documento
Uma Abordagem Leve para Testar o Comportamento Excepcional
(páginas 31-35)