Testes de Software
Prof. Rodrigo de Barros Paes
rodrigo@ic.ufal.br
Objetivos da disciplina COMP259 - TESTE DE
SOFTWARE
o Os objetivos da disciplina envolvem o estudo e prática de
conceitos ...
Ementa específica
o Domínio, intervalos, oráculos e tipos de teste
o Cobertura do teste
o Testes aleatórios
o Teste aleató...
Créditos
o Muitos slides, ideias e referências desse curso tiveram origem
nos seguintes locais
oProf. Ardnt Von Staa, PUC-...
Introdução Qualidade de Software
rodrigo@ic.ufal.br 5
Do ponto de vista do usuário
o Um sistema correto:
oResolve o meu problema;
oFunciona sempre que eu preciso dele;
oEu ente...
Errare humanum est
o Errar é inerente ao ser humano
ocomo somos falíveis e o desenvolvimento de software é intensivo em
es...
O que é um sistema?
rodrigo@ic.ufal.br 8
defeito
erro
falha
vulnera
bilidade
sistema
observador
Engano do
desenvolvedor
ou...
Definições
o Artefatos são resultados tangíveis resultantes do desenvolvimento ou da manutenção
o Defeito é um fragmento d...
BUG
o Indícios do uso da palavra BUG em engenharia
o“Defeitos inexplicáveis”
rodrigo@ic.ufal.br 10
It has been just so in ...
BUG – na computação
o Grace Hoper trabalhava no computador Mark II (Harvard) em
1946, quando o Mark II começou a apresenta...
Software é “Bugento”
o Cerca de 40 a 50% dos programas postos em uso contêm defeitos não
triviais
o defeito não trivial:
o...
Software é “Bugento””
o Como reduzir o tempo médio para recuperar?
oProjeto e programação orientada à recuperabilidade
o C...
Não existe software perfeito
o Mesmo sistemas perfeitos podem falhar. Erros provocados por causas exógenas:
o erros provoc...
Crenças
o Não é possível prever todos os potenciais riscos (causas dos
erros)
o Não se pode esperar que sistemas não conte...
Fidedignidade
o Fidedignidade de software é definida como sendo a fidelidade de
um sistema intensivo em software de modo q...
Características da fidedignidade (básicas)
o Adequação: prestar o serviço que interessa ao usuário usuário pode ser:
pesso...
Características da fidedignidade (básicas)
o Segurança: (safety) habilidade de evitar consequências catastróficas aos usuá...
Características da fidedignidade (tolerância)
o Robustez: habilidade de, em tempo de execução, detectar erros (reportar fa...
Características da fidedignidade (evolução)
o Manutenibilidade: habilidade de poder ser modificado ou corrigido com facili...
Crenças (cont.)
o Adicionar características de fidedignidade a posteriori é usualmente muito caro
o as características nec...
O que queremos?
rodrigo@ic.ufal.br 22
Ter a certeza de que estamos
desenvolvendo software, de forma
econômica, possuindo q...
Qualidade de
Software
Definições básicas
rodrigo@ic.ufal.br 23
Qualidade de um artefato
o A qualidade de um artefato é um conjunto de propriedades a
serem satisfeitas em determinado gra...
Qualidade satisfatória
o Um artefato possui qualidade satisfatória caso satisfaça plenamente
as necessidades e anseios de ...
Conceitos básicos
o Qualidade por construção
o Um artefato possui qualidade por construção caso possua qualidade satisfató...
Modelo economia da qualidade
rodrigo@ic.ufal.br 27
c
u
s
t
o
qualidade assegurada pelo desenvolvimento
custo desenvolvimen...
Por que desenvolver com qualidade?
o Custo do mau funcionamento, exemplos
oAborrecimento, pequenas perdas financeiras e/ou...
Por que desenvolver com qualidade?
o Uma das principais causas do excessivo tempo gasto (custo) ao
desenvolver software é ...
Exemplos de retrabalho inútil
o desenvolver algo e descobrir que não era isso que se queria ou que se precisava
o causa: e...
Introdução a
testes
rodrigo@ic.ufal.br 31
Atividades típicas de um Software
Análise e
especificação
de requisitos
Protótipos de
tela
Projeto,
provas de
conceito
Cod...
Atividades típicas de um Software
Análise e
especificação
de requisitos
Protótipos de
tela
Projeto,
provas de
conceito
Cod...
Foco
o Logo, esse curso se concentra em uma das atividades para se
chegar a um software de maior qualidade
o Embora exista...
Introdução
o Se nós pudermos encontrar os defeitos do nosso software
o Se pudermos corrigir esses defeitos
o Então, um dia...
Algumas empresas com “grana”
o Microsoft
o Google
rodrigo@ic.ufal.br 36
Mais algumas
o Apple
o Ubuntu
rodrigo@ic.ufal.br 37
Hummm … beleza, e agora?
o Se essas empresas não conseguiram, como eu vou conseguir fazer isso no
meu próprio software?
o ...
O que é teste?
o Como escolher boas entradas?
o Sempre é possível saber o resultado esperado?
o Sempre dá pra automatizar ...
Algumas dicas
o Encontre defeitos o mais cedo possível
o É possível gastar muito tempo na atividade de teste e ainda
assim...
Falhou, e agora?
o Quanto mais a gente “anda” para a direita nesse diagrama, mais a gente aprende sobre o
software
o O tes...
Exemplo
o Em 1998, foi lançado um foguete para
analisar o clima de Marte
o A NASA subcontratou a empresa Lockheed
Martin p...
Exemplo
o Dano
o O foguete executou uma
trajetória diferente e
explodiu em Marte
o Embora tanto a NASA
quanto a Lockheed t...
Pergunta
a) A causa foi um defeito no software sob teste?
b)A causa foi um defeito no teste de aceitação quando eles testa...
Por que testar?
rodrigo@ic.ufal.br 45
Programadores “de verdade” não testam
o O importante é que funcione e que funcione rápido, se eu for fazer o teste
vai me ...
Bugs famosos
o Ariane 5
o Se auto-destruiu 37 segundos após a decolagem
o http://youtu.be/gp_D8r-2hwk
o Reutilização do mó...
Bugs famosos
o Ariane 5
rodrigo@ic.ufal.br 48
L_M_BV_32 := TBD.T_ENTIER_32S ((1.0/C_M_LSB_BV) * G_M_INFO_DERIVE(T_ALG.E_BV...
Bugs famosos
o Ariane 5
rodrigo@ic.ufal.br 49
L_M_BV_32 := TBD.T_ENTIER_32S ((1.0/C_M_LSB_BV) * G_M_INFO_DERIVE(T_ALG.E_BV...
Bugs famosos
o Therac 25
omáquina de radioterapia, controlada
por computador, muito moderna
para sua época, por permitir a...
Bugs famosos – Therac 25
o 2 modos de operação
oElétron (baixa intensidade radiação)
o Aplicada diretamente no paciente
oR...
Bugs famosos – Therac 25
o Problemas
o O software as vezes funcionava no
modo de alta intensidade e não
acionava o filtro,...
Bugs famosos – World of Warcraft
o Corrupted Blood Incident
o Masmorra de Zul'Gurub
o Um chefão: Hakkar (o deus do sangue)...
Bugs famosos – World of Warcraft
o BUG
o Pequenos animais e monstrinhos
(minions) se contaminaram e levaram
a magia para f...
Um exemplo Fila Circular de Tamanho Fixo
rodrigo@ic.ufal.br 55
Fila circular de tamanho fixo
• Operações básicas
• enqueue
• dequeue
• full
• empty
• Comportamento
• First in First Out ...
Fila circular de tamanho fixo
o Atributos
o size : int
o max : int
o head : int
o tail : int
o data : int[ ]
o Passos:
o C...
Fila circular de tamanho fixo
o empty(): retorna True caso fila esteja vazia
o full(): retorna True caso a fila cheia
o en...
Todo mundo fez?
o Terminaram???
rodrigo@ic.ufal.br 59
__init__
def __init__(self,size_max):
self.max = size_max
self.head = 0
self.tail = 0
self.size = 0
self.data = array.arra...
empy, full
def empty(self):
return self.size == 0
def full(self):
return self.size == self.max
rodrigo@ic.ufal.br 61
Pergunta
o Suponha que a gente crie uma fila de 2 elementos. Definiremos uma variável temporária
r1 como sendo o valor de ...
Pergunta
• Suponha o teste:
def test_queue(self):
q = Queue(2)
q.enqueue(7)
self.assertEquals(7,
q.dequeue())
• Caso o tes...
Testes equivalentes
o Dado um caso de teste, é possível concluir que um outro caso de teste
também irá funcionar? Mesmo se...
Prática
• No exemplo anterior, mostramos como um teste pode
ser um representante de uma classe
• Nesse exercício iremos fa...
Code It !!
o Existem várias soluções corretas
o O importante é exercitar as situações do código
rodrigo@ic.ufal.br 66
“Minha” solução
rodrigo@ic.ufal.br 67
enqueue
def enqueue(self,x):
if self.size == self.max:
return False
self.data[self.tail] = x
self.size += 1
self.tail += 1...
dequeue
def dequeue(self):
if self.size == 0:
return None
x = self.data[self.head]
self.size -= 1
self.head += 1
if self.h...
Assertivas de
execução
rodrigo@ic.ufal.br 70
Definições
o É uma verificação executável de uma propriedade do seu código
o Podem ser desligadas (discutiremos sobre isso...
Regras para o uso de assertivas
o As assertivas não devem ser utilizadas para o tratamento de erros
o No caso da função an...
Regras para o uso de assertivas
o As assertivas não devem provocar efeitos colaterais
oExemplo:
assert( funcao( ) == 0) ##...
Regras para o uso de assertivas
o Não escreva assertivas inúteis
oassert(1+1 ==2)
o Você deve buscar verificar propriedade...
CheckRep
o Algumas propriedades devem ser sempre verdade durante a
execução de um código
o Invariantes
o Exemplo com a nos...
Código para verificar a invariante
rodrigo@ic.ufal.br 76
Que outras invariantes poderíamos ter?
Vamos fazer uma pequena simulação
o http://youtu.be/SmdYmxQYIB0
rodrigo@ic.ufal.br 77
Problemas
o Veja que no primeiro caso, a nossa invariante foi acionada e o
programa parou
o Se ele não tivesse sido aciona...
Hora de melhorar as nossas invariantes
o Que outras invariantes seriam úteis para o nosso código da fila?
rodrigo@ic.ufal....
Mais invariantes
rodrigo@ic.ufal.br 80
Introduza um defeito
o vamos voltar a fazer o tail receber 1 ao invés de 0
o Veja que agora o check_rep levantou dois erro...
Por que usar assertivas?
o O código se torna auto-verificável
oFalha proativa
o Na presença de um defeito, o código falha ...
Devemos usar assertivas em produção?
o GCC: 9000 assertivas
o LLVM: 13.000 assertivas
1.2 milhões de linhas de código
apro...
Desabilitar assertivas em produção?
• Vantagens
• O código rodará mais rápido
• Se o seu código atingir um estado de
erro,...
Por outro lado
• Um engenheiro da NASA disse que
para a maior parte da missão da nave,
as assertivas estavam ligadas
• Lan...
Em outras palavras
o Em relação ao seu sistema ...
oÉ melhor que ele continue rodando e produzindo resultados errados?
o N...
Especificações
rodrigo@ic.ufal.br 87
Especificação
o O software que você irá testar pode ser
gigante ou muito pequeno
o Mas o fato é que você gostaria de poder...
Espeficificação
rodrigo@ic.ufal.br 89
o Suponha um software que calcula a raiz quadrada
o Qual a resposta esperada?
o a)
o...
Especificação
o Qualquer uma poderia estar correta
o Depende da sua especificação
o O software sempre funciona com base em...
Exercício
o Escreva sua especificação para a função “sqrt”
o Imagine que outra pessoa irá implementar
rodrigo@ic.ufal.br 91
Se usarmos a sua especificação e...
o ... chamarmos : sqrt(-1)
oA) 1
oB) i
oC) NaN
oD) levanta uma exceção
oE) -1
rodrigo@...
Domínios e contra-domínios
o Podemos pensar no software que
iremos testar como uma espécie de
função matemática
oDomínio: ...
Exemplo da raiz quadrada
o Poderíamos pensar na função da raiz como aceitando somente
números positivos e mostrando como r...
Na prática
o Os computadores representam reais como números de ponto
flutuante
o Suponha que queremos que o nosso domínio ...
Voltando as questões sobre testes
o Suponha a última especificação:
o Devemos testar esse código com entradas negativas?
o...
SIM!!!
o As entradas negativas fazem parte do domínio
o Devemos testar com amostras de valores retiradas do domínio
da fun...
Domínios claramente definidos
o Em muitos casos, é possível definir precisamente o domínio
oBibliotecas para uso interno, ...
Exemplo
o Chamada de sistema: read
o Disponível em plataformas UNIX: mac, Linux ...
rodrigo@ic.ufal.br 99
Quais desses testes são úteis?
a) Ler de um descritor de arquivo número 1 – esse é sempre
descritor válido --, assumindo q...
Resposta
o Todos!
oNão temos como garantir o domínio bem definido! Logo, devemos
pegar amostras, que somadas, possuam uma ...
Crashme
o Aloca um bloco de memória
o Escreve lixo nesse bloco
o Executa esse lixo no S.O.
rodrigo@ic.ufal.br 102
http://c...
Fronteira de confiança
o Se você possui uma interface que representa uma fronteira de
confiança, você precisa testar com o...
Fronteira de confiança
o Suponha que você possui algum tipo de interface para interagir
com o código dos outros membros da...
Testes, APIs e dependências
o Testar um software com base na sua API é
relativamente simples, basta chamar a API e olhar o...
Exemplo: WEB Browser
o O que fazer?
oBrowser crash
oIgnorar e se manter em um
estado de erro
oParar de usar cookies até
ex...
Teste, não espere!!
o Não espere que tudo que você depende funcione
o Mas como testar uma falha em algo que não controlamo...
Exemplo
o ssize_t read(int fd, void *buf,
size_t count);
o On success, the number of
bytes read is returned
o On error, -1...
Exemplo read() em Python
rodrigo@ic.ufal.br 109
Fault Injection
o Introduza uma `falta no seu código “de propósito” de forma a
testar como o seu sistema irá se comportar ...
Exemplo
rodrigo@ic.ufal.br 111
class MyTestCase(unittest.TestCase):
def test_read(self):
fr = FileReader("file.txt")
self....
Exemplo (cont.)
rodrigo@ic.ufal.br 112
class FileReader:
def __init__(self, file_name):
self.file = open(file_name,"r")
se...
Injetando uma falta
o Vamos simular um problema com a leitura do arquivo
rodrigo@ic.ufal.br 113
Fault Injection
rodrigo@ic.ufal.br 114
class FileReader:
def __init__(self, file_name, fault_injection):
self.file = open(...
Quando devemos injetar faltas (defeitos) ?
o Em todos os cenários de falha possíveis
o Em nenhum caso
o Nos locais onde vo...
Tipos de Teste
rodrigo@ic.ufal.br 116
White box X Black box
o White
oUso de detalhes internos do sistema para construir casos de testes
melhores
o Black
oSem o ...
Teste unitário
o Testa uma unidade de forma isolada
o Geralmente a unidade é pequena
o Geralmente o teste é caixa branca
o...
Teste unitário
o Muito suporte de ferramentas, frameworks
o*units
o Mock objects
oObjetos falsos que facilitam o teste de ...
Teste de integração
o A partir de múltiplos módulos que já foram testados com testes
unitários
o Testá-los em conjunto
o G...
Teste de sistema
o O sistema como um todo atende ao comportamento esperado?
o Geralmente não estamos preocupados com o que...
Outros tipos de teste
o Existem vários outros tipos de teste, mas de alguma forma eles
se “encaixam” em uma das três categ...
Outros tipos de testes
o Testes aleatórios
o As entradas do caso de teste são criadas aleatoriamente, usando algum gerador...
Quiz
o Você desenvolveu alguns novos serviços para a sua aplicação web
o Mas esses serviços serão disponibilizados somente...
Resposta
o Veja que estamos querendo avaliar as funcionalidades com um todo
o Não seria aleatório, pois não tem nenhum ele...
Outra quiz
o Temos um software bem grande pra testar
o Ele usa uma biblioteca para cálculos numéricos
o Mas biblioteca se ...
Quiz (cont.)
o Que tipo de teste você faria? (escolha somente uma)
oUnitário
oCaixa branca
oCaixa preta
oStress
rodrigo@ic...
Quiz - discussão
o Qualquer resposta poderia ser aceitável
o Mas provavelmente você fará um teste unitário, para testar a
...
Atitudes de um bom testador
o Desenvolvedor
o“Eu quero que esse código funcione”
o Testador
o“Eu quero fazer esse código f...
Upcoming SlideShare
Loading in …5
×

Testes de Software - Módulo 1

1,504 views
1,349 views

Published on

Aulas de teste de software.

Published in: Education
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
1,504
On SlideShare
0
From Embeds
0
Number of Embeds
3
Actions
Shares
0
Downloads
65
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Testes de Software - Módulo 1

  1. 1. Testes de Software Prof. Rodrigo de Barros Paes rodrigo@ic.ufal.br
  2. 2. Objetivos da disciplina COMP259 - TESTE DE SOFTWARE o Os objetivos da disciplina envolvem o estudo e prática de conceitos chave acerca de testes de software, tais quais estão abaixo: oFundamentos de Testes de Software oPlanejamento de Testes oTeste Caixa Preta oTeste Caixa Branca oFerramentas para apoio e automação de teste rodrigo@ic.ufal.br 2
  3. 3. Ementa específica o Domínio, intervalos, oráculos e tipos de teste o Cobertura do teste o Testes aleatórios o Teste aleatório na prática o Teste em uma aplicação web rodrigo@ic.ufal.br 3
  4. 4. Créditos o Muitos slides, ideias e referências desse curso tiveram origem nos seguintes locais oProf. Ardnt Von Staa, PUC-RIO, disciplina de Testes de Software, http://www.inf.puc-rio.br/~inf1413/ oMassachusetts Institute of Technology, Elements of Software Construction oUdacity, Software Testing (curso on-line) rodrigo@ic.ufal.br 4
  5. 5. Introdução Qualidade de Software rodrigo@ic.ufal.br 5
  6. 6. Do ponto de vista do usuário o Um sistema correto: oResolve o meu problema; oFunciona sempre que eu preciso dele; oEu entendo como usar; oEu posso justificavelmente depender dele. rodrigo@ic.ufal.br 6 Correct Systems: Building a Business Process Solution (Applied Computing) Paperback by Mike Holcombe, Florentin Ipate, 1998
  7. 7. Errare humanum est o Errar é inerente ao ser humano ocomo somos falíveis e o desenvolvimento de software é intensivo em esforço humano, é utópico esperar que software não contenha defeitos. o Sed in errore perseverare dementis (mas perseverar no erro é próprio do louco) oé frequente não aprendermos com os nossos erros de modo que possamos reduzir a frequência de defeitos em um novo software rodrigo@ic.ufal.br 7
  8. 8. O que é um sistema? rodrigo@ic.ufal.br 8 defeito erro falha vulnera bilidade sistema observador Engano do desenvolvedor ou falha da ferramenta Engano do desenvolvedor ou falha da ferramenta dano
  9. 9. Definições o Artefatos são resultados tangíveis resultantes do desenvolvimento ou da manutenção o Defeito é um fragmento de um artefato que, se utilizado, pode levar a um erro o Erro é um desvio entre o que é desejado ou intencionado e o que é gerado ou derivado o pode existir sem que se saiba isso o Falha é um erro observado o Latência do erro é o tempo decorrido entre o momento em que o erro é gerado e o momento em que é observado o quanto maior a latência significativamente maior é o custo da remoção da causa, i.e. o defeito rodrigo@ic.ufal.br 9
  10. 10. BUG o Indícios do uso da palavra BUG em engenharia o“Defeitos inexplicáveis” rodrigo@ic.ufal.br 10 It has been just so in all of my inventions. The first step is an intuition, and comes with a burst, then difficulties arise — this thing gives out and [it is] then that "Bugs" — as such little faults and difficulties are called — show themselves and months of intense watching, study and labor are requisite before commercial success or failure is certainly reached. Thomas Edison, 1878
  11. 11. BUG – na computação o Grace Hoper trabalhava no computador Mark II (Harvard) em 1946, quando o Mark II começou a apresentar uma falha oCausa: uma mariposa rodrigo@ic.ufal.br 11 Mark I (não achei foto do II)
  12. 12. Software é “Bugento” o Cerca de 40 a 50% dos programas postos em uso contêm defeitos não triviais o defeito não trivial: o demora para ser diagnosticado e removido o e/ou produz danos elevados o Como reduzir este percentual? o procurar chegar perto do ideal corretude por construção o realizar continuamente controle da qualidade: ao especificar, o arquitetar, projetar, codificar: corretude por desenvolvimento rodrigo@ic.ufal.br 12
  13. 13. Software é “Bugento”” o Como reduzir o tempo médio para recuperar? oProjeto e programação orientada à recuperabilidade o Como reduzir o tempo médio para corrigir? oprojeto e programação orientada à corrigibilidade rodrigo@ic.ufal.br 13 Boehm, B.W.; Basili, V.R.; "Software Defect Reduction Top 10 List"; IEEE Computer 34(1); Los Alamitos, CA: IEEE Computer Society; 2001; pags 135-137
  14. 14. Não existe software perfeito o Mesmo sistemas perfeitos podem falhar. Erros provocados por causas exógenas: o erros provocados por mau uso, deliberado ou não o erros provocados por falhas de hardware o erros provocados por falhas da plataforma de software usada o Perfeição não existe, densidade de defeitos [Bao, 2007]: o INTEL: no more than 80-90 defects in Pentium (em 2012: +- 3*10**9 transistores no chip; existem GPU’s com +- 7*10**9 transistores [Wikipedia]) o Standard Software: 25 defects / 1,000 lines of delivered code (kLOC) o Good Software: 2 defects / 1,000 lines o Space Shuttle Software: < 1 defect / 10,000 lines rodrigo@ic.ufal.br 14 Xinlong Bao; Software Engineering Failures: A Survey; School of EECS, Oregon State University, Corvallis, OR, U.S.A; apud Huckle, T.; Collection of Software Bugs; http://www5.in.tum.de/~huckle/bugse.html; last update October 5, 2007
  15. 15. Crenças o Não é possível prever todos os potenciais riscos (causas dos erros) o Não se pode esperar que sistemas não contenham defeitos oSe o sistema realmente não tiver defeitos, nós não temos como ter 100% de certeza. Ou seja, não saberemos. rodrigo@ic.ufal.br 15
  16. 16. Fidedignidade o Fidedignidade de software é definida como sendo a fidelidade de um sistema intensivo em software de modo que se possa justificavelmente depender dele assumindo riscos compatíveis com o serviço por ele prestado. o fidedigno (Adjetivo) Digno de fé; merecedor de crédito (Aurélio) o fidelidade (Substantivo feminino) Exatidão em cumprir suas obrigações, em executar suas promessas. (Aurélio) rodrigo@ic.ufal.br 16 RISCO = PROBABILIDADE X IMPACTO(CUSTO) X RELEVÂNCIA
  17. 17. Características da fidedignidade (básicas) o Adequação: prestar o serviço que interessa ao usuário usuário pode ser: pessoa; outro artefato; outro sistema; sensores e/ou atuadores; mantenedores; operadores; ... o Usabilidade: habilidade de interagir com o usuário sem induzi-lo a erro, nem permitir que erros de uso (observáveis) fiquem despercebidos o Durabilidade: habilidade do software operar fidedignamente por períodos de duração indefinida (longa duração, e.g. 24/7) o Confiabilidade: prestar continuamente serviço fidedigno o Disponibilidade: estar pronto para prestar serviço fidedigno sempre que solicitado rodrigo@ic.ufal.br 17
  18. 18. Características da fidedignidade (básicas) o Segurança: (safety) habilidade de evitar consequências catastróficas aos usuários, à organização, ou ao ambiente (risco baixo) o Proteção: habilidade de evitar o sucesso de tentativas de agressão o Privacidade: habilidade de proteger dados e código contra acesso (uso) indevido acidental ou deliberado o Desempenho: habilidade de produzir resultados necessitando de poucos recursos (ex. tempo, memória) otimização ou: habilidade de atender à demanda consumindo recursos dentro do limite estipulado o Escalabilidade: habilidade da capacidade de processamento do software crescer junto com o crescimento da demanda o Interoperabilidade: habilidade de ser corretamente conectado com outro sistema rodrigo@ic.ufal.br 18
  19. 19. Características da fidedignidade (tolerância) o Robustez: habilidade de, em tempo de execução, detectar erros (reportar falhas) de modo que os possíveis danos ou lesões possam ser mantidos em um patamar aceitável o um software robusto não provoca lesões (lesão: “prejuízo” não conhecido) o pode gerar danos desde que controlados (dano: “prejuízo” conhecido) o Resiliência: habilidade de amoldar-se a condições anormais de funcionamento sem comprometer a fidedignidade o Recuperabilidade: habilidade de ser rapidamente reposto em operação fidedigna, preventivamente ou após a ocorrência de uma falha o Corrigibilidade: habilidade de ser fácil e rapidamente corrigido quando da ocorrência de uma falha. rodrigo@ic.ufal.br 19
  20. 20. Características da fidedignidade (evolução) o Manutenibilidade: habilidade de poder ser modificado ou corrigido com facilidade e sem que novos defeitos sejam inseridos o manutenção preventiva – refactoring o correção – corrigibilidade o melhorias, adaptação e evolução – evolutibilidade o Longevidade: habilidade do software e dos dados persistentes por ele utilizados terem vida longa, evoluindo junto com as necessidades do usuário, com a plataforma, ou com a tecnologia utilizada para a sua implementação o engenharia reversa o reengenharia o rejuvenescimento o Co-evolutibilidade: facilidade de manter a coerência entre todos os artefatos que constituem o software. o Disponibilizabilidade: facilidade de distribuir e por em uso correto as novas versões. rodrigo@ic.ufal.br 20
  21. 21. Crenças (cont.) o Adicionar características de fidedignidade a posteriori é usualmente muito caro o as características necessárias precisam ser especificadas, arquitetadas, projetadas etc. junto com os requisitos funcionais o é necessário identificar a priori que características são necessárias o isso é sempre possível? o para atingir bons níveis de fidedignidade deve-se: o prevenir a injeção de defeitos o controlar as potenciais falhas provocadas por causas exógenas o Usuário o Plataforma o bibliotecas rodrigo@ic.ufal.br 21
  22. 22. O que queremos? rodrigo@ic.ufal.br 22 Ter a certeza de que estamos desenvolvendo software, de forma econômica, possuindo qualidade de serviço assegurada e capaz de operar em ambientes reais. Qualidade de serviço = qualidade observada pelo usuário
  23. 23. Qualidade de Software Definições básicas rodrigo@ic.ufal.br 23
  24. 24. Qualidade de um artefato o A qualidade de um artefato é um conjunto de propriedades a serem satisfeitas em determinado grau, de modo que o artefato satisfaça as necessidades explícitas e implícitas de seus usuários e clientes. o“Em determinado grau”  necessidade de definir e medir o“explícitas”  é preciso especificar o“implícitas”  requer o uso de “bom sendo”, conhecimento do domínio, conhecimento do negócio, mas mesmo assim, como saber se não deixamos algo passar? rodrigo@ic.ufal.br 24
  25. 25. Qualidade satisfatória o Um artefato possui qualidade satisfatória caso satisfaça plenamente as necessidades e anseios de clientes e usuários, oferecendo riscos de uso justificavelmente aceitáveis o fidedignidade o a noção de “satisfatório” varia o com a finalidade a que se destina o artefato o com a natureza do artefato o com o nível de treinamento / conhecimento do usuário rodrigo@ic.ufal.br 25
  26. 26. Conceitos básicos o Qualidade por construção o Um artefato possui qualidade por construção caso possua qualidade satisfatória, considerando todas as propriedades relevantes, antes do primeiro teste o Qualidade por desenvolvimento o Um artefato possui qualidade por desenvolvimento caso possua qualidade satisfatória, considerando todas as propriedades relevantes, antes de ser posto em uso o podem sobrar defeitos não conhecidos! o Qualidade por manutenção o Um artefato possui qualidade por manutenção caso possua qualidade satisfatória, considerando todas as propriedades relevantes, antes de ser reposto em uso o podem ter sido adicionados defeitos não conhecidos! rodrigo@ic.ufal.br 26
  27. 27. Modelo economia da qualidade rodrigo@ic.ufal.br 27 c u s t o qualidade assegurada pelo desenvolvimento custo desenvolvimento custo total custo do risco = f(probabilidade, impacto, relevância) Perda por falta de qualidade Perda por excesso de qualidade
  28. 28. Por que desenvolver com qualidade? o Custo do mau funcionamento, exemplos oAborrecimento, pequenas perdas financeiras e/ou de material, grandes perdas financeiras e/ou de material, falência de empresas, acidentes graves, danos ecológicos consideráveis, perda de vidas o Custo da correção oRetrabalho inútil rodrigo@ic.ufal.br 28
  29. 29. Por que desenvolver com qualidade? o Uma das principais causas do excessivo tempo gasto (custo) ao desenvolver software é o retrabalho inútil oÉ responsável por algo em torno de 50% a 80% do custo de desenvolvimento. o Retrabalho inútil – é trabalho que não precisaria ter sido realizado, se o trabalho anterior tivesse sido realizado visando fidedignidade, ou seja pelo menos de forma correta, completa, consistente, e adequada aos usuários rodrigo@ic.ufal.br 29 Fairley, R.E.; Willshire, M.J., "Iterative rework: the good, the bad, and the ugly," Computer , vol.38, no.9, pp.34,41, Sept. 2005
  30. 30. Exemplos de retrabalho inútil o desenvolver algo e descobrir que não era isso que se queria ou que se precisava o causa: especificação inexistente ou mal formulada o desenvolver algo e descobrir que está cheio de defeitos o causa: falta de disciplina o causa: falta de conhecimento de como raciocinar sobre programas, componentes, módulos e código o trabalhar sem foco o causa: falta de método de trabalho o perfeccionismo patológico o causa: melhorar, melhorar e melhorar mais ainda algo que já está satisfatório rodrigo@ic.ufal.br 30
  31. 31. Introdução a testes rodrigo@ic.ufal.br 31
  32. 32. Atividades típicas de um Software Análise e especificação de requisitos Protótipos de tela Projeto, provas de conceito Codificação (sistema + testes) Release Produção rodrigo@ic.ufal.br 32
  33. 33. Atividades típicas de um Software Análise e especificação de requisitos Protótipos de tela Projeto, provas de conceito Codificação (sistema + testes) Release Produção rodrigo@ic.ufal.br 33 Técnicas da garantia de qualidade: • Revisão de requisitos – busca por clareza, ausência de ambiguidades, etc. • Métricas para os requisitos, ex: #falhas nos testes cuja causa foram requisitos mal especificados • Especificação formal • Inspeções de código • Testes
  34. 34. Foco o Logo, esse curso se concentra em uma das atividades para se chegar a um software de maior qualidade o Embora existam outras rodrigo@ic.ufal.br 34
  35. 35. Introdução o Se nós pudermos encontrar os defeitos do nosso software o Se pudermos corrigir esses defeitos o Então, um dia teremos o software livre de “bugs”. Um software em que poderemos confiar!! o É só ter grana e investir em uma quantidade suficiente de testes rodrigo@ic.ufal.br 35
  36. 36. Algumas empresas com “grana” o Microsoft o Google rodrigo@ic.ufal.br 36
  37. 37. Mais algumas o Apple o Ubuntu rodrigo@ic.ufal.br 37
  38. 38. Hummm … beleza, e agora? o Se essas empresas não conseguiram, como eu vou conseguir fazer isso no meu próprio software? o Resposta curta: você também não vai conseguir! o Resposta longa: mas você pode chegar a uma qualidade satisfatória com a ajuda das técnicas do restante desse curso o Iremos quebrar esse problemão em vários pequenos problemas o Veremos técnicas específicas para cada um dos pequenos problemas o Quando você se tornar “bom” na resolução dos pequenos problemas, você fará software de forma mais confiável como um todo rodrigo@ic.ufal.br 38
  39. 39. O que é teste? o Como escolher boas entradas? o Sempre é possível saber o resultado esperado? o Sempre dá pra automatizar o teste? rodrigo@ic.ufal.br 39
  40. 40. Algumas dicas o Encontre defeitos o mais cedo possível o É possível gastar muito tempo na atividade de teste e ainda assim testar mal. Portanto, testar direito é importante, mas requer técnica e alguma imaginação o Nem sempre mais teste é melhor o A tarefa de teste pode ser facilitada se o software for projetado para ser testado rodrigo@ic.ufal.br 40
  41. 41. Falhou, e agora? o Quanto mais a gente “anda” para a direita nesse diagrama, mais a gente aprende sobre o software o O teste é um pequeno experimento onde um teste que falha indica que alguma coisa está errada. Descobrir onde está o erro é um processo a parte e muitas vezes trabalhoso. rodrigo@ic.ufal.br 41 test output
  42. 42. Exemplo o Em 1998, foi lançado um foguete para analisar o clima de Marte o A NASA subcontratou a empresa Lockheed Martin para ajudá-los com o software e com o foguete o Em 1999, o foguete chegou à Marte o Os cálculos da trajetória o A NASA esperava o que o sistema utilizasse a unidade métrica (metros por segundo) o A Lockheed Martin programou usando pés por segundo rodrigo@ic.ufal.br 42
  43. 43. Exemplo o Dano o O foguete executou uma trajetória diferente e explodiu em Marte o Embora tanto a NASA quanto a Lockheed tenha feito cálculos corretos, o software tenha sido programado corretamente, a falha aconteceu rodrigo@ic.ufal.br 43
  44. 44. Pergunta a) A causa foi um defeito no software sob teste? b)A causa foi um defeito no teste de aceitação quando eles testaram o software anteriormente? c) A causa foi um defeito na especificação do sistema? d)A causa foi um defeito no hardware ou no sistema operacional do foguete? Minha resposta é (c) rodrigo@ic.ufal.br 44
  45. 45. Por que testar? rodrigo@ic.ufal.br 45
  46. 46. Programadores “de verdade” não testam o O importante é que funcione e que funcione rápido, se eu for fazer o teste vai me atrasar o Eu comecei a programar aos 5 anos de idade, meu código é perfeito, não preciso de testes o Teste é para os programadores incompetentes o Nós somos programadores da UFAL, portanto nosso código funciona o A maioria das funções do minha classe Grafo.java possui apenas uma ou duas linhas. Essas linhas simplesmente utilizam funções das classes HashMap ou HashSet. Estou assumindo que essas funções funcionam perfeitamente e, portanto, não preciso testá-las. rodrigo@ic.ufal.br 46
  47. 47. Bugs famosos o Ariane 5 o Se auto-destruiu 37 segundos após a decolagem o http://youtu.be/gp_D8r-2hwk o Reutilização do módulo de navegação do Ariane 4 o Mas não simularam como esse módulo se comportaria sob as mesmas condições de vôo do Ariane 5 o A maior aceleração do Ariane 5 fez com uma conversão de dados de um float de 64 bits para um inteiro de 16 bits não fosse verificada para um provável overflow o O que de fato aconteceu rodrigo@ic.ufal.br 47
  48. 48. Bugs famosos o Ariane 5 rodrigo@ic.ufal.br 48 L_M_BV_32 := TBD.T_ENTIER_32S ((1.0/C_M_LSB_BV) * G_M_INFO_DERIVE(T_ALG.E_BV)); if L_M_BV_32 > 32767 then P_M_DERIVE(T_ALG.E_BV) := 16#7FFF#; elsif L_M_BV_32 < -32768 then P_M_DERIVE(T_ALG.E_BV) := 16#8000#; else P_M_DERIVE(T_ALG.E_BV) := UC_16S_EN_16NS(TDB.T_ENTIER_16S(L_M_BV_32)); end if; P_M_DERIVE(T_ALG.E_BH) := UC_16S_EN_16NS (TDB.T_ENTIER_16S ((1.0/C_M_LSB_BH) * G_M_INFO_DERIVE(T_ALG.E_BH))); Verificaram o overflow para a variável E_BV (trajetória vertical) Esqueceram de fazer a mesma coisa para a variável E_BH (trajetória horizontal)
  49. 49. Bugs famosos o Ariane 5 rodrigo@ic.ufal.br 49 L_M_BV_32 := TBD.T_ENTIER_32S ((1.0/C_M_LSB_BV) * G_M_INFO_DERIVE(T_ALG.E_BV)); if L_M_BV_32 > 32767 then P_M_DERIVE(T_ALG.E_BV) := 16#7FFF#; elsif L_M_BV_32 < -32768 then P_M_DERIVE(T_ALG.E_BV) := 16#8000#; else P_M_DERIVE(T_ALG.E_BV) := UC_16S_EN_16NS(TDB.T_ENTIER_16S(L_M_BV_32)); end if; L_M_BH_32 := TBD.T_ENTIER_32S ((1.0/C_M_LSB_BH) * G_M_INFO_DERIVE(T_ALG.E_BH)); if L_M_BH_32 > 32767 then P_M_DERIVE(T_ALG.E_BH) := 16#7FFF#; elsif L_M_BH_32 < -32768 then P_M_DERIVE(T_ALG.E_BH) := 16#8000#; else P_M_DERIVE(T_ALG.E_BH) := UC_16S_EN_16NS(TDB.T_ENTIER_16S(L_M_BH_32)); end if; Código corrigido
  50. 50. Bugs famosos o Therac 25 omáquina de radioterapia, controlada por computador, muito moderna para sua época, por permitir a utilização do mesmo equipamento para a aplicação de diversas doses de radiação nos pacientes. rodrigo@ic.ufal.br 50
  51. 51. Bugs famosos – Therac 25 o 2 modos de operação oElétron (baixa intensidade radiação) o Aplicada diretamente no paciente oRaio-X (alta intensidade de radiação) o Passava por um “filtro”, era convertida em raios X e tinha sua intensidade diminuída e “espalhada” rodrigo@ic.ufal.br 51
  52. 52. Bugs famosos – Therac 25 o Problemas o O software as vezes funcionava no modo de alta intensidade e não acionava o filtro, fazendo com que a radiação fosse aplicada diretamente sobre os pacientes o O software não detectava quando essa situação ocorria (assertivas) o Danos o 6 acidentes e 5 mortes entre 1985 e 1987 rodrigo@ic.ufal.br 52
  53. 53. Bugs famosos – World of Warcraft o Corrupted Blood Incident o Masmorra de Zul'Gurub o Um chefão: Hakkar (o deus do sangue) o Quando atacado, lançava sobre os oponentes uma magia do “Corrupted Blood” o A magia deveria o Durar apenas alguns segundos o Ficar restrita a uma determinada área de Zul'Gurub rodrigo@ic.ufal.br 53
  54. 54. Bugs famosos – World of Warcraft o BUG o Pequenos animais e monstrinhos (minions) se contaminaram e levaram a magia para fora da área determinada o Outros personagens se contaminaram o Configurou-se uma pandemia o Muita reclamação dos usuários o Usuários evitaram áreas de grandes concentrações rodrigo@ic.ufal.br 54
  55. 55. Um exemplo Fila Circular de Tamanho Fixo rodrigo@ic.ufal.br 55
  56. 56. Fila circular de tamanho fixo • Operações básicas • enqueue • dequeue • full • empty • Comportamento • First in First Out (FIFO) • Exemplo • enqueue(7) enqueue(8) dequeue() # deve retornar 7 dequeue() # deve retornar 8 dequeue() # deve retornar algum erro ou vazio rodrigo@ic.ufal.br 56
  57. 57. Fila circular de tamanho fixo o Atributos o size : int o max : int o head : int o tail : int o data : int[ ] o Passos: o Criar uma classe Queue o O método inicial “__init__” deve receber o tamanho máximo da fila o O array deve ser estático (http://docs.python.org/3/library/array.html) rodrigo@ic.ufal.br 57
  58. 58. Fila circular de tamanho fixo o empty(): retorna True caso fila esteja vazia o full(): retorna True caso a fila cheia o enqueue(x): adiciona o elemento x na fila e returna True caso tenha conseguido adicionar. False caso não seja possível adicionar o elemento o dequeue(): retorna o próximo elemento da fila, caso exista. None caso contrário. rodrigo@ic.ufal.br 58
  59. 59. Todo mundo fez? o Terminaram??? rodrigo@ic.ufal.br 59
  60. 60. __init__ def __init__(self,size_max): self.max = size_max self.head = 0 self.tail = 0 self.size = 0 self.data = array.array('i', range(size_max)) rodrigo@ic.ufal.br 60
  61. 61. empy, full def empty(self): return self.size == 0 def full(self): return self.size == self.max rodrigo@ic.ufal.br 61
  62. 62. Pergunta o Suponha que a gente crie uma fila de 2 elementos. Definiremos uma variável temporária r1 como sendo o valor de retorno do enfileiramento do inteiro 6, r2 o valor retornado do enfileiramento do inteiro 7, r3 retorno do enfileiramento do inteiro 8, r4 o valor retornado pelo desenfileiramento de um elemento, r5 ser o valor devolvido pelo desenfileiramento de outro elemento, e, finalmente, r6 ser o valor devolvido pelo desenfileiramento de mais um elemento. Qual o valor dessas variáveis? o a) 6, 7, 8, 6, 7, 8. o b) True, True, True, 6, 7, None. o c) True, True, False, 6, 7, 8. o d) True, True, False, 6, 7, None. o A resposta correta é d rodrigo@ic.ufal.br 62
  63. 63. Pergunta • Suponha o teste: def test_queue(self): q = Queue(2) q.enqueue(7) self.assertEquals(7, q.dequeue()) • Caso o teste seja um sucesso, o que aprendemos? a) Nosso código passou nesse caso de teste; b) Nosso código passará em qualquer caso em que troquemos o 7 por outro inteiro; c) Nosso código passará em muitos casos em que troquemos o 7 por outro inteiro; • Resposta • Obviamente a (a) está correta; • Será que a (b) está correta? • E se passarmos um inteiro tão grande que o tipo inteiro da sua linguagem não conseguir armazená-lo? • A (c) também está correta rodrigo@ic.ufal.br 63 Verifica se o valor esperado é igual ao valor obtido. Nesse caso, verifica se 7 é igual ao retorno de q.dequeue() Moral da história: ao fazer um caso de teste, pense o que você poderá inferir a partir dele. Com isso você evitará escrever muitos casos de teste que significam a mesma coisa
  64. 64. Testes equivalentes o Dado um caso de teste, é possível concluir que um outro caso de teste também irá funcionar? Mesmo sem de fato executar o caso de teste? rodrigo@ic.ufal.br 64 ? Olhe novamente para o seu código. O fato de haver um sleep trará alguma consequência? Existe alguma dependência do tempo? 1 caso de teste como representante de uma classe de entradas e saídas
  65. 65. Prática • No exemplo anterior, mostramos como um teste pode ser um representante de uma classe • Nesse exercício iremos fazer o contrário, ou seja, não vamos testar funcionalidades equivalentes • Escreva mais uma ou duas funções de teste de forma a explorar situações que a função test_1 não explorou, por exemplo: • Não testamos o caso onde a fila fica cheia no enqueue • Não testamos a situação onde a fila está vazia e tentamos fazer um dequeue • … • Chame a sua primeira função de test_enqueue e procure explorar os testes da função enqueue • Chame a segunda função de test_dequeue e explore os testes da função dequeue rodrigo@ic.ufal.br 65
  66. 66. Code It !! o Existem várias soluções corretas o O importante é exercitar as situações do código rodrigo@ic.ufal.br 66
  67. 67. “Minha” solução rodrigo@ic.ufal.br 67
  68. 68. enqueue def enqueue(self,x): if self.size == self.max: return False self.data[self.tail] = x self.size += 1 self.tail += 1 if self.tail == self.max: self.tail = 0 return True rodrigo@ic.ufal.br 68
  69. 69. dequeue def dequeue(self): if self.size == 0: return None x = self.data[self.head] self.size -= 1 self.head += 1 if self.head == self.max: self.head = 0 return x rodrigo@ic.ufal.br 69
  70. 70. Assertivas de execução rodrigo@ic.ufal.br 70
  71. 71. Definições o É uma verificação executável de uma propriedade do seu código o Podem ser desligadas (discutiremos sobre isso depois) o Exemplo: cálculo da função de raiz quadrada def sqrt(x): ## aqui ficaria o seu código para encontrar a raiz quadrada assert(result >= 0) return result rodrigo@ic.ufal.br 71 an assertion is a predicate (a true–false statement) placed in a program to indicate that the developer thinks that the predicate is always true at that place. If an assertion evaluates to false at run-time, an assertion failure results, which typically causes execution to abort. wikipedia
  72. 72. Regras para o uso de assertivas o As assertivas não devem ser utilizadas para o tratamento de erros o No caso da função anterior, poderíamos ter feito: def sqrt(x): assert(x >= 0) ## aqui ficaria o seu código para encontrar a raiz quadrada assert(result >= 0) return result o Só que: o x foi gerado em alguma outra parte do código e, portanto, o local da assertiva deveria ser lá o Se você quiser garantir a pré-condição que x é maior que zero, seria mais adequado realizar um tratamento de erros (http://docs.python.org/2/tutorial/errors.html) rodrigo@ic.ufal.br 72
  73. 73. Regras para o uso de assertivas o As assertivas não devem provocar efeitos colaterais oExemplo: assert( funcao( ) == 0) ## só que funcao( ) muda o valor de alguma variável com escopo global (atributo de objeto, variável estática, …) oO que aconteceria se desligassemos as assertivas? o O código teria um comportamento diferente com assertivas e sem assertivas rodrigo@ic.ufal.br 73
  74. 74. Regras para o uso de assertivas o Não escreva assertivas inúteis oassert(1+1 ==2) o Você deve buscar verificar propriedades não-triviais que poderia estar errada caso você tenha colocado algum defeito na sua lógica rodrigo@ic.ufal.br 74
  75. 75. CheckRep o Algumas propriedades devem ser sempre verdade durante a execução de um código o Invariantes o Exemplo com a nossa fila: o 0 <=size <= max o Uma ideia é criar uma função para verificar essas invariantes o Você deve chamar essa função no final de cada método do seu objeto … assim você verifica se você não “quebrou” nenhuma dessas invariantes rodrigo@ic.ufal.br 75
  76. 76. Código para verificar a invariante rodrigo@ic.ufal.br 76 Que outras invariantes poderíamos ter?
  77. 77. Vamos fazer uma pequena simulação o http://youtu.be/SmdYmxQYIB0 rodrigo@ic.ufal.br 77
  78. 78. Problemas o Veja que no primeiro caso, a nossa invariante foi acionada e o programa parou o Se ele não tivesse sido acionada, provavelmente o programa continuaria rodando, mas em um estado de erro o Ou seja, resultados provavelmente iriam acontecer .... e outras partes do programa o O segundo caso ilustra a utilidade de mantermos testes automatizados rodrigo@ic.ufal.br 78
  79. 79. Hora de melhorar as nossas invariantes o Que outras invariantes seriam úteis para o nosso código da fila? rodrigo@ic.ufal.br 79
  80. 80. Mais invariantes rodrigo@ic.ufal.br 80
  81. 81. Introduza um defeito o vamos voltar a fazer o tail receber 1 ao invés de 0 o Veja que agora o check_rep levantou dois erros, tanto no deste de enqueue quanto no de dequeue (que não havia sido detectado antes) o As assertivas verificaram o detalhe interno da estrutura de dados, muitas vezes inacessível a um teste devido ao encapsulamento rodrigo@ic.ufal.br 81
  82. 82. Por que usar assertivas? o O código se torna auto-verificável oFalha proativa o Na presença de um defeito, o código falha antes, e falha próximo da origem do defeito, reduzindo o tempo de debugging o Funcionam como uma espécie de documentação executável deixando explícito as premissas que você usou para construir o código rodrigo@ic.ufal.br 82
  83. 83. Devemos usar assertivas em produção? o GCC: 9000 assertivas o LLVM: 13.000 assertivas 1.2 milhões de linhas de código aproximadamente 1 assertiva para cada 100 linhas de código o Certo .... E daí? Devemos usar em produção? rodrigo@ic.ufal.br 83
  84. 84. Desabilitar assertivas em produção? • Vantagens • O código rodará mais rápido • Se o seu código atingir um estado de erro, ele continua rodando, ou seja, não pára • Desvantagens • A gente quer que o sistema continue rodando, mesmo podendo gerar resultados errados? • Ou seja, o que é menos ruim? • Com as assertivas, o código irá parar perto do local do erro, facilitando o debugging rodrigo@ic.ufal.br 84 "This code is absolutely loaded with assertions, and these are permanently enabled. As Valgrind has become more widely used, they have shown they worth, pulling up various bugs which would otherwise have appeared as hard-to-find segmentation faults. I am of the view that it's acceptable to spend 5% of the total running time doing assertion checks." Valgrind tools that can automatically detect many memory management and threading bugs, and profile your programs in detail
  85. 85. Por outro lado • Um engenheiro da NASA disse que para a maior parte da missão da nave, as assertivas estavam ligadas • Lançamento • Cruzeiro • Órbita em Marte • Em caso de violação, o sistema era reiniciado • Porém, pouco antes do pouso, as assertivas eram desligadas • Não daria tempo de reiniciar o sistema • Era melhor tentar pousar de qualquer jeito rodrigo@ic.ufal.br 85
  86. 86. Em outras palavras o Em relação ao seu sistema ... oÉ melhor que ele continue rodando e produzindo resultados errados? o Não use assertivas oOu é melhor que ele pare logo a execução? o Use assertivas rodrigo@ic.ufal.br 86
  87. 87. Especificações rodrigo@ic.ufal.br 87
  88. 88. Especificação o O software que você irá testar pode ser gigante ou muito pequeno o Mas o fato é que você gostaria de poder encapsular a implementação das funcionalidades e testar as funcionalidades rodrigo@ic.ufal.br 88
  89. 89. Espeficificação rodrigo@ic.ufal.br 89 o Suponha um software que calcula a raiz quadrada o Qual a resposta esperada? o a) o b) o a) e b)
  90. 90. Especificação o Qualquer uma poderia estar correta o Depende da sua especificação o O software sempre funciona com base em alguma especificação oSeja ela implícita ou explícita o Parte do seu trabalho como testador é refinar a especificação, garantir que o entendimento está correto. rodrigo@ic.ufal.br 90
  91. 91. Exercício o Escreva sua especificação para a função “sqrt” o Imagine que outra pessoa irá implementar rodrigo@ic.ufal.br 91
  92. 92. Se usarmos a sua especificação e... o ... chamarmos : sqrt(-1) oA) 1 oB) i oC) NaN oD) levanta uma exceção oE) -1 rodrigo@ic.ufal.br 92 Essa não dá Se estivermos trabalhando com números complexos, essa seria uma resposta aceitável Também é uma resposta aceitável Também é uma resposta aceitável Essa também não dá
  93. 93. Domínios e contra-domínios o Podemos pensar no software que iremos testar como uma espécie de função matemática oDomínio: conjunto de todos os valores que o software foi projetado para gerenciar oContra-domínio (range): conjunto de todos os valores de saída possíveis para o software rodrigo@ic.ufal.br 93
  94. 94. Exemplo da raiz quadrada o Poderíamos pensar na função da raiz como aceitando somente números positivos e mostrando como resposta apenas números positivos o Uma outra função poderia aceitar qualquer número como entrada e oferecer como saída qualquer número, inclusive complexos rodrigo@ic.ufal.br 94
  95. 95. Na prática o Os computadores representam reais como números de ponto flutuante o Suponha que queremos que o nosso domínio aceite números negativos, mas que a resposta não seja de números complexos rodrigo@ic.ufal.br 95
  96. 96. Voltando as questões sobre testes o Suponha a última especificação: o Devemos testar esse código com entradas negativas? oSim oNão rodrigo@ic.ufal.br 96
  97. 97. SIM!!! o As entradas negativas fazem parte do domínio o Devemos testar com amostras de valores retiradas do domínio da função rodrigo@ic.ufal.br 97
  98. 98. Domínios claramente definidos o Em muitos casos, é possível definir precisamente o domínio oBibliotecas para uso interno, uma classe que só será usada por outras classes dentro de um mesmo projeto, etc. o Porém, em outros códigos não é possível definir esse domínio, pois você não terá controle da entrada oEntrada de usuários, APIs acessíveis via Internet, uma API de um sistema operacional, etc. rodrigo@ic.ufal.br 98
  99. 99. Exemplo o Chamada de sistema: read o Disponível em plataformas UNIX: mac, Linux ... rodrigo@ic.ufal.br 99
  100. 100. Quais desses testes são úteis? a) Ler de um descritor de arquivo número 1 – esse é sempre descritor válido --, assumindo que você passa um buffer válido e você irá ler 10 bytes; b) Ler em um buffer, 10 bytes mas usar o descritor -99999 c) Usar o descritor 1, mas passar como buffer um ponteiro para uma posição de memória inválida e ler 10 bytes d) Usar o descritor 1, usar um buffer válido, mas ler -33333 bytes rodrigo@ic.ufal.br 100
  101. 101. Resposta o Todos! oNão temos como garantir o domínio bem definido! Logo, devemos pegar amostras, que somadas, possuam uma grande representatividade do domínio o S.O. oPara o SO, da API pra “baixo”, ele confia nos componentes. Da “API” pra cima, ele tem que assumir que os programas irão atacá-los, ou usá-lo de forma errada oEle precisa ser defensivo rodrigo@ic.ufal.br 101
  102. 102. Crashme o Aloca um bloco de memória o Escreve lixo nesse bloco o Executa esse lixo no S.O. rodrigo@ic.ufal.br 102 http://crashme.codeplex.com/
  103. 103. Fronteira de confiança o Se você possui uma interface que representa uma fronteira de confiança, você precisa testar com os valores que representam o máximo do seu domínio rodrigo@ic.ufal.br 103
  104. 104. Fronteira de confiança o Suponha que você possui algum tipo de interface para interagir com o código dos outros membros da equipe o Eles podem confiar que você irá sempre gerar entradas válidas de acordo com o domínio dessas entradas? o E ao contrário? Você pode confiar neles? o Geralmente a resposta é não!! rodrigo@ic.ufal.br 104
  105. 105. Testes, APIs e dependências o Testar um software com base na sua API é relativamente simples, basta chamar a API e olhar os resultados o O problema é que muitas vezes o software que disponibiliza uma API também usa uma API rodrigo@ic.ufal.br 105
  106. 106. Exemplo: WEB Browser o O que fazer? oBrowser crash oIgnorar e se manter em um estado de erro oParar de usar cookies até existir espaço em disco rodrigo@ic.ufal.br 106 GUI network file ... process page store cookie save disk is full !
  107. 107. Teste, não espere!! o Não espere que tudo que você depende funcione o Mas como testar uma falha em algo que não controlamos? rodrigo@ic.ufal.br 107
  108. 108. Exemplo o ssize_t read(int fd, void *buf, size_t count); o On success, the number of bytes read is returned o On error, -1 is returned, and errno is set appropriately rodrigo@ic.ufal.br 108
  109. 109. Exemplo read() em Python rodrigo@ic.ufal.br 109
  110. 110. Fault Injection o Introduza uma `falta no seu código “de propósito” de forma a testar como o seu sistema irá se comportar em situações difíceis de reproduzir oPouca memória oHD sem espaço rodrigo@ic.ufal.br 110
  111. 111. Exemplo rodrigo@ic.ufal.br 111 class MyTestCase(unittest.TestCase): def test_read(self): fr = FileReader("file.txt") self.assertEquals("This is a test file!",fr.get_content()) This is a test file!
  112. 112. Exemplo (cont.) rodrigo@ic.ufal.br 112 class FileReader: def __init__(self, file_name): self.file = open(file_name,"r") self.content = self.file.read() def get_content(self): return self.content
  113. 113. Injetando uma falta o Vamos simular um problema com a leitura do arquivo rodrigo@ic.ufal.br 113
  114. 114. Fault Injection rodrigo@ic.ufal.br 114 class FileReader: def __init__(self, file_name, fault_injection): self.file = open(file_name,"r") self.fault_injection = fault_injection if ( not self.fault_injection): self.content = self.file.read() else: self.content = self.my_read() def my_read(self, size=None ): # lê com um caracter a menos, simulando um eventual problema de pouca memória return self.file.read(size)[:-1] def get_content(self): return self.content
  115. 115. Quando devemos injetar faltas (defeitos) ? o Em todos os cenários de falha possíveis o Em nenhum caso o Nos locais onde você espera que aconteça e que você espera que o seu software se comporte bem rodrigo@ic.ufal.br 115
  116. 116. Tipos de Teste rodrigo@ic.ufal.br 116
  117. 117. White box X Black box o White oUso de detalhes internos do sistema para construir casos de testes melhores o Black oSem o uso de detalhes internos. Teste baseado na entrada e saída esperadas, sem saber como as funções foram de fato implementadas rodrigo@ic.ufal.br 117
  118. 118. Teste unitário o Testa uma unidade de forma isolada o Geralmente a unidade é pequena o Geralmente o teste é caixa branca o Geralmente quem testa é a mesma pessoa que implementa rodrigo@ic.ufal.br 118
  119. 119. Teste unitário o Muito suporte de ferramentas, frameworks o*units o Mock objects oObjetos falsos que facilitam o teste de um componente isoladamente rodrigo@ic.ufal.br 119
  120. 120. Teste de integração o A partir de múltiplos módulos que já foram testados com testes unitários o Testá-los em conjunto o Geralmente se testa a integração dos módulos rodrigo@ic.ufal.br 120
  121. 121. Teste de sistema o O sistema como um todo atende ao comportamento esperado? o Geralmente não estamos preocupados com o que se passa “por baixo dos panos” oDesde que o sistema se comporte como esperado o Geralmente o teste é caixa-preta rodrigo@ic.ufal.br 121
  122. 122. Outros tipos de teste o Existem vários outros tipos de teste, mas de alguma forma eles se “encaixam” em uma das três categorias, ou tipos, de teste anteriores oMultiple version testing o Mesma entrada  múltiplas implementações da mesma funcionalidade  comparar resultados oTeste de stress o Teste do sistema sob condições anormais o Pouquíssima memória, número absurdo de usuários simultâneos... rodrigo@ic.ufal.br 122
  123. 123. Outros tipos de testes o Testes aleatórios o As entradas do caso de teste são criadas aleatoriamente, usando algum gerador de números aleatórios o Exemplo: o Crashme o Testes de regressão o Usar uma entrada que já fez o software falhar, provavelmente em produção, e construir um caso de teste que reproduza a falha. o Assim, se o defeito for corrigido, e por alguma razão for reintroduzido no futuro, a falha será detectada pelo teste rodrigo@ic.ufal.br 123
  124. 124. Quiz o Você desenvolveu alguns novos serviços para a sua aplicação web o Mas esses serviços serão disponibilizados somente para um subconjunto pequeno de usuários o Você quer avaliar se as novas funcionalidades terão uma boa aceitação o Que tipo de teste você faria? o Integração o Diferencial o Aleatório o Sistema rodrigo@ic.ufal.br 124
  125. 125. Resposta o Veja que estamos querendo avaliar as funcionalidades com um todo o Não seria aleatório, pois não tem nenhum elemento aleatório (mais ou menos) o Não temos múltiplas implementações de uma mesma “coisa” crítica. Logo não é diferencial o Não estamos focados na integração entre módulos o Por outro lado, queremos saber se o sistema se comporta como esperado, como um todo rodrigo@ic.ufal.br 125
  126. 126. Outra quiz o Temos um software bem grande pra testar o Ele usa uma biblioteca para cálculos numéricos o Mas biblioteca se comporta mal, gerando exceções de ponto flutuante de tempos em tempos o O fornecedor da biblioteca lançou uma nova versão o Mas o histórico indica que quando uma nova versão é lançada, muitos novos bugs são inseridos o Você precisa avaliar se vale a pena instalar a nova versão rodrigo@ic.ufal.br 126
  127. 127. Quiz (cont.) o Que tipo de teste você faria? (escolha somente uma) oUnitário oCaixa branca oCaixa preta oStress rodrigo@ic.ufal.br 127
  128. 128. Quiz - discussão o Qualquer resposta poderia ser aceitável o Mas provavelmente você fará um teste unitário, para testar a biblioteca em isolado o Você poderia também usar um teste diferencial em algumas funções o Como não falei se o código fonte estava disponível, poderia ser caixa preta ou branca rodrigo@ic.ufal.br 128
  129. 129. Atitudes de um bom testador o Desenvolvedor o“Eu quero que esse código funcione” o Testador o“Eu quero fazer esse código falhar” o Seja criativo e reflexivo o Nunca ignore algum comportamento estranho da sua aplicação rodrigo@ic.ufal.br 129

×