Академический Документы
Профессиональный Документы
Культура Документы
Sumrio
1 Introduo 2 Breve introduo linguagem Haskell
2.1 2.2 2.3 2.4 O paradigma funcional . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . A linguagem Haskell . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6 7
7 8 10 12
13
13 13 15 16
18
18 21 22 23 25 27 32
Funcionalidades avanadas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
35
35 36 36 36 36 37 38
Framework
HUnit
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Aplicao a testar
40
40 40
41 43 44 45 46 49 53
58
58 60 60 61 63
Derivao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8 Concluso 9 Referncias
65 66
Lista de Figuras
3.1 3.2 4.1 4.2 4.3 5.1 Gramtica da aplicao representada em EBNF . . . . . . . . . . . . . . . . . . . . . . . Arquitectura da aplicao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 15 23 24 26 35
Lista de Tabelas
3.1 4.1 4.2 4.3 4.4 4.5 4.6 4.7 6.1 6.2 6.3 6.4 6.5 6.6 6.7 6.8 6.9 Exemplos de expresses matemticas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Contagem de casos de teste da suite de testes . . . . . . . . . . . . . . . . . . . . . . . . Contagem de casos de teste da variante da suite de testes . . . . . . . . . . . . . . . . . 14 24 24 26 32 32 33 34 41 41 42 42 43 43 44 44 45 46 47 47 48 48
Caminhos na hierarquia de testes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Operadores de construo de asseres . . . . . . . . . . . . . . . . . . . . . . . . . . . . Exemplos de construes de asseres com operadores . . . . . . . . . . . . . . . . . . .
Vericaes efectuadas para validao sintctica da expresso . . . . . . . . . . . . . . . Transformao de expresses para o formato externo . . . . . . . . . . . . . . . . . . . . Construo da representao em rvore de uma expresso Operaes algbricas bsicas tratadas pela aplicao . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.12 Testes de converso de validao sintctica . . . . . . . . . . . . . . . . . . . . . . . . . . 6.13 Testes de converso de formato interno para o formato externo . . . . . . . . . . . . . .
6.15 Testes genricos de converso de expresses no formato interno a representao em rvore 49 6.16 Testes de operaes algbricas bsicas . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50 50 51 51 52 52 53 53 54
6.17 Testes das propriedades dos operadores algbricos . . . . . . . . . . . . . . . . . . . . . . 6.18 Testes das propriedades dos operadores algbricos . . . . . . . . . . . . . . . . . . . . . . 6.19 Testes de simplicao de avaliao de funes 6.20 Testes de simplicao de avaliao de funes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.21 Testes de validao semntica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.22 Testes de somas simplicveis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.23 Testes de somas no simplicveis 6.24 Testes de diferenas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
54 55 55 55 55 56 57 58 60 61 61 61 62 63
6.26 Testes de produtos no simplicveis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.27 Testes de divises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.28 Testes de potncias simplicveis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.29 Testes de potncias no simplicveis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.30 Testes de derivao de expresses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.31 Testes de composio de regras de derivao . . . . . . . . . . . . . . . . . . . . . . . . . 7.1 7.2 7.3 7.4 7.5 7.6 7.7 Execuo de testes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Falhas da vericao de operaes bsicas e suas propriedades . . . . . . . . . . . . . . . Falhas da converso de avaliao de funes . . . . . . . . . . . . . . . . . . . . . . . . . Falhas na qualidade da simplicao de expresses . . . . . . . . . . . . . . . . . . . . .
Captulo 1
Introduo
Este relatrio apresenta o resultado nal do estudo e desenvolvimento de uma arquitectura de testes de programas escritos em linguagem Haskell, no mbito do projecto da disciplina de Teste e Qualidade de Software da edio de 2004/2005 do Mestrado em Engenharia Informtica da Faculdade de Engenharia da Universidade do Porto. A arquitectura implementada visa fornecer uma plataforma para testar programas em Haskell, utilizando como base a
framework
HUnit 1.0.
aplicao desenvolvida na mesma linguagem. O segundo captulo apresenta a linguagem Haskell enquadrado-a no paradigma da programao funcional e comparando-a com linguagens imperativas como o C. So enumerados os potenciais benefcios da linguagem e apresenta-se uma panormica geral das suas construes e estruturas de dados. O captulo conclui com uma breve discusso sobre os dois paradigmas de programao em causa: o imperativo e o funcional. O terceiro captulo apresenta a aplicao que servir de base aos testes, a Aplicao de Simplicao e Derivao de Expresses Matemticas, desenvolvida em Haskell. Descreve-se o objectivo da aplicao, a sua arquitectura e blocos funcionais. O quarto captulo efectua um estudo da
framework
testes desenvolvida. So abordados os conceitos de asseres, testes e casos de teste posicionado-os no contexto da
framework.
identicao de caminhos em hierarquias de testes, execuo de testes e outras mais avanadas. O quinto captulo descreve os componentes da arquitectura do ambiente de testes. Estes componentes incluem a
framework
apresentado um dialecto XML de descrio de testes unitrios em Haskell, denominado HtestML. O sexto captulo aborda todo o processo de concepo de casos de teste. So enunciadas as regras de especicao da aplicao em teste e organizados os casos de testes que as vericam. Esses casos de teste so classicados em trs grandes categorias: converso de formatos entre expresses, simplicao de expresses e clculo de derivadas. O stimo captulo descreve a execuo dos testes e analisa os resultados obtidos. So identicados os casos de teste que acusam falhas na aplicao e discutida a sua gravidade e impacto na aplicao. Encerra-se o relatrio com uma concluso que discute os objectivos atingidos com o trabalho.
Captulo 2
de uma clula pode ser exprimido em funo dos valores de outras clulas. O foco sempre naquilo que est a ser calculado e no na forma como deve ser calculado. No indicada a ordem pela qual as clulas devem ser calculadas, essa responsabilidade deixada prpria folha de clculo. Tambm no so indicadas quaisquer tcnicas de gesto de memria, esperando-se, pelo contrrio, que a folha de clculo parea ser innita. Tudo o que indica o valor de uma clula atravs de uma expresso
(cujas componentes podem ser avaliadas por qualquer ordem), em vez de uma sequncia de comandos que calculem o ser valor. Uma consequncia de no haver ordem pr-estabelecida que a noo de
atribuio no muito til. Se no se conhece o momento em que uma atribuio ocorre, tal no pode ser incorporado na expresso. este aspecto que fomenta o maior contraste com linguagens como o C em que a sequncia de atribuies tem que ser cuidadosamente planeada. O facto do foco passar
do conceito de baixo nvel como para o de alto nvel o qu a caracterstica mais marcante que distingue as linguagens funcionais das imperativas. Outra linguagem quase-funcional a SQL para interrogao e manuteno de bases de dados. Uma interrogao SQL uma expresso que involve projeces, seleces, junes e condies. A expresso indica quais as relaes que devem ser interrogadas e o que se pretende, no entanto, no fornece qualquer indicao de como tal deve ser obtido. As implementaes de SQL incluem algoritmos de optimizao de interrogaes que tm como principal objectivo determinar qual a melhor ordem para avaliar a expresso. A execuo desses algoritmos transparente para o programador.
lazy
e considerada pura no contexto das linguagens funcionais. O seu nome presta homenagem a Haskell Brooks Curry, cujo trabalho matemtico serve de base s linguagens funcionais, nomeadamente no que respeita a
lambda calculus.
Os
A principal motivao para o aparecimento de linguagens funcionais como o Haskell, o de tornar o processo de escrita e manuteno de grandes sistemas de software mais simples e econmicos.
criadores da linguagem argumentam como vantagens de utilizao o aumento da produtividade dos programadores, a produo de cdigo mais curto, mais legvel e de manuteno mais simples. Ar-
gumentam tambm a diminuio de erros e maior abilidade e a reduo do fosso semntico entre o programador devido ao maior poder expressivo. A linguagem Haskell tem um espectro de aplicao alargado servindo para uma grande variedade de aplicaes. Segundo os seus autores, particularmente adequada para programas com grande necessidade de modicao e manuteno. A maior parte do ciclo de vida de um produto de software
corresponde especicao, desenho e manuteno e no propriamente programao. As linguagens funcionais so vocacionadas para escrever especicaes que podem ser executadas e consequentemente testadas. Essas especicaes constituem o primeiro prottipo do programa nal. Os programas nestas linguagens so relativamente simples de manter porque o cdigo mais curto, mais claro e o controlo rigoroso de efeitos laterais elimina uma grande quantidade de interaces imprevistas. Um exemplo tpico que pretende ilustrar estes conceitos a implementao do algoritmo de ordenao de um vector pelo mtodo
qsort [] = [] qsort (x:xs) = qsort lt ++ [x] ++ qsort ge where lt = [y | y <- xs, y < x] ge = [y | y <- xs, y >= x]
qsort( a, lo, hi ) int a[], hi, lo; { int h, l, p, t; if (lo < hi) { l = lo; h = hi; p = a[hi]; do { while ((l < h) && (a[l] <= p)) l = l+1; while ((h > l) && (a[h] >= p)) h = h-1; if (l < h) { t = a[l]; a[l] = a[h]; a[h] = t; } } while (l < h); t = a[l]; a[l] = a[hi]; a[hi] = t; qsort( a, lo, l-1 ); qsort( a, l+1, hi ); } }
Este exemplo-limite frequentemente utilizado pelo entusiastas da linguagem Haskell para ilustrar o seu poder expressivo. Tendo este exemplo como base, so enumerados os seguintes benefcios da
Conciso
Programas escritos em linguagem funcionais tendem a ser mais concisos do que os seus equivalentes em linguagens imperativas. Mesmo atendendo ao facto de que a implementao do algoritmo
quicksort
2.
constitui um caso extremo, de uma forma geral a reduo em linhas de cdigo pode
Facilidade de compreenso
Segundo os seus autores, possvel compreender a implementao do
quicksort
sem qualquer
conhecimento prvio de Haskell. A primeira linha arma que o resultado de ordenar uma lista vazia uma lista vazia. A segunda linha arma que para ordenar uma lista cujo primeiro elemento
x e a parte restante xs, basta ordenar os elementos de xs que so inferiores a x, os elementos de xs que so iguais ou superiores a x e concatenar os resultados com x no meio. Como as sub-listas
resultantes so inferiores lista original o processo acaba por convergir para as sub-listas vazias. A implementao em C no de fcil compreenso. necessrio seguir o uxo de execuo e as variveis utilizadas, sendo tambm mais passvel de erros de programao.
3.
piori
a um tipo. Com um forte sistema de tipos no existe, por exemplo, a possibilidade de tratar um inteiro como um apontador ou seguir um apontador nulo. 4.
Avaliao lazy
Muitas linguagens funcionais s avaliam as partes do programa que so necessrias para o clculo que efectuado. Designa-se a este tipo de avaliao por
lazy.
listas, so avaliadas s at onde for necessrio podendo haver partes delas que nem so avaliadas. 5.
Abstraco poderosa
As funes de ordem elevada so um mecanismo de abstraco que oferecido pelas linguagens funcionais. Consiste em poder usar funes como argumentos, parmetros de sada, armazenamento em estruturas de dados e qualquer outra operao que possa ser efectuada com valores de qualquer tipo de dados. A principal vantagem que a utilizao de funes de ordem elevada
heap.
Em C
O programador
tambm responsvel por libertar a rea alocada, caso contrrio ca sujeito ocorrncia de apontadores vazios. As linguagens funcionais libertam o programador destas tarefas e semelhana do Java possuem mecanismos de memria de forma automtica.
garbage collector
::,
Int
Integer Float
True
ou
False
Tuplos Sequncia de elementos de tipos pr-existentes podendo ser diferentes uns dos outros. O nmero de elementos est xado na denio do tipo. Um exemplo o tipo que pode ser instanciado com o tuplo
Listas Sequncia ordenada de elementos de um tipo, sendo o nmero de elementos arbitrrio. Alguns exemplos so a lista vazia caracteres)
[],
e uma
string
(lista de
"abc".
let,
let y = x + 2 x = 5 in x / y
A expresso
let
10
if-then-else,
then
e
encontrada nas linguagens imperativas. A principal tm que avaliar para um valor e tm que ser do
else
add
Int
Int.
A mesma funo pode ser denida com um nico parmetro, um tuplo par, que agregue os dois valores a somar:
xs.
guardas
abs:
Existem mais algumas construes para alm das apresentadas possibilitando um bom poder expressivo na formulao de algoritmos. tambm bastante rica em termos de bibliotecas de funes e
frameworks, estando continuamente em desenvolvimento novas extenses da linguagem. A partir do website da linguagem, http://www.haskell.org/, possvel ter acesso a inmeros tutoriais introdutrios bem como documentao extremamente aprofundada da linguagem. So disponibilizadas muitas bibliotecas que podem ser livremente importadas. Algumas dessas bibliotecas extendem bastante a linguagem dotando-a da possibilidade de poder rivalizar com muitas linguagens imperativas.
11
quicksort
que o vector ordenado directamente, sem recorrer a outras estruturas de dados. Em resultado disso, o algoritmo executado muito rapidamente e exigindo muito pouca memria para alm da necessria para conter o vector. A implementao em Haskell por outro lado aloca muito mais memria e de execuo muito mais lenta que o a execuo em C. A implementao em C troca a complexidade por tempos de execuo reduzidos. Tal leva a concluir que em aplicaes em que o desempenho que se baseie em tempos de execuo seja um factor critico, as linguagens como C sero sempre uma melhor escolha do que o Haskell, precisamente porque lidam mais como a forma como as computaes so efectuadas. A distancia do Haskell ao
hardware
um nvel mais elevado, mas com menor nvel de controlo sobre a mquina. Verica-se que so poucos os programas que exigem grande desempenho medidos somente tendo por mtrica o tempo de execuo. Os entusiastas do Haskell defendem que se abandonou a escrita de programas em Assembler, deixando-a apenas para casos extremos de desempenho. Argumentam que os benefcios de se ter um modelo de programao mais prximo da inteno do programador compensa os custos que tal implica. Uma viso mais ousada posiciona as linguagens funcionais relativamente s imperativas da mesma forma que estas se posicionam relativamente ao Assembler. Provavelmente trata-se de uma assuno megalmana mas em termos estritos verica-se que em ambos os casos, os programas tm maior poder expressivo e menor controlo directos sobre a mquina. Da mesma forma verica-se que para a maioria dos programas, este compromisso aceitvel.
12
Captulo 3
simplicaes e derivaes de expresses que tenham sido examinadas e aprovadas pelo validador tanto do ponto vista sintctico como semntico. As seces seguintes apresentam a gramtica das expresses, a arquitectura da aplicao e os vericaes efectuadas nas validaes.
x.
De forma a tornar
mais rpida e eciente a introduo de expresses, os operadores matemticos so representados por caracteres especcos. Por exemplo, a multiplicao, identicada na notao matemtica pelo smbolo
13
matemtica normal. A aplicao suporta as seguintes funes reais de varivel real: polinmios, funes trigonomtricas e trigonomtricas inversas, logartmica e exponencial. O formato com que o utilizador introduz uma expresso designado por
formato externo.
Embora
na validao e processamento, ocorram transformaes da expresso em outros formatos, o resultado das expresses produzidas obedece tambm a este formato. Uma denio formal desse formato obtida atravs de uma gramtica que explicita os operadores e funes admissveis, bem como as sequncias permitidas entre eles. A gura 3.1 apresenta a gramtica da aplicao atravs da sua escrita em EBNF (
expressao ::= ( { expressao operador expressao | f uncao ( expressao )| inteiro | real |x} ) f uncao ::= sen|cos|tg |arcsen|arccos|arctg |log |exp operador ::= +| | |/| | digito ::= 0|1|2|3|4|5|6|7|8|9 inteiro ::= digito | inteiro digito real ::= inteiro . f raccao f raccao ::= digito | digito f raccao
Figura 3.1
As expresses podem ser constitudas por nmeros (inteiros ou racionais), variveis, operadores, funes e outras sub-expresses. A tabela 3.1 apresenta alguns exemplos de escrita de expresses matemticas em notao algbrica e na notao da gramtica da aplicao:
Notao algbrica
4x2 + 2x 3.05 x(x + 2)(x + 3)
x+1 x2 +25x
3
Notao da aplicao
4x2+2x3.05 x(x+2)(x+3) (x+1)/(x2+25x) 3|(2x+1)2 sen(x)2+cos(x)2 3sen(3x+4)cos(4-2x) (x2+3)(sen(3x)4) exp(x) (log(x)/x)2
(2x + 1)2
(3x)
Tabela 3.1
14
Esta
representao corresponde decomposio sintctica da expresso e a mais conveniente para efectuar processamentos seguintes. A estratgia de soluo implicou que tenham sido criados blocos funcionais para a execuo de tarefas especcas de cada transformao. A execuo desses blocos segue uma sequncia denida, numa lgica semelhante a uma linha de montagem, que pode ser organizada em trs grupos: preparao da expresso, transformao da expresso e apresentao da expresso transformada. A arquitectura segue um padro tpico em linguagens funcionais, ou seja, a de
gura 3.2 apresenta o diagrama da arquitectura da aplicao com os blocos constituintes de cada grupo.
Figura 3.2
Arquitectura da aplicao
Cada bloco funcional da arquitectura corresponde a uma funo especca, actuando o bloco como um ltro. Os blocos efectuam processamento e sempre que necessrio alteram o formato da entrada em outro que constitui a entrada para o bloco seguinte.
15
syntatic sugar ).
Por serem
permitidas omisses de operaes, este formato no se torna conveniente para a anlise e decomposio da expresso em elementos. O formato interno aquele em que todas as variantes sintcticas so substitudas pelas suas representaes completas, ocorrendo algumas transformaes expresso. O formato em que a expresso ca aps essas transformaes designa-se por
formato
interno.
2.
Validador sintctico
Aps ser convertida para o formato interno, a expresso pode ser submetida a testes de validao do ponto de vista sintctico. O objectivo detectar se a expresso obedece gramtica denida para a aplicao. Se houver alguma violao dessa gramtica, a expresso recusada, no sendo sujeita a mais processamento sendo o utilizador informado do erro ocorrido. A validao
efectuada atravs da vericao da ocorrncia de determinadas situaes. A tabela 6.2 indica as vericaes efectuadas e exemplos de situaes de ocorrncia de erro: 3.
parse-tree )
caracter da expresso, sendo o resultado nal um conjunto de elementos com uma organizao hierrquica. Cada elemento pode ser um nmero, uma varivel, uma operao ou uma funo
e possui uma estrutura prpria. A anlise do processo de construo da parse-tree est fora do mbito deste trabalho, bastando apenas a percepo que a rvore uma estrutura recursiva do seguintes tipo:
forada a tratar mais dois casos, identicar uma diviso como uma multiplicao pelo inverso de um nmero e uma radiciao como uma potncia de expoente fraccionrio.
4.
??
indica as vericaes
efectuadas e exemplos de situaes de erros: A partir da representao inicial da rvore da expresso no possvel determinar se existem violaes de domnio, uma vez que s durante a
16
simplicao que so efectuadas as operaes algbricas. Antes de efectuar qualquer operao que possa levar a violao de domnio, os operandos so testados. Se for detectada uma das trs situaes anteriores, a operao no efectuada e o erro colocado na prpria rvore da expresso.
5.
Derivador
O derivador analisa a representao em rvore da expresso e cria novos elementos para cada elemento analisado. O conjunto dos novos elementos criados constitui a representao em rvore da derivada. A regra de derivao fornece indicaes de como construir o elemento da derivada correspondente a uma expresso. So indicadas operaes e o papel dos sub-elementos como operandos. frequente tambm a necessidade de derivar os sub-elementos e incluir a sua derivada na rvore. Cada elemento da rvore da expresso substitudo por um outro que corresponde regra de derivao a aplicar a esse tipo. A primeira regra de derivao a aplicar obtida a partir do
primeiro elemento da rvore, que corresponde operao de menor prioridade da expresso. O processo de derivao, tal como o de simplicao, recursivo. Uma vez obtida toda a rvore
resultante de uma derivao, essa rvore simplicada pelo mesmo bloco que simplicou inicialmente a expresso.
6.
Construtor de expresso
Para ser possvel apresentar o resultado nal do processamento da representao em rvore de uma expresso, necessrio convert-la novamente para uma expresso no formato interno (com notao inxa).
7.
17
Captulo 4
framework
de igual propsito para Java. Foi desenvolvida em 2002 por Dean Herington encontrando-se ainda na sua verso 1.0. Utilizando a HUnit, tal como a JUnit, simples criar testes, atribuir-lhes nomes, agrup-los em suites e execut-los, deixando a vericao dos resultados ao cargo da
framework.
A especicao de
testes em HUnit ainda mais exvel do que em JUnit, devido natureza da linguagem Haskell. De momento, a HUnit s inclui um controlador baseado em texto, no entanto, a
framework
est desenhada
de forma a ser facilmente extendida e acomodar outros tipos de controladores. As seces seguintes exploram a
framework
4.1 Asseres
Uma
assero
o bloco mais bsico para a construo de um teste e dene-se como sendo a armao
de que uma proposio verdadeira. No contexto de uma linguagem de programao, essa proposio pode assumir a forma de uma condio passvel de ser avaliada como verdadeira ou falsa. A assero sobre essa condio equivale a armar que ela verdadeira. As asseres so combinadas de forma a serem includas em casos de teste e de igual forma, vrios casos de teste formam uma suite de testes. No contexto da linguagem Haskell, a
framework
type Assertion = IO ()
O tipo
IO
Integer
indica inteiro e
Bool
indica um valor lgico. Numa abordagem simples, pode pensar-se em computaes como funes que aceitam um estado do sistema como argumento e retornam um par constitudo pelo estado do sistema actualizado e um resultado. Dentro dessa funo ocorre uma sequncia de computaes de tipo
IO
que
podem alterar o estado do sistema. Exemplos disso sero a entrada e sada de caracteres ou a leitura e escrita de cheiros.
18
IO
IO
denominadas Monads, que um dos seus tpicos mais complexos. A discusso de Monads est fora do mbito desta anlise e no crtica para os seus objectivos. suciente encarar o tipo tipo que retorna informao para o exterior. As asseres so assim computaes
IO
como um
resultados para o exterior, no retornam resultados como as funes tipicamente fazem. A motivao das asseres serem representadas como computaes
laterais possam ser testados. A utilidade de uma assero a sinalizao de um sinal de erro, invocando a funo
assertFailure,
framework
Assertion.
assertFailure
Utilizando o mecanismo de
binding
linguagens funcionais), possvel associar um identicador a uma assero. Os tipos de asseres so os seguintes:
Booleana
Arma que uma expresso booleana verdadeira. Pode ser indicada uma mensagem de erro para o caso em que a assero seja avaliada como falsa quando executada num caso de teste.
assertBool :: String -> Bool -> Assertion assertBool msg b = unless b (assertFailure msg)
A aplicao de simplicao e derivao de expresses matemticas inclui uma funo que verica se uma
isNumber
string
no numricos. A funo retorna um valor booleano, pelo adequada para ser testada por este tipo de assero. Com esta funo possvel denir duas asseres booleanas:
assercao1 = assertBool "isNumber 2.5" (isNumber "2.5") assercao2 = assertBool "isNumber 2a5" (isNumber "2a5")
Quando forem includas num caso de teste, a primeira assero seria avaliada como verdadeira e a segunda como falsa pois inclui o caracter
que no numrico.
String
Arma que uma
string
19
assertString :: String -> Assertion assertString str = unless (null str) (assertFailure str)
A aplicao de simplicao e derivao de expresses matemticas inclui uma funo que extrai uma
substr
substring de outra mediante a indicao de posies de inicio e m. A funo retorna uma string resultante da extraco, pelo que adequada pode ser testada por este tipo de assero. Com esta funo possvel denir duas asseres de string :
assercao1 = assertString (substr "2x+3" 0 0) assercao2 = assertString (substr "2x+3" 1 3)
Quando forem includas num caso de teste, a primeira assero seria avaliada como verdadeira, retorna uma
string
string
no nula.
Igualdade
Arma que duas expresses so iguais. As expresses podem ser de qualquer tipo, no entanto, tm que entre elas ser do mesmo tipo. Pode ser indicada uma mensagem de erro para o caso em que a assero seja avaliada como falsa quando executada num caso de teste.
assertEqual :: (Eq a, Show a) => String -> a -> a -> Assertion assertEqual mensagem esperado avaliado = unless (avaliado == esperado) (assertFailure mensagem) where msg = (if null mensagem then "" else mensagem ++ "\n") ++ "expected: " ++ show esperado ++ "\n but got: " ++ show avaliado
A aplicao de simplicao e derivao de expresses matemticas inclui uma funo que simplica uma expresso matemtica indicada numa string.
simplif
string
resultante da simplicao, pelo que adequada pode ser testada por este tipo de assero. Com esta funo possvel denir duas asseres de igualdade. Alm da mensagem de erro, indica-se a expresso esperada e de seguida a expresso que deve ser avaliada para ser comparada com a esperada:
assercao1 = assertEqual "Simplificao: 2x+1+3x+4" "5x+5" (simplif "2x+1+3x+4") assercao2 = assertEqual "Simplificao: 2x+1+3x+4" "8x-2" (simplif "2x+1+3x+4")
Quando forem includas num caso de teste, a primeira assero seria avaliada como verdadeira, a expresso esperada igual avaliada, e a segunda como falsa, onde tal no acontece.
A denio de asseres por si s no tem aplicao prtica, necessrio inclu-las em casos de teste. durante a execuo de casos de teste que se avaliam as asseres de qualquer um dos trs tipos.
20
entre si, ou seja, a execuo de uns no est dependente da execuo de outros. Por outro lado, se um caso de teste incluir vrias asseres, a sua execuo no independente. Se uma assero no conjunto for avaliada como falsa, as seguintes j no sero avaliadas. Este raciocnio til para denir uma
lgica de testes incrementais em que existem funcionalidades que dependem umas das outras. Se uma funcionalidade falhar numa assero, no far sentido testar outra que depende do resultado errada da primeira. Independentemente do nmero de asseres que possa incluir, a criao de um caso de teste efectuada com o construtor
TestCase.
referenciar um identicador de uma (ou vrias) j criadas. A cada caso de teste pode ser associado um identicador com o mecanismo de binding (como acontece com as asseres).
TestCase :: Assertion -> Test cteste1 = TestCase assercao1 cteste2 = TestCase (assertString (substr "2x+3" 1 3))
No primeiro exemplo criado um caso de teste a partir do identicador identicador
assercao1
e associa-o ao
teste1.
string
e associa-o ao identicador
teste2.
No exemplo seguinte, o caso de teste composto por duas asseres com ordem de precedncia:
cteste = TestCase (do assertEqual ("fmt_int: "++expressao) esperado fmt_int assertEqual ("fmt_ext: "++expressao) expressao fmt_ext) where expressao = "3x^2-3x+4" esperado = "3*x^2+-3*x+4" fmt_int = ext2int expressao fmt_ext = int2ext fmt_int
A construo com A construo
do
necessria para conseguir colocar duas ou mais asseres num caso de teste.
where
dene
bindings
O objectivo deste caso de teste vericar se na aplicao de simplicao e derivao de expresses matemticas uma expresso correctamente convertida do formato externo para o interno e vice-versa. Sendo funes simtricas, podem ser incorporadas no mesmo caso de teste, mas s faz sentido avaliar a segunda se a primeira produzir resultados satisfatrios. A expresso associada ao identicador externo. A expresso associada ao no formato interno.
fmt_int.
int2ext
e associado ao identicador
fmt_ext.
expresso esperada na segunda assero a que inicialmente convertida para o formato interno, ou seja, associada ao identicador
expressao.
Garante-se que na execuo deste caso de teste, a segunda assero s ser avaliada se a primeira for verdadeira.
21
teste
TestCase
Test.
que um teste possa ser um conjunto de casos de teste ou um conjunto de testes. Num ambiente de testes, assim que o nmero de testes comea a aumentar recomendvel formar grupos de testes para os processar mais facilmente. Os identicadores por
binding
facilitam apenas a
tarefa do programador de testes. A capacidade de poder atribuir nomes a testes sob a forma de labels (
nomes a testes (ou grupos de testes) so as duas formas que o HUnit disponibiliza para gerir grandes coleces de testes. O tipo de dados possvel:
Test
Uma
TestList
uma lista de testes em vez de uma lista de casos de teste. Tal implica que a Desta forma, os testes podem ser organizados da mesma
O nome,
TestLabel,
uma
string
Tal
implica que a todos os ns da rvore pode ser associado um nome. Esta caracterstica facilita a organizao dos testes.
Uma
TestLabel
que opcional associar um nome a um teste. benco que assim seja, pois em certas situaes pode ser desnecessrio e inconveniente ter se associar sempre um nome a cada n de uma grande rvore de testes. Um exemplo na aplicao de simplicao e derivao de expresses matemticas a seguinte suite de testes:
tSNumeros = TestCase (assertEqual "Simplificacao:" "9" (simplif "2+7")) tSMonomios = TestCase (assertEqual "Simplificacao:" "9x" (simplif "2x+7x")) tSPolinomio = TestCase (assertEqual "Simplificacao:" "12x^2+4x+5" (simplif "3x^2+9x^2+3x+5+x")) tSomas = TestLabel "Somas" (TestList [TestLabel "Numeros" tSNumeros, TestLabel "Monomios" tSMonomios, TestLabel "Polinomio" tSPolinomio]) tPNumeros = TestCase (assertEqual "Simplificacao:" "14" (simplif "2*7")) tPMonomios = TestCase (assertEqual "Simplificacao:" "14x^2" (simplif "2x*7x"))
22
tPPolinomio
tProd
= TestLabel "Produtos" (TestList [TestLabel "Numeros" tPNumeros, TestLabel "Monomios" tPMonomios, TestLabel "Polinomio" tPPolinomio])
Figura 4.1
23
para testes com asseres ser sempre de 1 (no incluem outros testes). O resultado da contagem, no entanto, s inclui os testes com asseres, no entrando para a contagem todos os testes que sirvam para agregar outros. A tabela 4.1 inclui os trs casos relevantes de contagem para a suite de testes da gura 4.1:
Comando
testCaseCount tSNumeros testCaseCount tSomas testCaseCount suiteTP
Contagem
1 3 6
Tabela 4.1
Criando um novo teste na rvore no mesmo nvel dos testes agregadores Soma e Produto para o tratamento de simplicao de potncias:
Figura 4.2
A tabela 4.2 inclui os trs casos relevantes de contagem para a suite de testes da gura 4.2:
Comando
testCaseCount tSNumeros testCaseCount tSomas testCaseCount suiteTP
Contagem
1 3 7
Tabela 4.2
O nmero de casos de teste contado a partir da raiz da arvore aumenta para 7, porque o teste um teste com uma assero.
tPoten
24
Node
ListItem
ou uma
Label
e o
Path
data Node = ListItem Int | Label String deriving (Eq, Show, Read) type Path = [Node]
O tipo tipo:
Node
Test,
ListItem
Label.
A unicidade de um teste garantida somente pelo inteiro em ListItem, no entanto, se existir um nome para o teste, este includo pela seguindo-se o um, dois, etc. A ordem dos ns no caminho de baixo para cima, ou seja, do teste para o n de raiz que agrega todos os testes. Desta forma mais simples de comparar caminhos j que os que prexos comuns podem ser partilhados. Para apresentao dos caminhos que um teste comporta, utiliza-se a funo caminhos so listados na mesma ordem com que os testes sero executados.
Label.
testCasePaths.
Os
testCasePaths tSomas [[Label "Nmeros", ListItem 0, Label "Somas"], [Label "Monomios", ListItem 1, Label "Somas"], [Label "Polinomio", ListItem 2, Label "Somas"]]
O resultado uma lista com os trs testes com asseres com indicao do seu nome (Label) e
25
nmero (ListItem). No m de cada caminho tambm includo o nome do teste agregador, neste caso
Somas.
testCasePaths suiteTP [[Label "Nmeros", ListItem 0, Label [Label "Monomios", ListItem 1, Label [Label "Polinomio", ListItem 2, Label [Label "Nmeros", ListItem 0, Label [Label "Monomios", ListItem 1, Label [Label "Polinomio", ListItem 2, Label [ListItem 2, Label "Polinmios"]]
0, 0, 0, 1, 1, 1,
O resultado uma lista com os todos os caminhos para os casos de teste com asseres, que como se vericou na tabela 4.2, so sete. Note-se que o ltimo caso no tem
Tal deve-se ao facto de no ter sido denida qualquer nome para este teste. A nica forma do caminho se referir a ele indicando que o teste n
o 2 na sequncia da rvore.
O resultado dos caminhos da raiz da rvore identica a framework atribu automaticamente um nmero aos testes, como se pode vericar na gura 4.3:
Figura 4.3
Partindo do teste em direco raiz da rvore, a funo identicou os caminhos de teste indicados na tabela 4.3, atravs de nmeros e atravs de nomes:
Nmeros
0 0 0 1 1 1 2 0 1 2 0 1 2
Nomes
Nmeros Somas Polinmios Monmios Somas Polinmios Polinmio Somas Polinmios Nmeros Produtos Polinmios Monmios Produtos Polinmios Polinmio Produtos Polinmios Polinmios
Caminhos na hierarquia de testes
Tabela 4.3
26
Count:
data Counts = Counts {cases, tried, errors, failures :: Int} deriving (Eq, Show, Read)
Os quatro elementos da estrutura so valores inteiros cujo valor vai sendo alterado durante a execuo de um teste:
cases
Nmero de testes includos no teste, s sendo superior a um para o caso dos testes
agregadores. Este valor uma propriedade esttica de um teste e permanece inalterado durante a execuo.
tried
de testes).
errors
Nmero de testes cuja execuo abortou devido ocorrncia de uma excepo inesper-
ada. Estes erros acusam problemas com o teste e no com o cdigo a ser testado.
failures
Nmero de testes em que pelo menos uma assero foi avaliada como falsa.
Estes
erros acusam problemas com o cdigo a ser testado. No existe nenhum contador para os casos de teste bem sucedidos. H dois motivos para que assim seja. Por um lado esse valor facilmente calculvel atravs de:
Controladores de testes
Os testes em HUnit so executados por um processo denominado Controlador de teste. Este processo tem sempre o mesmo modelo de execuo, no entanto, pode apresentar os resultados de forma distinta. medida que a execuo do teste progride, so lanados trs tipos de eventos para o controlador de teste. Cada controlador pode responder de forma distinta aos eventos, variando normalmente na forma como os apresenta:
27
Erro sempre que um caso de teste termina devido deteco de um erro, reportada a mensagem de erro, o caminho e o estado actual do teste;
Falha sempre que um caso de teste termina devido a uma falha, a mensagem de falha reportada, o caminho e o estado actual do teste.
Tipicamente, um controlador de teste apresenta os relatrios de erros e falha imediatamente mas utiliza o relatrio de inicio meramente para actualizar o progresso no estado de execuo. O Hunit inclui apenas um controlador de testes que baseado em texto, no entanto, o utilizador pode denir outros para obter variaes na apresentao dos testes. A funo que implementa o controlador de testes nativo da framework a
runTestText:
no segundo argumento. Durante a execuo, o controlador cria uma acordo com o esquema de apresentao. para cada evento a reportar e processa-a de
retorna os contadores e o estado nal para o esquema de reporte (de tipo par As
IO (Counts, st))
strings
Um
showCounts aplicado aos contadores imediatamente antes da inicializao do caso de teste a ser executado: A funo showCounts apresenta o conjunto de contadores da estrutura Counts como uma string : showCounts :: Counts -> String
O resultado tem o seguinte aspecto:
reporte de incio
onde
"Cases: num_cases Tried: num_tried Errors: errors Failures: failures" num_cases, num_tried, num_errors e num_failures so os valores contados durante
apresentado como:
execuo.
Um
reporte de erro
onde
path
do caso de teste em que ocorreu o erro e
message
a mensagem que
A funo
showPath
string,
aceitando
showPath
os ns desde a raiz at ao teste (efectua uma inverso da lista de ns que recebe). Os ns so apresentados separados pelo delimitador
":".
A representao de
28
Um
reporte de falha
apresentado como:
onde
"### Failure in: path message" path o caminho do caso "### Failure: message"
message
a mensagem que
Esquemas de apresentao
O HUnit inclui dois esquemas de apresentao para controladores baseados em texto. entanto, ser denidos outros conforme for a convenincia do programador. numa funo especca: 1. A funo um Podem, no Cada esquema baseia-se
handle
handle
de sada.
newline.
True,
newline.
Antes do reporte seguinte ser escrito, o reporte de inicio apagado com uma
sequncia apropriada de
carriage return
em terminais. No conveniente que assim seja em cheiros pois produz linhas em branco no necessrias. 2. A funo
putTextToShowS
newlines.
runTestText)
ShowS
cujo
string
a ser concatenada s linhas de reporte j acumuladas. que serve de atalho para a utilizao mais comum de um
runTestTT
A funo
runTestTT
invoca a funo
runTestText,
especicando
handle
runTestTT :: Test -> IO Counts runTestTT t = do (counts, 0) <- runTestText (putTextToHandle stderr True) t return counts
29
runTestTT
runTestTT tSPolinomio Cases: 1 Tried: 0 Errors: 0 Failures: 0 Cases: 1 Tried: 1 Errors: 0 Failures: 0
Alterando o teste de modo que a assero seja avaliada como falsa, por alterao do polinmio esperado:
runTestTT tSPolinomio Cases: 1 Tried: 0 Errors: 0 Failures: 0 ### Failure: Simplificacao: expected: "10x^2+8x+3" but got: "12x^2+4x+5" Cases: 1 Tried: 1 Errors: 0 Failures: 1
( (
reporte de m )
Somas :
0 1 2 3 Errors: Errors: Errors: Errors: 0 0 0 0 Failures: Failures: Failures: Failures: 0 0 0 0
de de de de
Voltando a injectar a mesma falha na soma de polinmios, a execuo acusa o erro no caso de teste respectivo na sequncia dos outros casos de teste:
Errors: 0 Failures: 0
30
reporte de incio )
Cases: 3 Tried: 1 Errors: 0 Failures: 0 Cases: 3 Tried: 2 Errors: 0 Failures: 0 ### Failure: Somas:2:Polinomio Simplificacao: expected: "10x^2+8x+3" but got: "12x^2+4x+5" Cases: 3 Tried: 3 Errors: 0 Failures: 0
reporte de m do teste 3 )
Polinmios :
0 0 0 0 0 0 0 0 Failures: Failures: Failures: Failures: Failures: Failures: Failures: Failures: 0 0 0 0 0 0 0 0
de de de de de de de de
1) 2) 3) 4) 5) 6) 7)
runTestTT suiteTP Cases: 7 Tried: 0 Errors: 0 Failures: 0 Cases: 7 Tried: 1 Errors: 0 Failures: 0 Cases: 7 Tried: 2 Errors: 0 Failures: 0 ### Failure in: Polinmios:0:Somas:2:Polinomio Simplificacao: expected: "10x^2+8x+3" but got: "12x^2+4x+5" Cases: 7 Tried: 3 Errors: 0 Failures: 1 Cases: 7 Tried: 4 Errors: 0 Failures: 1 ### Failure in: Polinmios:1:Produtos:1:Monomios Simplificacao: expected: "15x^3" but got: "14x^2" Cases: 7 Tried: 5 Errors: 0 Failures: 2 Cases: 7 Tried: 6 Errors: 0 Failures: 2 Cases: 7 Tried: 7 Errors: 0 Failures: 2
31
de de de de
framework
Operador
pred @? msg expected @=? actual actual @?= expected
Assero criada
assertionPredicate pred >>= assertBool msg assertEqual "" expected actual assertEqual "" expected actual
Operadores de construo de asseres
Tabela 4.4
No operador na funo
@? indica-se uma condio booleana e uma mensagem de erro separadamente, tal como assertBool mas com diferente ordem. Os operadores @=? e @?= fornecem uma forma abreviada de criar asseres de igualdade com a funo assertEqual, quando no necessria mensagem de erro. Diferem apenas na ordem com que
os operandos so indicados (valor esperado e valor avaliado). No mbito da aplicao de derivao e simplicao de expresses matemticas, algumas asseres podem ser escritas mais facilmente:
Operao
(isNumber "2.5") @? "isNumber 2.5" "5x+5" @=? (simplif "2x+1+3x+4") (simplif "2x+1+3x+4") @?= "5x+5"
Assero criada
assertBool "isNumber 2.5" (isNumber "2.5") assertEqual "" "5x+5" (simplif "2x+1+3x+4") assertEqual "" "5x+5" (simplif "2x+1+3x+4")
Tabela 4.5
assert
da classe de tipo
Assertable: class Assertable t where assert :: t -> Assertion instance Assertable () where assert = return instance Assertable Bool where assert = assertBool ""
32
instance (ListAssertable t) => Assertable [t] where assert = listAssert instance (Assertable t) => Assertable (IO t) where assert = (>>= assert)
A classe
ListAssertable permite que a funo assert possa ser aplicada a uma lista de caracteres
[Char],
ou seja, uma
string :
class ListAssertable t where listAssert :: [t] -> Assertion instance ListAssertable Char where listAssert = assertString
Com as declaraes indicadas possvel denir asseres que nunca falham, tais como:
Assertable, ListAssertable
AssertionPredicable
Operador
pred ~? msg expected ~=? actual actual ~?= expected label ~: t
Teste criado
TestCase (pred @? msg) TestCase (expected @=? actual) TestCase (actual @?= expected) TestLabel label (test t)
Tabela 4.6
Os operadores
~?, ~=?
~?=
@?, @=?
@?=
~:
associa um nome (
33
No mbito da aplicao de derivao e simplicao de expresses matemticas, alguns testes podem ser escritos mais facilmente :
Operao
(isNumber "2.5") ~? "isNumber 2.5" "5x+5" ~=? (simplif "2x+1+3x+4") (simplif "2x+1+3x+4") ~?= "5x+5"
Teste criado
TestCase ((isNumber "2.5") @? "isNumber 2.5") TestCase ("5x+5" @=? (simplif "2x+1+3x+4")) TestCase ((simplif "2x+1+3x+4") @?= "5x+5")
Tabela 4.7
test
da classe de tipo
Testable:
class Testable t where test :: t -> Test instance Testable Test where test = id instance (Assertable t) => Testable (IO t) where test = TestCase . assert instance (Testable t) => Testable [t] where test = TestList . map test
A funo test constri um teste tanto atravs de um valor de tipo Assertion (utilizando a funo TestCase), uma lista de testes (utilizando TestList) ou um valor de tipo Test (no fazendo alteraes).
34
Captulo 5
Testador
(que
framework
um cheiro de sada em
plain text com os resultados dos casos de teste. O componente Interface serve de intermedirio entre o Testador e a aplicao a testar, evitando que dependam um do outro. Embora o Testador dependa de um Interface, este varia de aplicao para aplicao.
Figura 5.1
35
framework
5.4 Testador
O Testador destina-se a executar uma suite de testes extendendo a cionalidades, nomeadamente:
framework
parser
XML para HtestML, que permite escrita dos testes em cheiro XML (em
data driven ;
Resultados da execuo dos testes escritos num cheiro texto (em vez de terminal de sada); Traduo dos resultados para Portugus; Diferenciao de diferentes execues do mesmo conjunto de testes.
5.5 Interface
O Interface associa o Testador Aplicao, de forma a que um no dependa do outro. As suas principais funes so:
string ) com as
funes a invocar da
Show
string
Para cada aplicao a testar tem que existir um componente Interface associado, pelo que este mdulo depende sempre da aplicao. pode ser sempre diferente. Por esse motivo, o Testador inclu um mdulo Interface que
interpretar
testes indicados no cheiro XML em funes presentes na aplicao a testar. este mecanismo que permite que Testador no dependa directamente da aplicao e sim de uma Interface que conserva o seu nome mas varia conforme a aplicao.
36
teste torna o formato XML adequado para a sua representao. O Testador solicita um cheiro XML e converte-o numa lista de testes em memria de acordo com a hierarquia indicada pela profundidade dos elementos no documento. Com este formato possvel indicar:
Nomes para testes Descrio opcional para casos de teste Funo a executar em casos de teste Valor a avaliar na funo indicada Valor a esperar na avaliao da funo indicada
Document
que mais rico em termos descrio de ocorrncias e tipos de dados de elementos. Apresenta-se a seguir o
Schema
<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"> <xs:element name="TESTE"> <xs:complexType> <xs:sequence> <xs:element name="NOME" type="xs:string"/> <xs:choice minOccurs="1" maxOccurs="unbounded"> <xs:element ref="CASO_TESTE"/> <xs:element ref="TESTE"/> </xs:choice> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="CASO_TESTE"> <xs:complexType> <xs:sequence> <xs:element name="DESCRICAO" type="xs:string" minOccurs="0" maxOccurs="1"/> <xs:element name="FUNCAO" type="xs:string" minOccurs="1" maxOccurs="1"/> <xs:element name="AVALIAR" type="xs:string" minOccurs="1" maxOccurs="1"/> <xs:element name="ESPERAR" type="xs:string" minOccurs="1" maxOccurs="1"/> </xs:sequence> </xs:complexType> </xs:element> </xs:schema>
37
Apresenta-se a seguir o documento que representa a rvore de testes referente gura 4.2.
<?xml version="1.0" encoding="UTF-8"?> <TESTE xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:noNamespaceSchemaLocation="HtestML.xsd"> <NOME>Polinmios</NOME> <TESTE> <NOME>Somas</NOME> <CASO_TESTE> <DESCRICAO>Nmeros</DESCRICAO> <FUNCAO>simplif</FUNCAO> <AVALIAR>2+7</AVALIAR> <ESPERAR>9</ESPERAR> </CASO_TESTE> <CASO_TESTE> <DESCRICAO>Monmios</DESCRICAO> <FUNCAO>simplif</FUNCAO> <AVALIAR>2x+7x</AVALIAR> <ESPERAR>9x</ESPERAR> </CASO_TESTE> <CASO_TESTE> <DESCRICAO>Polinmio</DESCRICAO> <FUNCAO>simplif</FUNCAO> <AVALIAR>3x^2+9x^2+3x+5+x</AVALIAR> <ESPERAR>12x^2+4x+5</ESPERAR> </CASO_TESTE> </TESTE> <TESTE> <NOME>Produtos</NOME> <CASO_TESTE> <DESCRICAO>Nmeros</DESCRICAO> <FUNCAO>simplif</FUNCAO> <AVALIAR>2*7</AVALIAR> <ESPERAR>15</ESPERAR> </CASO_TESTE> <CASO_TESTE> <DESCRICAO>Monmios</DESCRICAO> <FUNCAO>simplif</FUNCAO> <AVALIAR>2x*7x</AVALIAR> <ESPERAR>14x^2</ESPERAR> </CASO_TESTE> <CASO_TESTE> <DESCRICAO>Polinmio</DESCRICAO> <FUNCAO>simplif</FUNCAO> <AVALIAR>3x^2*9x^2*3x*5*x</AVALIAR> <ESPERAR>405x^6</ESPERAR> </CASO_TESTE> </TESTE> <CASO_TESTE> <FUNCAO>simplif</FUNCAO> <AVALIAR>2^3</AVALIAR> <ESPERAR>8</ESPERAR> </CASO_TESTE> </TESTE>
plain text ).
o de vezes que esse cheiro foi executado nessa data (identicando assim a
execuo em causa). O prprio nome que o Testador atribui ao cheiro segue um formato que permite perceber estas atributos.
38
{ficheiro_origem}_{data}_{no execucao}.txt
A parte restante do cheiro consiste na apresentao do resultado da execuo de cada caso de teste. Este cheiro apresenta uma verso modicada do as mensagens traduzidas para Portugus. Tal como na
output produzido pela framework HUnit, com framework, para os casos bem sucedidos so
ESPERADO,
e o valor obtido
apresentadas somente os quatro contadores, no entanto, para os casos que apresentem falhas, indicada a funo, obtido do elemento
FUNCAO,
AVALIAR.
A indicao do caminho do caso de teste foi profundamente alterada. O caminho especicado de acordo com o standard de XML, como o
XPath do W3C, que identica elementos num documento XML. Alguns editores XML Spy, aceitam expresses XPath e navegam directamente para o elemento XML
identicado. Desta forma possvel facilmente identicar no documento que contem os testes, o caso de teste que falhou
39
Captulo 6
defeitos.
Os defeitos
ocorrem quando uma funcionalidade no tem o funcionamento esperado. Por outro lado, necessrio medir a
vrios nveis de qualidade. Este aspecto particularmente mensurvel na aplicao em teste quando efectua simplicaes de expresses. Os casos de teste so concebidos com base na especicao da aplicao a testar. A especicao expressa num conjunto de regras agrupadas por categorias. Cada regra tem um cdigo, uma descrio e especica o
input
output
Tratar cada regra (mais precisamente, a gama de valores de entrada especicada na condio) como uma classe de equivalncia
Uma vez que a especicao recursiva, um mesmo caso de teste pode cobrir vrias regras Encontrar um conjunto mnimo de casos de teste que cubram todas as regras Quando uma regra testada mais do que uma vez, usar valores diferentes
Nas seces seguintes apresentam-se as regras de especicao e os casos de testes concebidos para as contemplar.
40
Cod.
CVFI01 CVFI02 CVFI03 CVFI04 CVFI05 CVFI06
Descrio
Remoo de espaos Converso de maisculas em minsculas Insero de radical 2 onde implcito Insero de sinal
Formato externo
a +b
Formato interno
a+b sen(a) 2 a 2a 21a 2 + 1 x
Sen(a) a 2a 2a
onde implcito
Insero de factor (-1) onde omitido Insero de sinal antes de cada sinal
21a
Tabela 6.1
As regras CVFI01 e CVFI02 so sempre efectuadas para qualquer expresso. As regras restantes, pelo contrrio, s so efectuadas perante a presena de operadores especcos.
Validao sintctica
No cenrio da converso de formatos efectuada a validao sintctica de expresses no formato interno. A validao sintctica descrita por um conjunto de regras s quais correspondem vericaes efectuadas pela ordem apresentada na tabela 6.2:
Cod.
VSIN01 VSIN02 VSIN03 VSIN04 VSIN05 VSIN06
Descrio
Expresso no indicada Smbolo invlido Parntesis no fechados Expresso invlida Funo desconhecida Elemento desconhecido
Causa
Ausncia de caracteres Presena de caracteres no denidos na gramtica Parntesis abertos diferentes de parntesis fechados Sequncia gramatical no denida Funo no denida na gramtica Varivel no denida na gramtica
Expresso
Tabela 6.2
41
Cod.
CVFE01 CVFE02 CVFE03 CVFE04
Descrio
Remoo do radical 2 onde implcito Remoo do sinal
Formato interno
2 a
Formato externo
a
onde implcito
2a 21a 2 + 1 x
2a 2a 21a
Tabela 6.3
parse tree )
cujos ns so ele-
mentos. Cada elemento um tuplo formado por quatro atributos, de acordo com a seguinte organizao:
Cod.
REPA01 REPA02 REPA03 REPA04 REPA05 REPA06
Descrio
Constante Varivel Adio Multiplicao Potenciao Funo
Tipo
k x + nome
Coeciente
valor 1 1 1 1 1
Expoente
0 1 1 1 1 1
Sub-elementos
Parcelas Factores Base e Expoente Argumento
Tabela 6.4
Para construir a rvore, necessrio separar os operandos dos operadores na expresso. Para esse efeito, detectada a operao de menor precedncia e as posies em ocorre na expresso. A presena de parntesis implica que a expresso que encapsulam no considerada para a deteco da operao de menor prioridade da expresso exterior.
42
Simplicador.
Cod.
OPER01 OPER01 OPER01
Operao
Adio Multiplicao Potenciao
Descrio
c c c
o resultado da soma de
Expresso
a
a com
b b
c=a+b c=ab c = ab
com
Tabela 6.5
Cod.
PALG01 PALG02 PALG03 PALG04 PALG05 PALG06 PALG07 PALG08 PALG09 PALG10 PALG11 PALG12 PALG13 PALG14 PALG15 PALG16 PALG17
Descrio
Elemento neutro da adio Elemento inverso da adio Comutatividade da adio Associatividade da adio Denio de subtraco Elemento neutro da multiplicao Elemento absorvente da multiplicao Elemento inverso da multiplicao Comutatividade da multiplicao Associatividade da multiplicao Denio de diviso Soma de expoentes Produto de bases Produto de expoentes Expoente inverso Diferena de expoentes Denio de radiciao
Propriedade
a+0=a a + (a) = 0 a+b=b+a (a + b) + c = a + (b + c) a b = a + (b) a1=a a0=0 a
1 a
=1
a b = b
a (1 b)
a abc = a c b c (c b a =a )
Tabela 6.6
43
Funes matemticas
Finalmente, o processo de simplicao deve tratar algumas funes contempladas pela aplicao. Quando o argumento for numrico, deve ser substitudo pelo valor correspondente aplicao da funo, caso contrrio, deve ser simplicado o mais possvel. A tabela 6.7 apresenta as funes contempladas pela aplicao, agrupadas por categorias. A descrio comum a todas as regras, sendo aplicao da funo ao seu argumento
b o resultado da
a,
em que
a identicao do domnio de cada funo, porque essa informao importante para uma das regras de validao semntica.
Cod.
FUNC01 FUNC02 FUNC03 FUNC04 FUNC05 FUNC06 FUNC07 FUNC08
Funo
Seno Co-seno Tangente Arco seno Arco co-seno Arco tangente Logartmica Exponencial
Expresso
b = sen(a) b = cos(a) b = tg (a) b = arcsen(a) b = arccos(a) b = arctg (a) b = log (a) b = exp(a)
Domnio (D)
aR aR aR:a= a [1, 1] a [0, ] aR a R+ aR
2
+ k, k Z
Em simultneo com o processo de simplicao de uma expresso efectuada a sua validao semntica, onde se vericam as regras apresentadas na tabela 6.8. Todas as regras se referem a violaes de
domnio das expresses, no entanto, separam-se em trs regras diferentes para identicar os casos de maior destaque.
Cod.
VSEM01 VSEM02 VSEM03
Descrio
Argumento invlido Diviso por zero Radicando negativo
Causa
Violao do domnio de uma funo da tabela 6.7 Denominador de fraco simplica para zero Radicando negativo em raiz de ndice par
Expresso
a /D
a b,b = 0 b a, a < 0 b
par
Tabela 6.8
Derivador.
respondem s regras de derivao suportadas pela aplicao e contemplam constantes, variveis, as operaes da tabela 6.5 e as funes da tabela 6.7.
44
A notao utilizada a
y y a a
b b
y
e
respectivamente
Cod.
RDEV01 RDEV02 RDEV03 RDEV04 RDEV05 RDEV06 RDEV07 RDEV08 RDEV09 RDEV10 RDEV11 RDEV12 RDEV13
Descrio
Constantes Variveis Adio Multiplicao Potenciao Funo seno Funo co-seno Funo tangente Funo arco seno Funo arco co-seno Funo arco tangente Funo exponencial Funo logaritmo
Expresso
y=k y=x y =a+b y = ab y=a
b
Derivada
y =0 y =1 y =a +b y = a b + ab y = bab1 a + b ab log (a) y = a cos(a) y = a sen(a) y = 1 + tg (a)2 y = y = y = y =
a 1a a 1 a a 1+a a a a
y =ae
Tabela 6.9
45
ivalidar_sint,
input
output
obtm-se a expresso
se a converso para o formato interno no afecta constantes, e em simultneo, se a aplicao consegue tratar gamas de valores elevadas, bem como um grande nmero de casas decimais. No estando denida na gramtica das expresses a notao cientica para exprimir valores de gamas elevadas, nos casos de teste necessrio a indicar estes valores em notao normal. Note-se que nesta converso no ocorre qualquer simplicao de valores, pelo que de esperar que os valores se mantenham com o mesmo aspecto, ainda que possam conter dgitos redundantes.
No
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
Input
0 0000 1 0001 123456 10000000000 -0 -0000 -1 -0001 -123456 -10000000000 0.0 0000.0000 1.5 456.7890123 -0.0 -1000.0000 -1.5 -456.7890123
Output
0 0000 1 0001 123456 10000000000 -0 -0000 -1 -0001 -123456 -10000000000 0.0 0000.0000 1.5 456.7890123 -0.0 -1000.0000 -1.5 -456.7890123
Descrio
Zero sem sinal com um digito Zero sem sinal com dgitos redundantes Valor inteiro positivo com um digito Valor inteiro positivo com dgitos redundantes Valor inteiro positivo com vrios dgitos Valor inteiro positivo elevado Zero com sinal negativo com um digito Zero com sinal negativo com dgitos redundantes Valor inteiro negativo com um digito Valor inteiro negativo com dgitos redundantes Valor inteiro negativo com vrios dgitos Valor inteiro negativo elevado Zero sem sinal com um digito com uma casa decimal Zero sem sinal com dgitos redundantes e casas decimais Valor inteiro positivo com um digito e uma casa decimal Valor inteiro positivo com casas decimais Zero com sinal negativo com uma casa decimal Valor inteiro negativo com casas decimais redundantes Valor inteiro negativo com um digito com uma casa decimal Valor inteiro negativo com casas decimais
Tabela 6.10
46
2.
No
1 2 3 4 5 6 7
Input
X +1 + SEN (Cos(x))
Output
x + 1 + sen(cos(x)) 2|(x + 2) + 3|x 2 x + x sen(x) x (x + 1) (x + 2) 2 + 1 x + 5 + 3 1 (x + 1) 2 2|(x + 1 (x 5 cos(x)))
Tabela 6.11
3.
No
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
Input
Output
ERRO: Funcao nao indicada
2?3 cos(2 \ 4) y = 2x + 3 ((x + 1)(x + 2) + 3 (x + 1))(x + 2) + 3 sen(x + 3 +1 1 2 + 5 2 + sec(x) sen(cotg (x)) 2 + sec + x sen(t) 2x + 3 equation
ERRO: Simbolo invalido ERRO: Simbolo invalido ERRO: Simbolo invalido ERRO: Parenteses nao fechados correctamente ERRO: Parenteses nao fechados correctamente ERRO: Parenteses nao fechados correctamente ERRO: Expressao invalida ERRO: Expressao invalida ERRO: Expressao invalida ERRO: Funcao 'sec' desconhecida ERRO: Funcao 'cotg' desconhecida ERRO: Elemento 'sec' desconhecido ERRO: Elemento 't' desconhecido ERRO: Elemento 'equation' desconhecido
Tabela 6.12
4.
47
No
1 2 3 4 5 6
Input
2|(x + 2) + 3|x 2 x + x sen(x) x (x + 1) (x + 2) 2 + 1 x + 5 + 3 1 (x + 1) 2 2|(x + 1 (x 5 cos(x)))
Output
|(x + 2) + 3|x 2x + xsen(x) x(x + 1)(x + 2) 2x+53 (x + 1) 2 | (x (X 5cos(x)))
Tabela 6.13
iespandir.
A funo
espandir
efectua na aplicao a converso de uma expresso em Esta funo levantou o problema da apresentao dos
string
Expressao.
string e assim possibilitar a sua utilizao na arquitectura de testes denida, foi necessrio incluir na interface de testes um instncia da funo
show para o tipo de dados Expressao. A funo iespandir da interface por sua vez invoca a funo show sobre a funo espandir o que possibilita a apresentao
do resultado como uma Como
string. output
obtm-se a lista correspondente
input
representao em rvore. 1.
No
1 2 3 4 5 6
Input
3.5 x 2+x 2x 2x cos(x + 2)
Output
(k, 3.5, 0.0, []) (x, 1.0, 1.0, []) (+, 1.0, 1.0, [(k, 2.0, 0.0, [])(x, 1.0, 1.0, [])]) (, 1.0, 1.0, [(k, 2.0, 0.0, [])(x, 1.0, 1.0, [])]) (, 1.0, 1.0, [(k, 2.0, 0.0, [])(x, 1.0, 1.0, [])]) (cos, 1.0, 1.0, [(+, 1.0, 1.0, [(x, 1.0, 1.0, [])(k, 2.0, 0.0, [])])])
Tabela 6.14
2.
48
No
1 2
Input/Output
2 + 3 + 4 + 5 (+, 1.0, 1.0, [(k, 2.0, 0.0, [])(k, 3.0, 0.0, [])(k, 4.0, 0.0, [])(k, 5.0, 0.0, [])]) 2 3 + 4 x + 5 (+, 1.0, 1.0, [(, 1.0, 1.0, [(k, 2.0, 0.0, [])(k, 3.0, 0.0, [])]) (, 1.0, 1.0, [(k, 4.0, 0.0, [])(x, 1.0, 1.0, [])])(k, 5.0, 0.0, [])])
4x2+3x+1 (+, 1.0, 1.0, [(, 1.0, 1.0, [(k, 4.0, 0.0, [])(, 1.0, 1.0, [(x, 1.0, 1.0, [])(k, 2.0, 0.0, [])])]) (, 1.0, 1.0, [(k, 3.0, 0.0, [])(x, 1.0, 1.0, [])])(k, 1.0, 0.0, [])])
4 5 6 7 8 9 10
(x + 2.5) 3.2 (, 1.0, 1.0, [(+, 1.0, 1.0, [(x, 1.0, 1.0, [])(k, 2.5, 0.0, [])])(k, 3.2, 0.0, [])]) 2 x (3 + x + 5) (, 1.0, 1.0, [(k, 2.0, 0.0, [])(x, 1.0, 1.0, [])(+, 1.0, 1.0, [(k, 3.0, 0.0, [])(x, 1.0, 1.0, [])(k, 5.0, 0.0, [])])]) (x + 1) (x + 2) (, 1.0, 1.0, [(+, 1.0, 1.0, [(x, 1.0, 1.0, [])(k, 1.0, 0.0, [])])(+, 1.0, 1.0, [(x, 1.0, 1.0, [])(k, 2.0, 0.0, [])])]) ((x + 1)) (+, 1.0, 1.0, [(x, 1.0, 1.0, [])(k, 1.0, 0.0, [])]) ((((x + 1)))) (+, 1.0, 1.0, [(x, 1.0, 1.0, [])(k, 1.0, 0.0, [])]) ((((x + 1)) + 2)) (+, 1.0, 1.0, [(+, 1.0, 1.0, [(x, 1.0, 1.0, [])(k, 1.0, 0.0, [])])(k, 2.0, 0.0, [])]) tg (log (2 x) + sen(x)) (tg, 1.0, 1.0, [(+, 1.0, 1.0, [(log, 1.0, 1.0, [(, 1.0, 1.0, [(k, 2.0, 0.0, [])(x, 1.0, 1.0, [])])]) (sen, 1.0, 1.0, [(x, 1.0, 1.0, [])])])])
Tabela 6.15 Testes genricos de converso de expresses no formato interno a representao em rvore
inputs
sero expresses no formato externo, que sero convertidas para o formato interno e poste-
riormente para sua representao em rvore. Nessa representao, aplicada a funo de simplicao que reduz a rvore o mais possvel. A rvore convertida na expresso no formato interno e de seguida no formato externo, que sero os
outputs.
Os testes podiam incidir somente na componente de simplicao, no entanto, tal obrigaria a trabalhar com representaes em rvore que so de escrita extensa e pouco cmoda, no trazendo qualquer mais-valia para os objectivos destes testes. Estes so por um lado, avaliar a correco da expresso
simplicada e por outro medir a qualidade da simplicao, ou seja, se de facto a expresso resultante a mais simples possvel ou se seria possvel efectuar mais simplicaes. Os testes de simplicao incluem vericao das regras e propriedades dos operadores algbricos bsicas, das funes denidas, regras de validao semntica, requisitos bsicos de simplicao e por m teste de qualidade.
49
No
1 2 3 4 5 6
Input
1.1 + 2.3 + 4 1.1 2.3 4 1.1 2.3 4 35+23+1 3x 2 + 2x + 4 + 5x 2 + 3x + 2 sen(x) + 4 + 3x + 2sen(x) + 2 + x
Output
7.4 10.12 14.399156128283 24 8x 2 + 5x + 6 3sen(x) + 6 + 4x
Tabela 6.16
No
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
Input
5+0+3 5 + (5) 2+x+3 x+2+3 (2 + x) + 3 2 + (x + 3) 23 2 + (3) 513 503 3x x3 (2x) 3 2(3x) 2/5
Output
8 0 x+5 x+5 x+5 x+5 1 1 15 0 3x 3x 6x 6x 0.4
Tabela 6.17
50
No
16 17 18 19 20 21 22 23 24 25 26 27 28
Input
2 0.2 5 (1/5) 3233 3 (2 + 3) 223 2 (2 3) (2 2) 3 2 (3) 1/(2 3) 3 (5 2) 3 5/3 2 |(3 4) 3 (4/2)
Output
0.4 1 243 243 256 256 64 0.125 0.125 27 27 9 9
Tabela 6.18
No
1 2 3 4 5 6 7 8 9 10 11
Input
sen(0) sen(arcsen(1) 2/3) sen(arcsen(1)) cos(0) cos(arcsen(1)/6) cos(arcsen(1)) tg (0) tg (arcsen(1) 2/3) arcsen(0) arcsen(1) arccos(0)
Output
0 0.866025403784439 1 1 0.965925826289068 0 0 1.73205080756888 0 1.5707963267949 1.5707963267949
O grupo de testes das tabelas 6.21 destinam-se a vericar as regras de validao semntica atravs de expresses que contenham violaes do domnio das funes envolvidas. As funes so as indicadas
51
No
12 13 14 15 16 17 18 19
Input
arccos(1) arctg (0) arctg (1) e(0) e(1) log (1) log (e(1)) e(log (1))
Output
0 0 0.785398163397448 1 2.71828182845905 0 1 1
Tabela 6.20
na 6.7 que inclu uma coluna para a gama de valores admitidos no domnio. Nos testes seguintes, a violaes de domnio explicita em alguns casos e implcita noutros (advm de simplicao de valores).
No
1 2 3 4 5 6 7 8
Input
tg (arccos(1)/2) arcsen(2) arccos(2 arccos(1)) log (0) (5 x)/(3 + 8 5) 3/(x x) |(1) 4|(2)
Output
ERRO: Argumento invalido em 'tg' ERRO: Argumento invalido em 'arcsen' ERRO: Argumento invalido em 'arccos' ERRO: Argumento invalido em 'log' ERRO: Divisao por zero ERRO: Divisao por zero ERRO: Radicando negativo em raiz de radical par ERRO: Radicando negativo em raiz de radical par
O ltimo conjunto de testes no mbito da simplicao visa averiguar a qualidade da simplicao. Para estes testes, assume-se que a expresso em causa ser simplicada sem erros. Nestes testes no so indicadas as regras de especicao cobertas, uma vez que no esse o foco de anlise. O foco da anlise vira-se para a capacidade da aplicao em obter expresses o mais simples possvel. Assim os resultados destes, indicam no se a expresso est correcta, mas se est efectivamente na sua forma mais simples. 1. Simplicao de Somas As expresses que envolvem somas foram agrupadas em dois conjuntos: o das somas simplicveis (tabela 6.22) e o das somas no simplicveis (tabela 6.23). 2. Simplicao de Diferenas Neste conjunto de testes (tabela 6.24) pretende-se avaliar se uma expresso simplica correctamente para o valor zero atravs de diferenas de valores simtricos.
52
No
1 2 3 4 5
Input
x 2 + 3x + 4 + 5x 2 + 4x + 6 4 + 3x + x 2 + 5x 2 + 4x + 6 (x 2 + 3x + 4) + (5x 2 + 4x + 6) (x 2 + 3x + 4) + 2(5x 2 + 4x + 6) sen(x) + sen(x + 1) + sen(x) + sen(x + 1)
Output
6x 2 + 7x + 10 6x 2 + 7x + 10 6x 2 + 7x + 10 x 2 + 3x + 4 + 2(5x 2 + 4x + 6) 2sen(x) + 2sen(x + 1)
Tabela 6.22
No
1 2 3 4 5 6 7 8 9
Input
x 2 + 3x + 4 4 + 3x + x 2 (x 2 + 3x) + 4 x 2 + (3x + 4) (x 2 + 3x + 4) sen(x) + cos(x) sen(x) + sen(x) 2 sen(x 2) + sen(x) sen(x) + (x + 1)
Output
x 2 + 3x + 4 x 2 + 3x + 4 x 2 + 3x + 4 x 2 + 3x + 4 x 2 + 3x + 4 sen(x) + cos(x) sen(x) + sen(x) 2 sen(x 2) + sen(x) sen(x) + x + 1
Tabela 6.23
3. Simplicao de Produtos
As expresses que envolvem produtos foram agrupadas em dois conjuntos: o dos produtos simplicveis (tabela 6.25) e o dos produtos no simplicveis (tabela 6.26). 4. Simplicao de Divises Neste conjunto de testes (tabela 6.27) pretende-se avaliar se uma expresso simplica correctamente para o valor unitrio ou se elimina factores neutros. 5. Simplicao de Potncias As expresses que envolvem potncias foram agrupadas em dois conjuntos: o das potncias simplicveis (tabela 6.28) e o das potncias no simplicveis (tabela 6.29).
iderivar
de derivao com as simplicaes envolvidas. Num primeiro grupo de testes so vericadas as regras de derivao, sendo ento efectuados testes com a composio de vrias regras em expresses que do origem a derivadas progressivamente mais complexas.
53
No
1 2 3 4 5 6 7
Input
(x + 1) x 1 (x + 1) (x + 1) (x + 1) 2 (x + 1) 2 x 2 + 3x + 4 5x 2 4x 6 + 4x 2 + x + 2 sen(x) + 2sen(x) 3sen(x) sen(x 2) sen(x 2) sen(x) 2 sen(x) 2
Output
0 0 0 0 0 0 0
Testes de diferenas
Tabela 6.24
No
1 2 3 4 5 6
Input
2xxx x(x + 1)(x + 1)(x + 2) (x + 1)x(x + 1)(x + 2) (x + 1) 2(x + 2)(x + 1) 3 sen(x)cos(x)sen(x) sen(x)x cos(x)sen(x) 2
Output
2x 3 (x + 1) 2x(x + 2) (x + 1) 2x(x + 2) (x + 2)((x + 1) 5) sen(x) 2cos(x) sen(x) 3 x cos(x)
O grupo de testes da tabela 6.30 pretende vericar as regras de derivao apresentadas na tabela 6.9.
54
No
1 2 3 4 5
Input
x(x + 1) x(x + 1)(x + 3)(x + 2) x(x + 1)(x + 2)(x + 3) sen(x + 1)cos(x)sen(x) sen(x)sen(x 2)
Output
x(x + 1) x(x + 1)(x + 3)(x + 2) x(x + 1)(x + 2)(x + 3) sen(x + 1)cos(x)sen(x) sen(x)sen(x 2)
Tabela 6.26
No
1 2 3 4 5 6
Input
x(1/x) x(x + 1)/x (x + 1)x/x (x + 1)(x + 2)/(x + 1) (x + 2)(x + 1)/(x + 1) ((x + 1)(x + 2))/(x + 1)
Output
1 x+1 x+1 x+2 x+2 x+2
Tabela 6.27
No
1 2 3 4 5 6
Testes de divises
Input
x2x3 x (x + 1) + x (x + 1) x (x 2) x (x + 1 1) x8+x8 x23+x8
Output
x5 2x (x + 1) xx2 xx 2x 8 2x 8
Tabela 6.28
No
1 2 3 4
Input
x (x + 1) (x + 1) x x sen(x) sen(x) x
Output
x (x + 1) (x + 1) x x sen(x) sen(x) x
Tabela 6.29
55
No
1 2 3 4 5 6 7 8 9 10 11 12 13
Input
3.5 x 3x x(4x + 5) x (x + 1) sen(x) cos(x) tg (x) arcsen(x) arccos(x) arctg (x) e(x) log (x)
Output
0 1 3 8x + 5 x x(x + 1) + log (x)x (x + 1) cos(x) sen(x) 1 + tg (x) 2 1/|(1 + x 2) 1/((1 + x 2) 0.5) 1/(1 + x 2) e(x) 1/x
Tabela 6.30
56
No
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
Input
3x 2 5x + 1 (x + 3) 5 (x 1)(x 3) (2x 3)(x 2)(x + 3) 1/(x + 3) (3x + 1)/(x 2 8x) ((x 1)/(x + 2)) 2 ((x 2 1)/2x) 3 |(x 3) sen(2x + 1) xsen(x) 2 + 3sen(2x) sen(x 3) 3 cos(3x 2 x) 2cos(1 x) 3 cos(x) + xcos(x 2) 2 sen(x)cos(x) tg (1/(x + 3)) tg (x 2 + 1) 2 cos(x) 2 + tg (xsen(x) 2) tg (|(x 2 + 1)) + tg (cos(x)) arcsen(x 2 + 1) sen(x) 2 + arcsen(x 2) 2 + arcsen(cos(x) 2) 2 arcsen(1/x) + sen(1/x) arccos(x)/x sen(x)arccos(2x) x 3 arccos(|(x 2 1)) arctg (|(x 2 + 1)) 1 + arctg (x) 2 e(x/2) (x 1) 2 e(x) e(arcsen(x)) e(x)sen(x) + e(1/x) log (x 2 + 1) log (sen(x)) log (e(3x) + x 2) cos(log (arctg (x))) (5x) (log (x)) arctg (x) sen(x)
2
Output
6x 5 5(x + 3) 4 2x 4 6x 2 2x 15 1/(x + 3) 2 (3x 2 2x + 8)/(x 2 8x) 2 6(x 1)/((x + 2) 3) 3(x 2 1) 2(x 2 + 1)/(8x 4) 1/(2 |(x 3)) 2cos(2x + 1) sen(x) 2 + 2x 2cos(x) 2 + 6cos(2x) 9cos(x 3)x 2sen(x 3) 2 sen(3x 2 x)(6x 1) 6sen(1 x)cos(1 x) 2 sen(x) 4xsen(x 2)xcos(x 2) + cos(x 2) 2 sen(x) 2 + cos(x) 2 (1 + tg (1/(x + 3)) 2)/((x + 3) 2) 4x(1 + tg (x 2 + 1) 2)tg (x 2 + 1) 2sen(x)cos(x) + (1 + tg (xsen(x) 2) 2)(2xcos(x)sen(x) + sen(x) 2) 2x/|(x 2 + 1) 2x/|(1 (x 2 + 1) 2) 2xsen(x) + (2x)/|(1 x 4) (2sen(2x)arcsen(cos(x) 2))/|(1 cos(x) 4) 1/(x |(x 2 1)) cos(1/x)/(x 2) (x |(1 x 2)arcsen(cos(x) 2)/(x 2 |(1 x 2)) 2sen(x)/|(1 4x 2) + cos(x)arccos(2x) 3x 2arccos(|(x 2 1)) x4 /((|x 2 1)(|2 x 2)) x/(|(x 2 + 1)(x 2 + 2)) 2arctg (x)/(1 + x 2) 0.5e(0.5x) ((x 1) 2)e(x) + 2(x 1)e(x) e(arcsen(x))/|(1 x 2) e(x)cos(x) + e(x)sen(x) e(1/x) 1/x 2 2x/(x 2 + 1) cos(x)/sen(x) (3e(3x) + 2x)/(e(3x) + x 2) sen(log (arctg (x)))/((1 + x 2)arctg (x)) 5log (x)(5x) (log (x) 1) + (log (5x)(5x) log (x))/x (sen(x)arctg (x) (sen(x) 1))/(1 + x 2) + log (arctg (x))arctg (x) sen(x)cos(x)
Testes de composio de regras de derivao 57
Tabela 6.31
Captulo 7
Suite
1 2 3 4 5 6 7 8 9 10 11
Testes
Converso de formatos: Valores numricos (Tabela 6.10) Converso de formatos: Formato externo e formato interno (Tabela 6.11) Converso de formatos: Validao sintctica (Tabela 6.12) Converso de formatos: Formato interno para formato externo (Tabela 6.13) Converso de formatos: Representao em rvore (Tabelas 6.14 e 6.15) Simplicao: Operaes algbricas bsicas (Tabela 6.16) Simplicao: Propriedades dos operadores algbricos (Tabelas 6.17 e 6.18) Simplicao: Funes (Tabelas 6.19 e 6.20) Simplicao: Validao semntica (Tabela 6.21) Simplicao: Qualidade (Tabelas 6.22, 6.23, 6.24, 6.25, 6.26, 6.27, 6.28 e 6.29) Derivao de expresses (Tabelas 6.30 e 6.31)
Ficheiro
ext2int_const.xml ext2int_transf.xml ext2int_vsint.xml ext2int_transf.xml reparv.xml simpl_op.xml simpl_op.xml simpl_func.xml simpl_vsem.xml simpl_qualid.xml derivar.xml
Tabela 7.1
Execuo de testes
Testador> testador *** Teste de programas em Haskell *** Ficheiro XML com os testes a efectuar: derivar Executando testes em 'derivar.xml' ... Resultados em 'derivar_2005June6-001.txt'
58
Resultados dos testes em 'derivar.xml' Execuo no 004 de 2005June6 Casos: Casos: Casos: Casos: Casos: Casos: 65 65 65 65 65 65 Tentados: Tentados: Tentados: Tentados: Tentados: Tentados: 0 1 2 3 4 5 Erros: Erros: Erros: Erros: Erros: Erros: 0 0 0 0 0 0 Falhas: Falhas: Falhas: Falhas: Falhas: Falhas: 0 0 0 0 0 0
### Falha em: /TESTE[NOME='Derivacao de Expressoes']/TESTE[NOME='Derivadas simples']/ CASO_TESTE[FUNCAO='derivar' and AVALIAR='x^(x+1)'] esperado: "x^x(x+1)+log(x)x^(x+1)" obtido: "x^(x+1-1)(x+1)+log(x)x^(x+1)" Casos: Casos: Casos: Casos: Casos: Casos: Casos: 65 65 65 65 65 65 65 Tentados: Tentados: Tentados: Tentados: Tentados: Tentados: Tentados: 6 7 8 9 10 11 12 Erros: 0 Erros: 0 Erros: 0 Erros: 0 Erros: 0 Erros: 0 Erros: 0 Falhas: 1 Falhas: 1 Falhas: 1 Falhas: 1 Falhas: 1 Falhas: 1 Falhas: 1
### Falha em: /TESTE[NOME='Derivacao de Expressoes']/TESTE[NOME='Derivadas simples']/ CASO_TESTE[FUNCAO='derivar' and AVALIAR='tg(3x^2)'] esperado: "6x(1+tg(3x^2)^2)" obtido: "6(1+tg(3x^2)^2)x" Casos: 65 Tentados: 13 Erros: 0 Falhas: 2 ### Falha em: /TESTE[NOME='Derivacao de Expressoes']/TESTE[NOME='Derivadas simples']/ CASO_TESTE[FUNCAO='derivar' and AVALIAR='arcsen(x)'] esperado: "1/|(1+x^2)" obtido: "1/((1+x^2)^0.5)" Casos: 65 Tentados: 14 Erros: 0 Falhas: 3 ### Falha em: /TESTE[NOME='Derivacao de Expressoes']/TESTE[NOME='Derivadas simples']/ CASO_TESTE[FUNCAO='derivar' and AVALIAR='arcsen(3x^2)'] esperado: "6x/|(1+9x^4)" obtido: "6x/((1+9x^4)^0.5)" Casos: 65 Tentados: 15 Erros: 0 Falhas: 4 ### Falha em: /TESTE[NOME='Derivacao de Expressoes']/TESTE[NOME='Derivadas simples']/ CASO_TESTE[FUNCAO='derivar' and AVALIAR='arccos(x)'] esperado: "-1/|(1-x^2)" obtido: "-1/(-(1+x^2)^0.5)" Casos: 65 Tentados: 16 Erros: 0 Falhas: 5 ### Falha em: /TESTE[NOME='Derivacao de Expressoes']/TESTE[NOME='Derivadas simples']/ CASO_TESTE[FUNCAO='derivar' and AVALIAR='arccos(3x^2)'] esperado: "-6x/|(1-9x^4)" obtido: "-6x/((1+9x^4)^0.5)" Casos: 65 Tentados: 17 Erros: 0 Falhas: 6 Casos: 65 Tentados: 18 Erros: 0 Falhas: 6 Casos: 65 Tentados: 19 Erros: 0 Falhas: 6 ...
59
Suite
1 2+4 3 5 6+7 8 9 10 11
Testes
Converso de formatos: Valores numricos Converso de formatos: Formato externo e formato interno Converso de formatos: Validao sintctica Converso de formatos: Representao em rvore Simplicao: Operaes algbricas bsicas + Propriedades Simplicao: Funes Simplicao: Validao semntica Simplicao: Qualidade Derivao de expresses
Casos
20 12 14 18 33 19 4 42 65
Falhas
0 1 0 0 4 1 1 14 28 (0%) (8%) (0%) (0%) (12%) (5%) (25%) (33%) (43%)
Tabela 7.2
Os testes das suites 1 a 9 so testes que tm como objectivo a deteco de falhas na especicao da aplicao. Os testes da suites 10 visam medir a qualidade da simplicao efectuada. Os testes da suite 11 tm como objectivo simultaneamente detectar falhas no processo de derivao e medir a qualidade da simplicao que efectuada derivada. No primeiro grupo (suites 1 a 9), verica-se que o processo de simplicao a nvel de operaes bsicas e suas propriedades o que tem o nvel de falhas mais elevado. falhas permitir averiguar sobre a sua gravidade. No segundo grupo (suites 10 e 11), verica-se que os nveis de falhas so igualmente elevados, o que revela que, de uma forma geral, a aplicao no simplica totalmente as expresses, relativamente ao que seria esperado. Nas seces seguintes efectuada uma anlise a estes resultados tendo em conta os objectivos denidos para cada teste. A anlise detalhada destas
60
Avaliado
2|(x + 1 (x 5 cos(x)))
Esperado
|(x 1(x 5cos(x)))
Obtido
2|(x 1(x 5cos(x)))
Tabela 7.3
7.2.2 Simplicao
Operaes bsicas e as suas propriedades
O primeiro grupo de testes de simplicao incide na vericao das operaes bsicas e das suas propriedades. No mbito destes testes foram detectadas 4 falhas em 33 casos de teste, representando 15%. A tabela 7.4 apresenta os casos de teste com falhas:
Avaliado
5 + (5) 2+x+3 (2 + x) + 3 2 + (x + 3)
Esperado
0 x+5 x+5 x+5
Obtido
1 5+x 5+x 5+x
Tabela 7.4
Verica-se que destas falhas h uma muito grave sendo as outras trs menos graves. A primeira falha, na soma de um valor com o seu simtrico compromete seriamente todo o processo de simplicao, pelo deve corrigida de imediato. As trs falhas restantes devem-se ao facto de ser esperado um polinmio ordenado por grau e a aplicao no efectuar essa ordenao. Esta falha vai manifestar-se em muitos dos testes seguintes em que so esperados polinmios ordenados por grau. Como no afecta a correco do resultado, considerada de menor gravidade.
Avaliao de funes
Este grupo de testes acusou um falha num conjunto de 19 casos, apresentada da tabela 7.5:
Avaliado
cos(arcsen(1))
Esperado
0
Obtido
6.12303176911189e 017
Tabela 7.5
era obter o valor de
Esta falha resulta da aproximao de valores utilizada pelo interpretador do Haskell. A inteno
arcsen(1), no entanto, o valor obtido foi aproximado levando a que a funo cos no tivesse o valor de exacto, e consequentemente no assuma tambm exactamente
atravs da funo o valor zero. O valor obtido est em notao cientca podendo ser aproximado pelo valor zero. Da se conclui que, sob ponto de vista de avaliao de funes, a falha de pouca gravidade.
61
Validao Semntica
Este grupo de testes acusou uma falha na situao de diviso por zero. A falha no se vericou na validao em si mas na forma como o denominador foi simplicado, sendo o primeiro caso da tabela 7.4. Conclui-se que o processo de validao semntica no apresenta falhas da sua responsabilidade.
Qualidade da simplicao
Neste grupo de testes ocorreram 14 falhas nos 42 casos de teste, representando 33%, apresentadas na tabela 7.6:
Avaliado
4 + 3x + x 2 + 5x 2 + 4x + 6
Esperado/Obtido
6x 2 + 7x + 10 10 + 7x + 6x 2
(x 2 + 3x + 4) + 2(5x 2 + 4x + 6)
4 + 3x + x 2
x 2 + 3x + 4 4 + 3x + x 2
(x + 1) (x + 1)
0 x + 1 + ((x + 1))
x 2 + 3x + 4 5x 2 4x 6 + 4x 2 + x + 2
0 0x 2 + 0x
(x + 1)x(x + 1)(x + 2)
(x + 1) 2x(x + 2) (x + 2)x((x + 1) 2)
(x + 1) 2(x + 2)(x + 1) 3
(x + 2)(x + 1) 5 (x + 2)((x + 1) 5)
sen(x)cos(x)sen(x)
sen(x)x cos(x)sen(x) 2
x(x + 1)/x
x+1 (x + 1)x 0
(x + 1)(x + 2)/(x + 1)
x+2 (x + 2)((x + 1) 0)
x (x + 1) + x (x + 1)
2x (x + 1) 2(x (x + 1))
Tabela 7.6
62
Tal como em grupos anteriores, as falhas variam em nvel de gravidade. possvel identicar os problemas recorrentes que afectam a qualidade da simplicao:
Nos polinmios, os monmios no so ordenados por grau; Em produtos e divises, permanecem monmios com expoente zero que deviam ser simplicados para um e desaparecerem do produto;
Em somas, permanecem factores que multiplicam por zero que deviam ser eliminados; Em diferenas de expresses iguais, h casos em que a expresso resultante mais complicada do que a original;
Verica-se a presena de operadores de precedncia redundantes na expresso; Em produtos de funes, a ordem dos factores sempre invertida.
7.2.3 Derivao
Os testes de derivao englobam tambm testes de simplicao. Recorde-se que uma expresso antes de ser derivada simplicada. A expresso resultante da derivada tambm simplicada. Tendo-
se vericado que o processo de simplicao tem algumas falhas importantes, de esperar que os resultados dos testes de derivao apresentem muitas falhas. Por esse motivo, um sub-conjunto inicial desses testes analisa somente as regras de derivao sem simplicao. Os testes que se seguem a esse subconjunto incluem expresses que necessitam de simplicao e originam a derivadas que so tambm simplicadas. Neste grupo de testes ocorreram 28 falhas nos 65 casos de teste, representando 43%. Verica-se que na generalidade estas falhas so as mesmas analisada previamente no processo de simplicao, pelo que sero apenas apresentadas as que se devem exclusivamente ao processo de derivao ou que apresentam novas situaes anmalas no processo de simplicao. Estas falhas so apresentadas na tabela 7.6:
Avaliado
arcsen(x) arcsen(3x 2) arccos(x) arccos(3x 2) 1/(x + 3)
Esperado
1/|(1 + x 2) 6x/|(1 + 9x 4) 1/|(1 x 2) 6x/|(1 9x 4) 1/(x + 3) 2
Obtido
1/((1 + x 2) 0.5) 6x/((1 + 9x 4) 0.5) 1/((1 + x 2) 0.5) 6x/((1 + 9x 4) 0.5) 1/((x + 3) 2)
Tabela 7.7
Os dois primeiros casos apresentam falhas na simplicao. A raiz quadrada avaliada como uma potncia levando a discrepncia nos resultados. Embora o resultado da derivao esteja correcto, no est apresentando da forma mais conveniente, que seria com o operador de radiciao. Os dois casos seguintes representam a nica situao em que o clculo da derivada efectuado de forma errada. A regra de derivao da funo
arccos est implementada de forma diferente da especicao havendo no denominador uma troca do sinal + onde devia estar um sinal . Tal leva construo de uma expresso
63
que no corresponde derivada da funo. O ltimo caso apresenta tambm um erro no clculo. O denominador tem um sinal negativo que no era esperado no resultado. Todas as outras falhas (no includas na tabela 7.7), devem-se exclusivamente a detalhes de simplicao implementados de forma diferente da esperada. Por esse motivo, as derivadas calculadas esto correctas, mas simplicadas de forma diferente ou incompleta, de acordo com as falhas j identicadas no processo de simplicao.
64
Captulo 8
Concluso
Este trabalho tinha vrios objectivos que foram lanando desaos medida que o desenvolvimento avanava. O primeiro deles foi a concepo de uma arquitectura de testes de programas em Haskell. Este objectivo foi atingido atravs da arquitectura de quatro componentes desenhada. A proposta
apresentada neste trabalho constitui um ponto de partida passvel de ser melhorado e implementado com mais funcionalidades. Para atingir este objectivo, foi necessrio efectuar o estudo de uma de testes unitrios. Sendo a linguagem Haskell o mbito do ambiente de testes, a
ter que ser tambm implementada nesta linguagem. Aps alguma pesquisa na internet, foi encontrada a
framework
Um segundo objectivo do trabalho foi a denio de uma estratgia de concepo de casos de teste. A estratgia que melhor se adequa arquitectura desenvolvida a
data driven
que consiste em
executar sempre o mesmo cdigo de teste, fazendo variar apenas a funo a testar e o seu argumento. Para sistematizar e agilizar este processo, desenvolveu-se um dialecto XML, o qual de denominou de HtestML. Este dialecto, no tendo sido inicialmente denido como objectivo, revelou-se a representao mais adequada para a natureza hierrquica da organizao de casos de teste do HUnit 1.0. A concepo de casos de teste obrigou anlise de regras de especicao. Os casos de teste foram concebidos de forma a cobrir essas regras de forma vericar o seu cumprimento. Paralelamente, dada a natureza
dos processos de simplicao e derivao de expresses matemticas, conceberam-se casos de testes destinados a medir a qualidade das expresses produzidas por estes processos. Esta concepo implicou separar os vrios cenrios de criao de expresses em classes de equivalncia para que o nmero de testes fosse o mnimo necessrio para cobrir as regras de especicao. Como objectivo nal, pretendeu-se detectar falhas na aplicao em teste. Foram detectadas algumas falhas, no entanto, reconhece-se que tal tarefa no simples e exigiria um tempo de execuo mais alargado para obter resultados mais completos. A deteco de falhas na aplicao um exemplo
meramente ilustrativo das capacidades da arquitectura de testes. As perspectivas de trabalho futuro incluem o enriquecimento do dialecto HtestML, uma sada de
plain text e melhoramentos ao componente Testador de forma a incluir testes directos em funes com output para IO e tornar a sua execuo mais rpida.
resultados tambm para HtestML em vez de O desenvolvimento deste projecto revelou-se uma tarefa interessante tendo permitido tomar um primeiro contacto com uma ferramenta de teste de
software.
65
Captulo 9
Referncias
Bibliograa:
BURNSTEIN, Ilene -
Practical Software Testing, Springer, 2003 Concepts In Programming Languages, Cambridge University Press, 2003 Haskell, The Craft of Functional Programming, Addison-Wesley, 1996 Frmulas e Tabelas de Matemtica Aplicada,
MITCHELL, John C. -
THOMPSON, Simon -
Stios na web :
http://hunit.sourceforge.net Stio da
framework
HUnit 1.0
66