Upload
kaique-caetano
View
214
Download
0
Embed Size (px)
Citation preview
MBT (1)
• O que é um modelo?– descrição (incompleta) de comportamento de
um elemento (usuário, software, indústria, etc.)• O que é MBT?
– Geração de casos de teste a partir de modelo
MBT (2)
• Vantagens:– Não precisa acessar o código: caixa-branca– Descreve apenas o que o software precisa
obedecer• Desvantagens:
– Modelo pode ser caro de construir e manter
Um cenário
• Usuário constrói modelo• Ferramenta gera testes a partir do modelo• Script executa e classifica testes:
sucesso/falha• Script pode minimizar conjunto de testes
reportados (seleção). Por exemplo:– Baseado em cobertura– Baseado em falha
Um cenário
• Usuário constrói modelo• Ferramenta gera testes a partir do modelo• Script executa e classifica testes:
sucesso/falha• Script pode minimizar conjunto de testes
reportados (seleção). Por exemplo:– Baseado em cobertura– Baseado em falha
Ênfase
Modelo de interação de uso
• Representa possíveis interações do usuário com o sistema– Inclui possíveis dados de entrada – Inclui possíveis sequências
Geração do teste faz uso destas alternativas!
Exercício
• Construa uma máquina de estados para gerar dados e seqüências de operações de depósito e transferência bancária – Ignore oracles
Duas fontes de não determinismo: sequência
(depósito/transferência) e dados
deposito transferencia
num. agencia
num. c.c.
num. agencia origem
num. c.c. origem
num. agencia
num. cc
valor valor
Opção 1: Máquina de estados
Quiz
• O que representa cada nó do grafo?
Quiz
• O que representa cada nó do grafo?– Estado
• mental do usuário de um caixa eletrônico• de um programa gerador de casos de teste
Note que o estado após um depósito é o estado inicial. Portanto, o estado não
corresponde ao estado do sistema.
Modelo de interação
• Pode ser útil para encontrar crashes• Modelo do sistema define comportamento
– Útil para encontrar erros lógicos (conformidade)– Requer função de abstração
Comparação de estado
executa operação
compara (α)
MODELO SISTEMA
Opção 2: Modelo em código
• Construir modelo direto no código– Modelo contém mais detalhes– Pode construir teste simultaneamente a geração
• Reduz necessidade de scripts de execução• Facilita definição de pré e pós-condições
Operador de escolha
• Ch(E1,…,En) é uma expressão da ling.– Semântica randômica
• Retorna valor de Ej para um j sorteado– Semântica exaustiva
• Constrói n execuções. Retorna valor de Ei para cada 1<i<n
Operador de escolha
• Ch(E1,…,En) é uma expressão da ling.– Semântica randômica
• Retorna valor de Ej para um j sorteado– Semântica exaustiva
• Constrói n execuções. Retorna valor de Ei para cada 1<i<n
Assuma semântica randômica daqui em diante.
Outra versão com mais detalhes
void genDeposito() { int ag = ch(777,888, 999); int cc = ch(1023, 54, 85); int valor = ch(124.2, 300, 9.99); deposito(ag,cc,valor);}
void genTransferencia() { int ag1 = ch(777,888, 999); int cc1 = ch(1023, 54, 85); int ag2 = ch(777,888, 999); int cc2 = ch(1023, 54, 85); int valor = ch(124.2, 300, 9.99); transferencia(ag1,cc1,ag2,cc2, valor);}
void genOneTest() { /* gerador de casos de teste*/ while(seqLen++ < N) { int op = ch(0,1); switch(op) { 0: genDeposito(); break; 1: genTransferencia(); break; default: throw new RuntimeException(); } }}
Quiz 1
• Este código precisa necessariamente ser usado em conjunto com o sistema?
Quiz 1
• Este código precisa necessariamente ser usado em conjunto com o sistema?– Não. É possível construir testes.
• As linguagens de descrição do modelo e da aplicação não precisam ser a mesma
Onde está o teste?
• Valores de entrada e seqüência de chamadas de depósito e transferência
• (Mais sobre oracle adiante.)
Sequência exemplo (N =3)
deposito(777,1023,124.2); deposito(888, 54, 300); transferencia(777,85, 888, 54, 300);
Oracles
• Como saber se o teste passou?– As sequências omitem o oracle
Oracles
void genDeposito() { int ag = ch(777,888, 999); int cc = ch(1023, 54, 85); int valor = ch(124.2, 300, 9.99); int saldo = readSaldo(ag,cc); deposito(ag,cc,valor); Assert.assertEquals(saldo+valor, readSaldo(ag,cc));}
Tipicamente, a construção de oracles é uma atividade manual (parte do modelo)
Pré e Pós condições
• É possível que a intenção seja testar apenas combinações válidas de dados e sequência!
Necessário declarar pré condiçoes para restringir comportamentos do modelo
Pré-condiçõesmap = { // agencia, conta corrente 777 => {1023}, 888 => {54}, 999 => {85}};valores = {124.2, 300, 9.99};void genTransferencia() { int ag1 = ch(777,888, 999); int cc1 = ch(map.get(ag1)); int ag2 = ch(map.keys – {ag1}); int cc2 = ch(map.get(ag2)); int saldo = readSaldo(ag1, cc1); int valor = ch({v < saldo| v \in valores}); transferencia(ag1,cc1,ag2,cc2, valor);}
Pré-condiçõesmap = { // agencia, conta corrente 777 => {1023}, 888 => {54,99}, 999 => {85}};valores = {124.2, 300, 9.99};void genTransferencia() { int ag1 = ch(777,888, 999); int cc1 = ch(map.get(ag1)); int ag2 = ch(map.keys – {ag1}); int cc2 = ch(map.get(ag2)); int saldo = readSaldo(ag1, cc1); int valor = ch({v < saldo| v \in valores}); transferencia(ag1,cc1,ag2,cc2, valor);}
Note que se execução violar uma única pre-condição, o teste é inconclusivo! mesmo se falhar!
Pré-condiçõesmap = { // agencia, conta corrente 777 => {1023}, 888 => {54,99}, 999 => {85}};valores = {124.2, 300, 9.99};void genTransferencia() { int ag1 = ch(777,888, 999); int cc1 = ch(map.get(ag1)); int ag2 = ch(map.keys – {ag1}); int cc2 = ch(map.get(ag2)); int saldo = readSaldo(ag1, cc1); int valor = ch({v < saldo| v \in valores}); transferencia(ag1,cc1,ag2,cc2, valor);}
Modelo é aproximado. Perde comportamentos!
Aproximações
• Sobre-aproximações– Superconjunto dos comp. do sistema real– Podem construir falso-positivos
• viola pre-condições
• Sub-aproximações– Subconjunto dos comp. do sistema real– Podem perder erros do sistema
• Tipicamente, mais eficientes
Opção 3: Modelos em gramática
• Strings de uma linguagem descrita com uma EBNF correspondem a teste
Exemplo
• MODELO := OP+;
• OP := DEP | TRA• DEP := `deposito(` AG CC VAL `)`• TRA := `transferencia(` AG CC VAL `)`• AG := `777` | `888` | `999`• CC := `1023` | `54` | `85`• VAL := `124.2` | `300` | `9.99`
Teste baseado em gramática
• Símbolos não terminais podem detalhar geração de dados
• Geno (Lammel e Shulte, 2005) adiciona restrições para restringir o espaço de termos da linguagem (teste)
Limitações
• Gramática é livre de contexto– Dificuldade para associar conta 1 com
agencia 1• Não define oracles
– Mais usada para encontrar crashes