Download - Uma Estratégia para Teste de Conformidade Automático em ... · projeto e teste. Em teste de software, muitas abordagens estão usando modelos formais para automatizar a geração

Transcript

Resumo— Teste de software é uma atividade cara e custosa; ela

é também propensa a erros devido a sua natureza humana. Mas, teste continua sendo o principal esforço usado na indústria de software para atingir um nível aceitável de qualidade para seus produtos. Uma alternativa ao teste de software é o uso de técnicas verificação formal, embora, estas técnicas ainda não são encontradas frequentemente na indústria. Este artigo propõe uma estratégia automática de verificação para incrementar a fase de teste baseado em verificação de refinamentos, na qual os formalismos ficam escondidos dos desenvolvedores. A estratégia consiste em uma linguagem natural controlada (um subconjunto da língua Inglesa) para descrever requisitos (que são automaticamente traduzidos na linguagem de especificação formal CSP) e extrair um modelo diretamente de um aparelho celular usando uma ferramenta como suporte; estes artefatos são normalizados em um mesmo nível de abstração e comparados usando o verificador de refinamentos FDR. Esta estratégia esta sendo experimentada na Motorola.

Palavras chave— CSP (communicating sequential process), verificação de refinamento (refinement checking), teste de conformidade (conformance testing).

I. INTRODUÇÃO Embora, métodos formais serem considerados difíceis de

usar na prática, modelos formais são uma tendência atual na indústria. Estes modelos são usados, por exemplo, na análise, projeto e teste. Em teste de software, muitas abordagens estão usando modelos formais para automatizar a geração de casos de teste [1], bem como melhorar a qualidade do processo de teste como um todo [2].

Este trabalho é o resultado da colaboração entre Motorola e o Centro de Informática da Universidade Federal de Pernambuco. Nós estamos usando a linguagem formal CSP (Seção II-A); uma linguagem primeiramente desenvolvida para modelar sistemas concorrentes e distribuídos. Também, usamos verificação automática baseada em verificação de refinamentos [3] (Seção II-B), ocultando o uso de métodos formais. Isto é, desenvolvedores continuam usando seus

Os autores agradecem o suporte do Conselho Nacional de

Desenvolvimento Científico e Tecnológico – CNPq – processo número 550466/2005-3.

C. Bertolini é aluno de doutorado do Centro de Informática da Universidade Feneral de Pernambuco, Recife/PE, Brasil, Caixa Postal 7851, CEP 50732-970 ([email protected]).

A. Mota é professor do Centro de Informática da Universidade Federal de Pernambuco, Recife/PE, Brasil, Caixa Postal 7851, CEP 50732-970 ([email protected]).

artefatos tradicionais e obtendo resultados sem precisar conhecer como métodos formais funcionam. A principal motivação dessa pesquisa é melhorar a produtividade reduzindo esforço através da automação.

Uma visão geral de nossa estratégia (Seção III) é apresentada na Fig. 1. Nós consideramos duas entradas: um documento de requisitos escrito em uma Linguagem Natural Controlada---CNL1 (um subconjunto da língua Inglesa), no qual reusamos o trabalho reportado em [4] para gerar especificações CSP a partir do documento de requisitos (Seção III-A), e um telefone celular, onde desenvolvemos uma ferramenta chamada BxT (Seção III-B) para extrair automaticamente uma especificação CSP a partir do telefone usando uma API proprietária da Motorola chamada PTF [5] . Após a extração dos dois modelos, é feito um ajuste do nível de abstração (Seção III-C). Devido a implementação possuir mais detalhes que o modelo de requisitos, e aplicamos um algoritmo proposto baseado em verificação de refinamentos, executando uma espécie de teste de conformidade, para analisar e reportar problemas encontrados (Seção III-D). Note que, a estratégia como um todo esconde o formalismo dos desenvolvedores.

Fig. 1. Visão geral da estratégia.

Finalmente, para mostrar os benefícios da nossa estratégia,

é apresentado um estudo de caso (Seção IV) baseado em uma aplicação real de celular. Também, são considerados alguns

1 A razão para usar CNL ao invés de uma linguagem gráfica, como UML, está relacionado com os artefatos usados na Motorola; Estes são descritos em Inglês.

C. Bertolini and A. Mota

Uma Estratégia para Teste de Conformidade Automático em Sistemas Embarcados

290 IEEE LATIN AMERICA TRANSACTIONS, VOL. 6, NO. 3, JULY 2008

trabalhos relacionados (Seção V), conclusões e trabalhos futuros (Seção VI).

Desta forma, as principais contribuições do artigo são: • A proposta de uma estratégia automática para

melhorar a qualidade do teste de sistema no contexto de aplicações para celular;

• Desenvolvimento da ferramenta (BxT) para extrair o comportamento de um aparelho celular como uma especificação formal CSP;

• Formalização de como ajustar diferentes níveis de abstração de especificações de requisitos e implementação para permitir uma correta verificação de refinamentos;

• Um algoritmo baseado em verificação de refinamentos para capturar todas as falhas encontradas entre requisitos e implementação.

II. ESTADO DA ARTE Esta seção apresenta conceitos básicos sobre verificação de

modelos e a linguagem formal CSP.

A. CSP: Visão Geral A idéia básica de CSP é representar o sistema com um

conjunto de processos interagindo entre si através de ações (eventos). O alfabeto de um processo P, representado como αP, é o conjunto de eventos disparados pelo processo. Para usar CSP na prática, é necessário usar uma versão machine-readable chamada CSPM; todos os elementos de CSP usados no artigo seguem a versão CSPM. Uma vez que se tem a especificação CSPM, pode-se aplicar o verificador de refinamentos FDR [6] (Failures-Divergences Refinement). Foi usada a seguinte especificação CSP a partir do estudo de caso utilizado para introduzir CSP:

Esta especificação CSP captura o comportamento de uma implementação real de um celular. Ela inicia com a descrição do processo principal SysImpl. Este processo representa uma composição seqüencial (;) entre o processo P1_Hiding e ele

mesmo. Assim, SysImpl comporta-se como P1_Hiding até uma terminação de sucesso ocorrer (será explicado abaixo). Nesse caso, ele torna SysImpl novamente.

O operador hiding (\) é usado para abstrair detalhes de um processo. Por exemplo, o processo P1_Hiding esconde os eventos goto.DTGOT_SCREEN.(IDLE_SCREEN,{}), goto.DTGOT_MENU.(MAIN_MENU,{}) do processo P1.

Um prefixo (a -> P) combina um evento e um processo para produzir um novo processo; um comportamento linear. Em steps -> goto.DTGOT_SCREEN.(IDLE_SCREEN,{}) ->..., depois ocorre steps, o evento goto é o primeiro evento do comportamento resultante. Quando se tem uma escolha externa ([]), ela determina uma escolha entre dois processos. O ambiente decide qual processo será escolhido. Por exemplo, em (P2 [] PA1) o ambiente pode escolher o processo P2 ou PA1. O processo Skip significa uma terminação de sucesso e o processo STOP significa um comportamento problemático; um deadlock. Isto também serve para outros objetivos (veja seção III-D). A semântica de CSP é definida em três modelos semânticos: traces, failures e failures-divergences [3]. Este trabalho usa o modelo de traces para descrever o comportamento. É o modelo mais simples e captura o que um processo pode fazer na forma de um conjunto de seqüências de eventos. Assim, para qualquer processo CSP P, a função T(P) retorna os traces. Uma escolha não determinística entre dois processos CSP é representada como P |~| Q. Em um modelo de trace, não se pode capturar não determinismo porque T(P [] Q) = T(P |~| Q) = T(P) U T(Q). Isto é útil para este trabalho porque casos de teste são muito similares a traces. Sendo assim, o modelo de traces é mais adequado.

Tendo os traces de um processo, podem-se verificar seus relacionamentos através de refinamentos. Sejam P e Q dois processos CSP, então P [T= Q =def T(Q) ⊆ T (P), ou seja, Q é melhor que P se Q tem menos ou o mesmo comportamento de P. Além disso, processos CSP podem também ser representados semanticamente (usando seus operadores semânticos) em termos de LTS (Labelled Transition Systems); um tipo de grafo rotulado (veja Fig. 5(a) para um exemplo de LTS).

B. Modelos e Verificação de Refinamentos Model Checking é uma técnica automática para verificar se

um dado modelo satisfaz uma propriedade desejada. Usualmente, model checking é usado para projetos de hardware, mas é usado também para software [7]. Propriedades são escritas em formulas em lógica temporal (por exemplo, CTL ou LTL [8] ) e modelos em alguma linguagem de especificação (por exemplo, CSP e PROMELA [9]). Então, dado uma formula em lógica temporal f e um modelo M, model checking, o qual é representado como M f, significa verificar se M satisfaz f. Na pratica, isto envolve

BERTOLINI AND MOTA : IDEAS08: AN STRATEGY FOR AUTOMATIC CONFORMANCE 291

representar M e f como LTS, e executando buscas nestas estruturas. A essência é que model checking é exaustivo (utiliza-se a estrutura inteira se é necessário [10] e obviamente necessita que essas estruturas sejam finita.)

Um tipo especial de model checking, chamado verificação de refinamentos, usa dois modelos escritos na mesma linguagem de especificação ao invés de lógica temporal. Seu objetivo é verificar se um modelo Q é melhor que outro modelo P no sentido que todas as propriedades de P são preservadas por Q. Formalmente, dado modelos P e Q, diz-se que Q refina P se P [= Q. Pode-se pensar que P é um modelo que já é conhecido por ter certa propriedade dada pela formula f. Assim, Q f ⇔ P [= Q.

Em nossa estratégia, temos os requisitos de uma aplicação bem como sua implementação. Pode-se pensar em usar model checking tradicional através de PROMELA ao invés de CSP e SPIN [9] ao invés de FDR [6], mas verificação de refinamentos é a escolha mais natural para verificar se uma implementação esta em conformidade com sua especificação.

Atualmente, muitas abordagens usam model checking como apoio ao teste principalmente para a geração de casos de teste. Embora verificação de refinamentos também possa ser aplicado nesse sentido [11], nós usamos nesse trabalho em sua essência. Ou seja, ao invés de extrair partes da especificação (testes) para executar em uma implementação, nós simplesmente checamos se o modelo de implementação está em conformidade com o modelo de especificação.

III. MODELO PROPOSTO A estratégia proposta (veja Fig. 1) consiste em verificar a

conformidade entre requisitos SysSpec, e sua implementação SysImpl. Como é usual na literatura [8], assume-se que SysSpec está correto, mas SysImpl pode apresentar problemas (isto é, pode não estar em conformidade com SysSpec). Para aplicar verificação de refinamentos é preciso de dois modelos formais capturandos a partir de requisitos e implementação. Linguagens formais não são padrão na indústria, sendo assim, esconde-se os formalismos dos desenvolvedores a fim de obter uma melhor aceitação da nossa estratégia.

A. Extraindo o Modelo Formal dos Requisitos Para tratar com requisitos formalmente, mas de uma forma

que o formalismo fique transparente, nós usamos a CNL [4], que é um subconjunto da língua Inglesa que não introduz ambigüidades e de mais fácil processamento. Em nossa estratégia na Motorola, a CNL foi desenvolvida para gerar casos de teste automaticamente [11]. Por exemplo, uma simples sentença CNL é “Select phonebook application", onde um documento de requisitos é visto como um conjunto de sentenças CNL. Uma visão simplificada da sintaxe usada da CNL é vista abaixo:

Por exemplo, Fig. 2 descreve parte da funcionalidade usada em nosso estudo de caso (Seção IV). Como observado na Fig. 2, há dois fluxos: fluxo principal e o fluxo de exceção; para cada fluxo existe a descrição de passos, o estado do sistema complementa os passos e as respostas do sistema. O fluxo de exceção é relacionado com algum passo do fluxo principal (From Step:). O Step ID é usado como identificador único de cada passo em um caso de uso. Por exemplo, UC_01_1M é o primeiro passo do fluxo principal do caso de uso. A partir do UC_01_1M, pode-se seguir os demais fluxos do passo principal. Note que no fluxo alternativo, o From Step: indica o passo UC_01_1M. Assim, o fluxo no passo UC_01_1A é uma alternativa para UC_01_1M.

Fig. 2. Caso de Uso Escrito em CNL.

A partir de um caso de uso escrito em CNL, pode-se usar o

framework da CNL para gerar o modelo CSP. Na Fig. 3(a), é apresentado o framework da CNL que consiste em:

• Sentenças CNL: requisitos são escritos em um documento Microsoft Word baseados em um template específico (Fig. 2);

• Processamento CNL: traduz cada sentença em um evento CSP (Fig. 3(b)) e o caso de uso como um todo em uma especificação CSP.

• Alfabeto CSP: é formado por todos os eventos CSP extraídos do caso de uso;

• Processo CSP: é à saída do processamento CSP e representa um caso de uso descrito em uma especificação CSP.

292 IEEE LATIN AMERICA TRANSACTIONS, VOL. 6, NO. 3, JULY 2008

Fig. 3. Framework CNL.

O framework CNL também checa por algumas inconsistências. Quando um erro gramatical é reportado, o usuário ajusta a sentença CNL correspondente em um caso de uso. Outra situação pode ocorrer quando uma palavra não é reconhecida na base de dados da CNL. Assim o usuário pode mudar a palavra por um sinônimo já existente na base ou adicionar uma nova palavra.

B. Extraindo o Modelo Formal da Implementação Para obter uma especificação CSP de uma aplicação de

telefone, foi implementado uma ferramenta chamada BxT (Behavior Extractor Tool). Ela obtém todos os caminhos relevantes de uma aplicação analisando o código fonte de um framework chamado PTF (Phone Test Framework) [5]. Este framework nos dá acesso a todas as funções do telefone. Ademais, para produzir um modelo com um objetivo específico (por exemplo, uma aplicação específica), BxT foi projetada para possibilitar que o usuário guie a geração do modelo. É suficiente estar com um objetivo (geralmente aplicação ou sub-aplicação) e o modelo é gerado seguindo o objetivo definido. É importante observar que BxT extrai um comportamento alto nível através do PTF, isto é um comportamento funcional relacionado principalmente com aspectos de navegação. Outro importante aspecto da geração é o uso do modulo de processamento da CNL para obter um alfabeto compatível entre modelos de requisitos e implementação. Isto é atingido através da escrita de chamadas de métodos PTF usando sentenças CNL. Por exemplo, a navegação correspondente a Fig. 4(b) é expressa em CNL como "Select Message". Estas são as principais razões que levam nosso modelo de implementação ficar próximo ao modelo de requisitos como discutido na Seção III-C. Dada uma aplicação de telefone, BxT assume que o estado inicial é idle (tela inicial do telefone) e usando a estrutura da chamada de métodos PTF são extraídos todos os caminhos de uma aplicação específica. BxT gera uma especificação CSP como saída mas também pode gerar um log contendo chamadas de métodos PTF.

Fig. 4(a) mostra o framework da BxT: para cada tela, são capturados todos os componentes usando o código PTF correspondente. Os componentes são todas as telas, botões, labels, figuras, painéis, etc. Para cada componente, um conjunto de propriedades podem ser capturadas como texto, estado, cor, posição, etc. BxT captura os componentes para a navegação.

Fig. 4. Framework BxT e telas de uma aplicação.

Fig. 5(a) corresponde ao caso de uso da Fig. 2 com um

LTS. A Fig. 5(b) corresponde ao modelo CSP da implementação da Seção II-A. Observndo esses modelos, pode-se notar que a Fig. 5(b) quase contem a Fig. 5(a). A diferença entre estes dois modelos vem de duas fontes: eventos de navegação de baixo nível (por exemplo, “Go to main menu”) e transições extras não descritas nos requisitos.

Fig. 5. Implementação (a) e especificação (b) em LTS.

C. Lidando com diferentes níveis de abstração Quando trabalhamos com dois modelos, requisitos e

implementação, a diferença comportamental entre eles pode ser considerável devido a diferença semântica. Entretanto, uma vez que a BxT captura o comportamento de navegação (ou sistema) baseado no framework PTF, somente são adicionados detalhes necessários para atingir um certo objetivo. Assim, enquanto requisitos capturam aspectos (características) mais orientados a objetivos, o comportamento da implementação complementa tal comportamento com detalhes de navegação (outras transições).

Assim, a partir de observações previas sobre as Fig. 5(a) e Fig. 5(b), para fazer a correta comparação entre requisitos e implementação, precisa-se esconder todos os eventos de SysImpl que não ocorram em SysSpec (os detalhes adicionais de navegação) Isto corresponde com a seguinte relação de refinamento:

SysSpec [T= SysImpl \ Impl_Details where Impl_Details = αSysImpl \ αSysSpec

BERTOLINI AND MOTA : IDEAS08: AN STRATEGY FOR AUTOMATIC CONFORMANCE 293

D. Análise de Resultados Com a prévia relação de refinamento disponível, precisa-se

executar a verificação usando o verificador de modelos FDR para obter duas possíveis situações: tudo está correto e então a implementação satisfaz seus requisitos, ou existe um problema de conformidade entre os modelos e FDR gera um contra exemplo. Este contra exemplo

Estes contra-exemplos são similares a um caso de testes falho. Assim, precisa-se coletar todos os possíveis contra-exemplos para ajustar a implementação apropriadamente, seguindo um processo de testes tradicional. Como o verificador de modelos prove somente um contra-exemplo para cada verificação (o menor contra-exemplo possível) para descobrir todos eles, propõem-se um procedimento iterativo para gradualmente achar o próximo contra-exemplo.

A idéia chave para coletar todos os contra-exemplos da relação de refinamento prévia é baseada nas propriedades de dois elementos básicos de CSP: o trace de uma escolha externa e a definição de refinamento de traces. Suponha que temos a seguinte relação de refinamento SysSpec [T= SysImpl tal que um refinamento produz um trace s como um contra-exemplo.

Observando a Seção II-A que SysSpec [T= SysImpl significa T(SysImpl) ⊆ T(SysSpec) e que T(P [] Q) = T(P) ∪ T(Q). Assim, para achar o próximo contra-exemplo, atualiza-se a especificação SysSpec com a escolha de executar o contra-exemplo s como um processo CSP.

Para construir um processo dado um trace introduz-se a função MakeCSPProcess , a qual paga como entrada um trace <e1,...,en> e produz como saída o processo e1 -> ...-> en -> STOP como segue:

MakeProcess(<e1, ... , en>) = e1 -> ... -> en -> STOP A função MakeProcess produz um processo terminado em

STOP porque T(STOP)={<>}, o qual não interfere na relação de refinamento. Entretanto, o refinamento SysSpec [T= SysImpl torna-se SysSpec [] F= [T= SysImpl, depois da atualização de SysSpec, onde F=MakeProcess(s), para um contra-exemplo s.

Observando as discussões previas, propõem-se o Algoritmo 1 que gera o conjunto Res representando todos os contra-exemplos obtidos. Isto é, se a relação de refinamento entre SysSpec e SysImpl não é satisfeita (SysSpec ⌐[T= SysImpl), então um contra-exemplo s é gerado e incluído no conjunto Res. O contra-exemplo s torna-se o processo F usando a função MakeProcess, e então é combinado com o processo SysSpec usando uma escolha externa. O refinamento (SysSpec [T= SysImpl) é repetido até que seja valido (neste caso s = ⟨⟩).

Uma observação sobre o Algoritmo 1 é que ele pode rodar indefinidamente. Para tratar esse problema o parâmetro N é usado para coletar somente N (#Res<N) contra-exemplos.

Outra importante contribuição é usar nossa análise de navegação orientada para investigar partes criticas das aplicações por engenheiros de testes experientes. Isto é um passo além na análise porque isso leva um tempo menor para ser verificado, bem como analisar as partes que historicamente são mais problemáticas. Em particular, os modelos apresentados nesse artigo seguem objetivos relacionados a função de messaging (envio, recebimento e gerenciamento de mensagens).

IV. ESTUDO DE CASO: APLICAÇÃO MÓVEL

Nesta seção, foi aplicada a estratégia proposta em um estudo de caso real da Motorola.

Este estudo de caso apesar de ser simples, corresponde a um cenário real no desenvolvimento de uma aplicação móvel. Sua simplicidade vem do fato de termos usado nossa navegação orientada para analisar somente partes da aplicação relacionada a requisitos de messaging.

O primeiro esforço na direção de analisar a conformidade entre requisitos e implementação da nossa aplicação móvel é obter uma especificação formal de ambos: requisitos e implementação. Assim, aplicando o framework de processamento CNL nos casos de uso descritos na Fig. 2 obtém-se o modelo CSP correspondente aos requisitos.

Ademais, usando o framework BxT (Fig. 4(a)) em um

telefone celular real obtém-se o modelo CSP relativo a implementação como apresentado na Seção III-A.

294 IEEE LATIN AMERICA TRANSACTIONS, VOL. 6, NO. 3, JULY 2008

Para a geração do modelo de requisitos nós assumimos que o modelo é escrito corretamente, então se leva alguns segundos para a extração do modelo CSP. Por outro lado, o modelo de implementação leva aproximadamente 3 minutos, pata que a ferramenta BxT extraia e gere o modelo CSP correspondente.

Com esses dois modelos formais pode-se fazer uma série de análises clássicas, como deadlock, livelock e não determinismo. Essas propriedades são interessantes de serem analisadas porque, em geral, as especificações formais precisam estar corretas e por isso livres desses problemas. Caso um desses problemas seja encontrado, o modelo pode ser imediatamente ajustado (se necessário2).

Figura 6(a) mostra o resultado do uso do verificador de modelos FDR: tanto os requisitos quanto a implementação estão livres de deadlock e livelock bem como são determinísticos.

Após análise prévia, começa-se o procedimento de conformidade executando o Algoritmo 1 até que a relação de refinamento entre requisitos e implementação seja satisfeita.

Fig. 6. Propriedades clássicas e refinamento verificado.

2 Algumas vezes uma situação de deadlock (um dispositivo está quebrado) pode ser intencional, então os modelos podem ser mantidos com deadlock.

Quando um erro é encontrado, isto significa que a implementação possui um bug. FDR fornece o contra-exemplo como resultado, conforme apresentado na Fig. 7. Este trace mostra uma seqüência de eventos que é possível de ser executada pelo modelo de implementação, mas não pelo modelo de requisitos. Portanto, isto representa um erro na implementação.

Fig. 7. Contra-exemplo.

Com o contra-exemplo em mãos e seguindo o algoritmo

proposto, nós armazenamos este contra-exemplo e usamos para obter um novo modelo CSP dos requisitos (apresentado abaixo). Uma nova verificação de refinamento usa esse novo modelo para aplicação do Algoritmo 1. Como a última verificação de refinamento o algoritmo não produziu nenhum contra-exemplo, o algoritmo termina com sucesso.

Pelo fato da BxT ser baseada no PTF, o contra-exemplo da

Figura poderia ser facilmente reescrito como um caso de teste automático em PTF.

Como apresentado na Fig. 6(b), o nível de abstração entre requisitos e implementação em nosso contexto (visão caixa preta de uma aplicação de celular) é muito próxima. Assim, temos uma relação de equivalência entre requisitos e implementação quando uma implementação está em conformidade com os requisitos. Isto é, ambas as relações de refinamento SysSpec [T= SysImpl e SysImpl [T= SysSpec são satisfeitas (SysSpec ≅T SysImpl).

No sentido de dar idéia no esforço gasto para executar a estratégia proposta, foi usado um PC com 1 GB e 1,7MHZ. A Tab. 1 apresenta os resultados obtidos quanto comparados com outras duas estratégia: processo manual que corresponde a escrita e execução dos casos de teste manualmente e o processo TaRGeT que corresponde a uma ferramenta onde requisitos são descritos em CNL e casos de teste são gerados e

BERTOLINI AND MOTA : IDEAS08: AN STRATEGY FOR AUTOMATIC CONFORMANCE 295

executados manualmente. Tab. 1. Comparativo de tempo da estratégia.

Processo manual

Processo TarGeT

Estratégia proposta

Escrita de testes 9,2h 1h 1h Execução de testes 15min 20min - BxT e FDR - - 8min

Observa-se que o maior tempo levado por nossa estratégia

corresponde na escrita dos testes que no nosso caso representa a escrita de casos de uso em CNL. Observa-se também que o processo TaRGeT obteve um tempo similar, no entanto em aplicações maiores naturalmente terão um número maior de casos de teste a serem executados, com isso levando um tempo muito maior do que a verificação de refinamento que estamos propondo.

V. TRABALHOS RELACIONADOS

A maioria de trabalhos relacionados a teste e model checking são associados à model checking clássico [12,13]. Usualmente, propriedades são descritas em lógica temporal (como LTL) e o modelo da implementação é descrito em algum método formal (como autômatos, máquinas de estado, etc.), então cada propriedade é verificado no modelo. Com relação a refinamento de modelos, ambas as propriedades são representadas na mesma linguagem, no nosso caso CSP.

Teste baseados em interfaces gráficas (GUI---Graphical User Interfaces) geralmente envolve modelos. Existem abordagens que geram casos de teste automaticamente, ferramentas para seleção de casos de teste e ferramentas de ripping para teste de GUI [14]. Assim, nossa estratégia é similar ao teste de GUI, mas difere no sentido que extraímos nossos modelos usando um framework de testes PTF [5]. Assim, se for necessário, pode-se extrair muito mais informação. Entretanto estamos limitados as interações que o framework fornece.

Doron, Vardi, e Yannakakis [15] propõem uma estratégia combinando model checking e testes: black box checking. A estratégia consiste em verificar se uma implementação satisfaz dada propriedade. É assumido que a estrutura da implementação é conhecida e as informações estão incompletas para executar model checking diretamente. Assim, o modelo de implementação é ajustado usando uma estratégia de aprendizado baseada no algoritmo de Angluin. A estratégia black box checking é caracterizada como um problema e vários algoritmos são propostos para resolve-lo. Uma variação dessa estratégia é chamada Adaptive Model Checking [12]. Nessa estratégia considera-se um modelo incorreto, mas não obsoleto, assim, aprende-se com esse modelo adaptando black box testing e uma máquina de aprendizagem até se ter um modelo correto. Nesse contexto, nossa estratégia assume que os requisitos são confiáveis tal que qualquer problema deve estar relacionado com o modelo de implementação. Assim, nós não precisamos ajustar o modelo de requisitos com algoritmos de aprendizagem.

Considerando os modelos de requisito e implementação, a

estratégia de Güldali [13] usa ambos os modelos para executar model checking direcionado a cobertura. Neste caso, model checking executa testes automaticamente, e também, a estratégia gera casos de teste através de model checking [13]. Em ambos os casos, a motivação para incorporar model checking é para a geração de casos de teste. Diferentemente disso, nós estamos interessados em quando model checking pode ser utilizado substituindo teste.

Outras estratégias combinando model checking e teste de software têm sido propostas com diferentes objetivos e aplicabilidade. Godskesen e Skou propõem algoritmos para a geração de testes para sistemas embarcados combinando o modelo de falhas de um sistema [16]. Vlad, Herv e Thierry apresentam a combinação de técnicas de verificação e teste de conformidade com algoritmos de geração de casos de teste [17]. Ambos os trabalhos são relacionados a geração de casos de teste; eles sugerem o uso de model checking para a geração automática de casos de teste.

VI. CONCLUSÕES

Usualmente, teste cobre apenas um conjunto de situações críticas devido às restrições de tempo e custo. Entretanto, às vezes a experiência dos engenheiros de teste pode levar a descoberta de novos cenários resultando, muitas vezes, em cenários problemáticos.

A estratégia apresentada nesse artigo propõe uma forma alternativa ao teste de software para melhorar a qualidade. Faz-se necessário que o time de teste escreva os requisitos em CNL e conecte o celular no computador; O framework CNL e a ferramenta BxT fazem o restante. Depois de obter os dois modelos, o Algoritmo 1 é executado para obter o conjunto de casos de teste (contra-exemplos) que falharam. Apesar da estratégia proposta focar em aplicações de celulares, qualquer aplicação apresentada abstratamente (de um ponto de vista navegacional) pode-se beneficiar da estratégia proposta.

Pelo fato da BxT ser baseada em PTF, ela representa uma extensão PTF para a geração de modelos CSP para uma aplicação de celular específica. Assim, pode-se facilmente reescrever um contra-exemplo da Fig. 7 como um caso de teste automático. Um conjunto de casos de teste gerados baseados nos contra-exemplos pode ser aplicado como um bom conjunto de teste de regressão.

Apesar do fato da literatura relatar alguns trabalhos sobre model checking e testes [12,13], nós argumentamos que verificação de refinamentos é mais apropriada ao nosso contexto porque simplesmente faz uso da teoria de refinamento para comparar requisitos com a implementação correspondente. A geração de casos de teste é uma conseqüência natural da teoria de refinamentos, nós não precisamos focar na geração de casos de teste no sentido que nosso objetivo é verificar se uma dada implementação está em conformidade com seus requisitos. Usamos o modelo de trace para executar a analise porque ele está diretamente relacionado ao teste. Usando o modelo de traces podemos notar certa fragilidade porque o processo STOP refina qualquer processo P (para qualquer processo P, T(STOP) = {⟨⟩} ⊆ T(P)). Portanto, se um modelo de implementação tem

296 IEEE LATIN AMERICA TRANSACTIONS, VOL. 6, NO. 3, JULY 2008

menos eventos do que o modelo de requisitos então nós não conseguimos detectar isso. Para trabalhar com esse problema, precisamos estender para o uso de outros modelos semânticos como o modelo de falhas.

A versão corrente da BxT já traz bons resultados, mas possui algumas limitações: comportamentos que necessitem de entradas especificas de dados (por exemplo, senhas), informações relacionadas a estados (por exemplo, e-mail vazio) e requisitos não funcionais como performance não são capturados. Entretanto, como trabalhos futuros iremos melhorar a BxT para tratar dessas limitações.

REFERÊNCIAS [1] Rajan, A.: Automated Requirements-Based Test Case Generation.

SIGSOFT Softw. Eng. Notes 31(6) (2006) 1-2. [2] Drabick, R.D.: Best Practices for the Formal Software Testing Process:

A Menu of Testing Tasks. Dorset House Publishing Company (2003) [3] Roscoe, A.W.: The Theory and Practice of Concurrency. Prentice Hall

PTR, Upper Saddle River, NJ, USA (1997). [4] Cabral, G., Sampaio, A.: Formal Specification Generation from

Requirement Documents. In: Brazilian Symposium on Formal Methods, Natal, Brazil, ENCS (2006).

[5] Esipchuk, I., Validov, D.: PTF-based Test Automation for JAVA Applications on Mobile Phones. In: Proceedings of the IEEE 10th International Symposium on Consumer Electronics (ISCE). (2006) 1-3.

[6] Systems, F.: (FDR2 Model-Checker.) http://www.fsel.com/. [7] Group, S.: (BANDERA Model-Checker.)

http://bandera.projects.cis.ksu.edu/. [8] Clarke, E.M., Grumberg, O., Peled, D.: Model Checking. The MIT

Press (2000). [9] Barland, I.: (Promela and SPIN Reference.) http://www.spinroot.com/. [10] Andersen, H.R.: Partial Model Checking. In: LICS '95: Proceedings of

the 10th Annual IEEE Symposium on Logic in Computer Science, Washington, DC, USA, IEEE Computer Society (1995) 398.

[11] Nogueira, S.: Automatic CSP Test Case Generation Guided by Purposes. (In Portuguese). Master's thesis, Federal University of Pernambuco, Brazil (2006).

[12] Groce, A., Peled, D., Yannakakis, M.: Adaptive Model Checking. In: Tools and Algorithms for the Construction and Analysis of Systems: 8th International Con- ference, TACAS 2002, Held as Part of the Joint European Conference on Theory and Practice of Software, ETAPS 2002, Grenoble, France, LNCS (2002).

[13] GÄuldali, B.: Model Testing Combining Model Checking and Coverage Testing. Master's thesis, University of Paderborn, Germany (2005).

[14] Xie, Q., Memon, A.M.: Designing and Comparing Automated Test Oracles for GUI-Based Software Applications. ACM Transactions on Software Engineering and Methodology 16(1) (2007).

[15] Peled, D., Vardi, M.Y., Yannakakis, M.: Black Box Checking. J. Autom. Lang. Comb. 7(2) (2001) 225-246.

[16] C. Godskesen, B.N., Skou, A.: Connectivity Testing through Model-Checking. In: International Conference on Formal Techniques for Networked and Distributed Systems (FORTE), Madrid, Spain (2004).

[17] Vlad, R., Herv, M., Thierry, J.: Automatic Verification and Conformance Testing for Validating Safety Properties of Reactive Systems. In Fitzgerald, J., Tarlecki, A., Hayes, I., eds.: Formal Methods 2005 (FM05). LNCS, Springer (2005).

Cristiano Bertolini é mestre em Ciência da Computação pela Pontifícia Universidade Católica do Rio Grande do Sul (2004). Atualmente é doutorando em Ciência da Computação pela Universidade Federal de Pernambuco. Possui experiência na área de desenvolvimento de sistemas com foco em confiabilidade. Seus interesses de pesquisa compreendem modelos analíticos para avaliação de desempenho, métodos formais, teste de software e software model checking.

Alexandre Mota é professor do Centro de Informática da Universidade Federal de Pernambuco, onde também é atualmente Coordenador da Graduação em Ciência da Computação. Seus interesses de pesquisa envolvem técnicas, métodos e ferramentas para o desenvolvimento de aplicações confiáveis. As áreas onde atua são: modelagem e análise sistemas críticos (incluindo aeronáuticos), verificação de sistemas (incluindo testes) e métodos formais (particularmente Z, CSP, Perfect e Promela). É atualmente membro da Sociedade Brasileira de Computação, através da

qual obteve o 1º lugar no concurso de teses de doutorado em 2001.

BERTOLINI AND MOTA : IDEAS08: AN STRATEGY FOR AUTOMATIC CONFORMANCE 297