20 mai 2010 @ 19:42 
1 Star2 Stars3 Stars4 Stars5 Stars6 Stars7 Stars8 Stars9 Stars10 Stars (3 votes, average: 10,00 out of 10)
Loading ... Loading ...

Ontem, dia 19 de maio de 2010, realizei minha terceira palestra em universidades, convidado pelo Centro Universitário de Belo Horizonte (UNI-BH).

Em primeiro lugar, gostaria de agradecer a UNI-BH e toda sua administração pelo convite, aos alunos pela paciência e atenção durante toda a palestra, ao meu amigo Junior Braga pela indicação e ao professor Tarcizo José pela ajuda, orientação e apoio durante todo o evento. Agradecimentos também a Fabíola Lara, Marlon Lima e Vanessa Vaz (colegas de trabalho) pela revisão, ao Ricardo Antunes por alguns slides e as nossas “fontes inesgotáveis” de conhecimento como a UFMG e a DFTestes, de onde boa parte do material foi baseado ou estudado.

Gostaria de elogiar a UNI-BH pela iniciativa e pela organização, diversidade e pontualidade do evento, meus parabéns!
O evento contou com outros profissionais e acadêmicos do setor de computação, sistemas e engenharias, como Marcio Sete da Challenge, Leonardo Martins e Charles Fortes da Paiva Piovesan, Gibran Silva da Localiza entre vários outros talentos de Belo Horizonte e região.

O tema da minha palestra foi “Introdução a Automação de Teste de Software”, mas claro que, por envolver alunos de todos os períodos e vários cursos (inclusive fora de TI como Engenharias), a palestra não pôde ser totalmente técnica, e abordamos boa parte do planejamento, elaboração e analise de testes funcionais e não funcionais, que não fazem parte unicamente das atividades de automatização.

Abaixo o Slide:


Abaixo um passo a passo explicando um pouco do que foi comentado durante a palestra (slide a slide):

Inicialmente conversamos um pouco sobre o motivo central da existência de qualquer departamento de qualidade e teste de software, até mesmo dos processos de desenvolvimento. Consideramos a filosofia de que existem diversos tipos diferentes de defeitos, assim como planejamento quando o cronograma não foi realista, análise quando um requisito não é corretamente detalhado no diagrama de atividades, de software quando uma falha é identificada etc. Discutimos sobre o custo que isso pode representar a um projeto e sobre os momentos em que podemos identificar esses defeitos, considerando alguns estudos como o de Boehm sobre o custo dos defeitos e o de Wheeler sobre a distribuição dos defeitos ao longo do projeto de desenvolvimento de software. Mais conteúdo sobre esses temas pode ser encontrado nos posts “Comentários sobre a Semana de Sistemas de Informação 2010 da PUC” e no “Bug is Dead“.

Falamos então, sobre existirem diferentes “técnicas” para aumentar a qualidade de um produto de software. Que nenhuma delas é por si só a verdade absoluta, mas que um conjunto delas, aplicadas nos momentos mais adequados podem aumentar a confiabilidade de que o produto está funcionando adequadamente. Usando a analogia das joaninhas acima (Ladybug em inglês, por isso são representadas como “bugs”, sentido figurado genérico na área de computação para problemas em softwares), podemos considerar que essas diversas técnicas são diferentes inseticidas, e que cada um deles tem maior eficácia contra cada um dos “bugs” que podem existir no processo de desenvolvimento de produtos de software.

Quando o assunto é automação de teste de software, o que estamos fazendo, basicamente, é automatizar a aplicação desse inseticida, ou seja, automatizando o processo de teste de software que tem efeitos principalmente em dois tipos de defeitos: Defeitos de Software e Defeitos de Arquitetura (veremos a frente alguns pontos que justificam essa afirmação). Como o nosso foco será nesse inseticida em especial, discutimos os conceitos e sua evolução de 1979 até os dias de hoje. Com isso eliminamos do escopo de estudo, outras aplicações, como inspeções, revisão estatica de código, etc. Para saber mais sobre os diversos mecanismos que um profissional de teste de software ou qualquer outra pessoa que vise melhorar o produto pode usar, recomendo a leitura do material gratuito do ISTQB, mantido e revisado em português pelo BSTQB que pode ser baixado da seguinte página: http://www.bstqb.org.br/?q=node/12

Falamos bastante sobre os “três fundamentos” ou pilares do teste de software que representam o nosso “GPS”. Conceitos importantes de aliar para entender melhor o escopo da automação em cada nível, as ferramentas e técnicas usadas para cada tipo de teste e os conhecimentos exigidos para cada técnica. Ressaltamos um pouco o conceito definido de caixa branca, preta e cinza, lembrando que a caixa branca ou transparente (também chamada de caixa de vidro por alguns autores, inclusive Glenford Myers, divulgador do conceito) está diretamente relacionada a estrutura do produto, seu código fonte, sua arquitetura e seus recursos em geral, enquanto o teste de caixa preta está relacionado aos seus requisitos, as necessidades que o produto visa solucionar e os testes de caixa cinza são intermédios entre as duas principais técnicas. Um exemplo interessante de teste de caixa cinza pode ser testar com acesso ao banco de dados, mas isso varia de autor para autor.

Como muito bem descrito na palestra “Automação de Testes, Mitos e Verdades” do Elias Nogueira, especialmente no slide 7 (Falsas Expectativas), muitas pessoas acreditam, por diferentes motivos, que automatizar o teste de software vai resolver todos os problemas. Infelizmente, automatização de testes não é a cura do câncer dos nossos projetos de software, primeiramente porque antes de automatizar testes, temos que ter bons testes especificados. Em um artigo da IBM chamado “Traceability from Use Cases to Test Cases” que foi citado em um treinamento/conferência há dois anos atrás, foi apresentada uma estrutura como a descrita abaixo que eu aproveitei por ser muito didática. Nela é apresentado um modelo ainda simples, pois não considera a rastreabilidade entre diferentes necessidades, funcionais e não funcionais, ou seja, testar é uma atividade extremamente analítica, complexa e desafiadora!

Detalhamos também os níveis de teste, explicando o modelo em V que há muitos anos vem sendo usado, e, apesar de não ser o melhor modelo para aplicação de teste de software hoje, continua sendo muito didático e ainda bastante próximo da realidade dos nossos processos de desenvolvimento de software. Chegamos a conclusão também, que momentos diferentes tem objetivos diferentes, consequentemente, planejamento e elaboração próprios, assim como robôs ou modelos de automação diferentes, que serão propostos e explicados mais adiante.

Automatizando Teste de Unidade:

Falamos sobre o conceito de teste de unidade e sobre os diversos itens que podem ser a nossa unidade. Para facilitar o entendimento, definimos a nossa unidade como uma classe, nossa linguagem de programação como Java e nosso framework de desenvolvimento de testes de unidade como o JUnit. Então falamos sobre a relação de cada classe, com seus diversos caminhos ou galhos (ver The Art of Software Tesging, 1979 de Glenform Myers para mais detalhes) que podem ser validados de diversas formas por testes desenvolvidos em qualquer momento, depois da classe, durante a criação da classe ou antes da criação da classe. Comentamos sobre esse último caso em especial, sobre a existência de uma regra chamada “Code the Unit Test First” do XP, que também foi comentado por mim no post “Uma introdução a TDD com JUnit“.

Automatizando Teste de Integração:

Comentamos sobre o escopo de validar a integração entre as unidades (normalmente já testadas). Basicamente, podemos imaginar que com dados validos entrando e sempre retornando valores ou resultados válidos, o que pode ser avaliado com o conjunto de testes de unidade, mas, ainda assim, podem existir defeitos entre esses valores que não foram identificados anteriormente. Nesse ponto é que o teste de integração atua, conferindo a conformidade com os requisitos e tentando identificar problemas na integração entre as unidades do sistema. Testando a comunicação (troca de informação) entre os vários contratos das unidades. Vimos também os três principais modelos descritos no terceiro slide, e recomendei o uso do modelo Bottom up para aplicação de testes de integração de funcionalidade e do modelo top down em testes de integração de desempenho/carga.

Automatizando Teste de Sistema:

Comentamos sobre os testes de sistema serem os primeiros a ser desenhados e usados nas organizações quando começam a ter mais maturidade, obviamente, assim também acontece com a automatização dos testes. Também falamos que é aqui que o Analista de Teste e o Testador atuam com mais frequencia e intensidade, elaborando casos de teste em nível de caso de uso e validando a maior parte dos requisitos do software. Relembramos os comentários feitos no slide “Testar é  muito mais que automatizar” sobre a forma de desenvolver casos de teste baseados em casos de uso e cenários de teste. Para entender um pouco mais sobre o assunto, leia “Um modelo para elaboração de cenários e casos de teste“.

Importante comentar sobre os slides abaixo. As figuras são unicamente ilustrativas e de certa forma até cômicas, mas não quero que você leitor, tenha uma interpretação de que programadores produzem “lixo” nem que sem uma ferramenta de automação o código fica com qualidade inferior. O que quero demonstrar é que quando temos ferramentas de apoio ao nosso processo, podemos melhorar a qualidade de vida e de trabalho de todos os envolvidos no processo de desenvolvimento de software. Nos slides abaixo, quero passar a mensagem que, uma vez que exista um processo definido e aplicado, esse processo por si só, ajuda a melhorar a qualidade do software, mas muitas vezes ele se torna repetitivo, cansativo e pouco desafiador, abaixando a motivação dos envolvidos. Esse cenário é agravado em empresas do seguimento de produtos, pois os colaboradores normalmente podem ficar anos com os mesmos sistemas. Com ferramentas de apoio como as de automatização de testes funcionais, podemos tornar essas atividades mais desafiadoras, eficazes e gerenciáveis, permitindo mais tempo para os desenvolvedores e testadores evoluírem outros aspectos da organização.

Comentamos também sobre a estrutura de teste de sistema usada na maioria das ferramentas de automação de testes, onde desenvolvemos ou gravamos e refinamos vários scripts, e em seguida planejamos uma execução ordenada desses scripts, inclusive selecionando dados específicos de um repositório qualquer.

Automatizando Teste de Aceite:

Entendemos o conceito de teste de aceite, e verificamos que esses testes, normalmente, são do cliente. E o objetivo deles não é nem encontrar defeitos, nem garantir que o software não tenha defeitos, mas sim avaliar o software e ter certeza que esse atende aos requisitos esperados, por isso, esses são testes muito pessoais. Chegamos então a conclusão, que muitas vezes não é interessante ter esses testes automatizados, pois na maioria quase que absoluta dos casos, perderia o valor agregado para o cliente.

Porem, vimos também que existem requisitos não funcionais, que são inviáveis de testar sem a ajuda de ferramentas sofisticadas, assim como os testes de carga e outros relacionados ao desempenho do sistema. Apresentei um exemplo de sumário de informações que podemos coletar nesses testes, para tentar identificar o principal problema no sistema, arquitetura ou ambiente da aplicação, assim como foi demonstrado que um sistema na internet pode ser afetado por inúmeras variáveis, como quantidade de acessos, recursos disponíveis e algoritmos aplicados.

Exemplifiquei com a apresentação de um vídeo contendo a execução de um caso real de automação e expliquei a plataforma utilizada, que também foi explicada no post Comentários sobre a palestra “Técnicas de Teste” na UNA, e pelo mesmo motivo não posso publicá-los na internet :( .

Comentei brevemente sobre a arquitetura dos testes automatizados na plataforma de reuso Praxis, que estudo atualmente na UFMG. Todo o trabalho desenvolvido pode ser baixado através da minha página do Departamento de Ciência da Computação da UFMG http://homepages.dcc.ufmg.br/~camilo ou também através do sítio do professor e criador do praxis, o Prof. Dr. Wilson de Pádua http://homepages.dcc.ufmg.br/~wilson.

Os testes no praxis são realizados de uma forma extremamente automática, e com uma arquitetura tão bem definida, que depois de criar todo o arcabolço do teste, a criação dos casos de teste passa a ser feita através de linhas simples, com vírgulas separando os dados que serão utilizados. Ou seja, os testes podem mudar que você não precisa mudar uma linha de código fonte, apenas os valores de entrada e saída. É claro que um conjunto de conhecimentos e muita prática são necessários para criar e manter os testes antes desse nível de automatização, mas vale ressaltar, que o praxis é um modelo de desenvolvimento de software para fins acadêmicos, logo não são muito reproduzíveis em fábricas e projetos de software. Apesar do praxis ser muito criticado (principalmente por ignorância e pré julgamento), eu acredito que seja o melhor modelo de engenharia de software para se ensinar e aprender (minha opinião). Para saber mais sobre o praxis pode adquirir o livro “Engenharia de Software: fundamentos, métodos e padrões – terceira edição” do Wilson de Pádua.

Assim encerramos, com agradecimentos já citados no início dessa publicação, mas, agradecer a quem nos apóia e nos escuta nunca é demais, por isso agradeço novamente a UNI-BH e aos meus colegas revisores :)

Novamente, muito obrigado pela presença e paciência ao assistir a palestrar e visitar a minha página. Sinto muito não ter reservado alguns minutos a mais para eventuais dúvidas, mas gostaria de ressaltar que estou sempre disponível para quaisquer dúvidas aqui no blog ou por e-mail camilo [at] camiloribeiro [dot] com

Bibliografia:

•Myers, Glenford J. (1979). The Art of Software Testing. John Wiley and Sons. ISBN 0-471-04328-1.
•BOEHM, B.W., 1981, Software Engineering Economics, Prentice Hall.
•WHEELER, D.A., BRYKEZYNSKI, B., MEESON, R.N., 1996, Software Inspections: An Industry Best Practice, IEEE Computer Society.
• PRESSMAN, R.S., 2001, Software Engineering: A Practitioner´s Approach, Fifth Edition, McGraw Hill.
•[ISO9126] ISO/IEC 9126-1:2001, Software Engineering – Software Product Quality
•ISQTQB Glossário de termos usados no Teste de Software Versão 1.0
• Foundation Level ISTQB Syllabus, ISTQB
•PÁDUA FILHO (2003), Wilson. Engenharia de Software – Fundamentos, Métodos e Padrões. 3ª Edição. LTC Editora, 2009.
•RIOS, E., MOREIRA, T., SOUZA, A., CRISTALLI, R . Base de Conhecimento em Teste de Software 2ª Edição. Martins, 2007.
•IEEE Standards Board, “IEEE Standard for Software Unit Testing: An American National Standard, ANSI/IEEE Std 1008-1987″ in IEEE Standards: Software Engineering, Volume Two
•IEEE Std 829-2008.
•IEEE Std 610
• Hetzel, Bill, The Complete Guide to Software Testing, 1993, Ed.2
•CBT-TST110, Computer Based Training TST110 Principals of Software Testing for Testers;
•IEEE729-1983
•NOGUEIRA, Elias. Automação de Teste – Mitos e Verdades, 4° Encontro Mensal ALATS, http://www.slideshare.net/elias.nogueira, 2009
• IEEE Standard Computer Dictionary: A Compilation of IEEE Standard Computer Glossaries; IEEE; New York, NY.; 1990
•MERCI2010, Praxis 3.0 – Wilson de Pádua. http://homepages.dcc.ufmg.br/~wilson/praxis/ 2010
•ZIELCZYNSKI, Peter, Traceability from Use Cases to Test Cases,  http://www.ibm.com/developerworks/rational/library/04/r-3217/ IBM Rational Technical library, 2006

Post to Twitter

Posted By: Camilo Ribeiro
Last Edit: 20 mai 2010 @ 19:42

EmailPermalinkComments (6)
Tags
 02 mar 2010 @ 10:56 
1 Star2 Stars3 Stars4 Stars5 Stars6 Stars7 Stars8 Stars9 Stars10 Stars (9 votes, average: 9,33 out of 10)
Loading ... Loading ...

Testes de unidade são uma realidade cada vez mais próxima das nossas fábricas de software, porem, é uma das coisas que tanto os profissionais de teste quando os profissionais de desenvolvimento desconhecem em sua maioria. Melhor dizendo, conhecer todos conhecem, mas ver funcionando, saber fazer e principalmente acreditar no benefício, não.

É um pouco difícil achar exemplos em blogs, sites ou comunidades de desenvolvimento e/ou testes, principalmente em português, mas um ótimo exemplo da aplicação de testes de unidade usando a ferramenta Visual Studio, para a plataforma .Net, está no excelente post “VSTS – Visual Studio Team System para Testadores – Unit Test” do Gustavo Quezada. No post ele descreve muito bem um resumo sobre o momento dos testes de unidade e também como aplicá-los tecnicamente.

Vou tentar elaborar aqui uma visão baseada em TDD (Test-driven development) usando a solução mais usada para Java, o Framework de testes de unidade JUnit, Desenvolvido por Kent Beck (XP) e Erich Gamma (GoF).

Primeiramente vamos pensar em como deve ser o micro processo para a implementação de TDD em alto nível:
1 – Escrever os Testes
2 – Executar os testes e verificar as falhas
3 – Escrever o código
4 – Rodar os testes para identificar sucesso
5 – Refatorar o código para corrigir defeitos e efetuar melhorias

Agora vamos ver isso funcionando:

1 – Escrever os Testes:
É premissa para a escrita dos testes termos todos os requisitos especificados e detalhados de forma a podemos avaliar os dados de entrada e os resultados esperados. Se você é um analista de teste já deve ter notado uma semelhança. A composição básica do nosso teste de unidade é a mesma dos nossos casos de teste, porem, ao escrever testesde unidade não nos preocupamos com as pré condições, procedimentos de teste e outros detalhes. Nosso objetivo aqui é claro: Fornecer o que a classe que será escrita precisará e receber o que ela nos fornecerá.

Vamos supor que a lista de requisitos da nossa classe é a seguinte:
“O programa deve ler 3 números inteiros. Os três valores serão  interpretados como os comprimentos dos lados de um triângulo. O programa imprime uma mensagem sobre o tipo do triângulo”

Vamos pensar em algumas opções de respostas que podemos ter:
a – Se for isósceles
b – Se for equilátero
c – Se for Escaleno
d – Se a soma de dois lados for igual a do terceiro
e – Se a soma de dois lados for menor a do terceiro

Podemos listar também algumas opções de exceções:
a – Se algum lado for negativo ;
b – Se todos os comprimentos do triânngulo forem zero;
c – Se algum comprimento do triângulo for zero;

Enfim, para isso podemos criar inúmeros casos de teste, mas para esse exercício vamos escrever apenas 14 (quatorze) considerando que o usuário sempre vá entrar com valores numéricos.

Abaixo os “casos de teste” ainda em formato texto:
1 – Triângulo Escaleno
2 – Triângulo Equilátero
3 – Triângulo Isósceles
4 – Triângulo Isósceles
5 – Triângulo Isósceles
6 – Triângulo com Lado Nulo
7 – Triângulo com Lado Negativo
8 – Triângulo cuja soma dos lados A e B é igual a C
9 – Triângulo cuja soma dos lados A e C igual a B
10 – Triângulo cuja soma dos lados C e B igual a A
11 – Triângulo cuja soma dos dois lados menor que a terceiro”}
12 – Triângulo onde todos os lados são Nulos
13 – Triângulo cuja soma dos lados A e B é menor que C
14 – Triângulo cuja soma dos lados B e C é menor que B

Abaixo vamos escrever os dados de entrada o que esperamos com eles usando a seguinte sintax
(entradaA, entradaB, entradaC, resultadoEsperado), sendo que as entradas devem ser inteiros e o resultado uma String
1 – {2, 9, 10,”Escaleno”}
2 – {20, 20, 20, “Equilátero”}
3 – {20, 20, 30, “Isósceles”}
4 – {20, 30, 20, “Isósceles”}
5 – {30, 20, 20, “Isósceles”},
6 – {0, 2, 9, “Lado Nulo”}
7 – {3, -2, 9, “Lado Negativo”}
8 – {5, 6, 11, “Soma dos dois lados igual a terceiro”}
9 – {5, 11, 6, “Soma dos dois lados igual a terceiro”}
10 – {11, 6, 5, “Soma dos dois lados igual a terceiro”}
11 – {5, 6, 12, “Soma dos dois lados menor que a terceiro”}
12 – {0, 0, 0, “Todos os lados Nulos”}
13 – {5, 12, 6, “Soma dos dois lados menor que a terceiro”}
14 – {12, 5, 6, “Soma dos dois lados menor que a terceiro”}

É muito importante entender que o teste de unidade tem menos valor se aplicado após a classe estar escrita, principalmente porque a sua principal finalidade, economizar tempo na implementação da classe deixa de ser aproveitada, ficando somente os testes “de unidade de regressão” para modificações da classe. Portanto, é fundamental escrever os casos de teste antes mesmo que a classe que será testada, para essa atividade, é muito recomendável que o analista de teste e programador trabalhem juntos, pensando em caminhos e entradas que poderão ser usados na futura implementação.

Para escrever o teste vamos precisar do Eclipse e do JUnit.
O JUnit pode ser baixado no link:  http://sourceforge.net/projects/junit/files/junit/ e incluído nas libraries do Java Build Path do projeto do eclipse.

Agora vamos entender o básico dos métodos (notation ) do JUnit:
@RunWith: Quando uma classe tem a notation @RunWith ou estende uma classe com o predecessor com @RunWith, JUnit irá chamar a classe que faz referência para executar os testes em que a classe em vez de o corredor construído em JUnit. Podemos implementar uma Suite de Testes com o parâmetro Suite.class ou uma lista de parâmetros com o parâmetro Parameterized.class (que será usada no nosso exemplo).

@Parameters: A notation de um método que cria uma coleção, array, lista ou outra estrutura de dados, de forma a garantir que não precisemos de vários métodos para executar uma sequencia ordenada de testes, através de uma sequencia de parâmetros que serão enviados, um a um, para o construtor da classe ao instânciar um objeto (teste).

@Test: A notation do método que realiza o teste. Normalmente esse método instância o objeto da classe que será testado e realiza comparações.

org.junit.Assert.*: Os métodos de comparação. realizam várias comparações como mostrado abaixo:
assertTrue : Verifica se o valor de retorno é true
assertFalse : Verifica se o valor de retorno é false
assertEquals : Compara dois valores de retorno
assertNotNull : Verifica se o valor de retorno não é null
assertNull : Verifica se o valor de retorno é null
assertSame : Confere se dois objetos referenciam o mesmo objeto
assertNotSame : Confere se dois objetos referenciam objetos diferentes
fail : usado para criar falha no teste via programação do teste

Para a lista completa dos métodos assert: http://www.junit.org/apidocs/org/junit/Assert.html
API completa do JUnit: http://www.junit.org/apidocs/

Agora vamos ver a classe de teste desenvolvida com base nos nossos dados de entrada e devidamente comentada para facilitar o entendimento:


// Importamos as classes que precisamos para usar os métodos citados

// Importante importar essa como static, pois usamos os métodos estáticos para realizar as comparações.
import static org.junit.Assert.*;
import java.util.Arrays;
import java.util.Collection;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

/* Usar o RunWith informando que vamos usar uma classe parametrizada.
*  Isso fará com que ao ser instanciada como JUnit Test, a classe crie um objeto usando os parâmetros informados
*  no método Parameters para realizar cada teste, economizando dezenas de linhas de código.
*/
@RunWith(Parameterized.class)

//Declaramos uma classe normal
public class TesteExemplo {

// Declaramos os inteiros que representarão os lados do triângulo
private int a;
private int b;
private int c;

// Declaramos a string que representará o resultado esperado
private String tipo;

// Criamos o construtor que receberá os parâmetros para execução do teste
public TesteExemplo(int a, int b, int c, String trianguloEsperado) {
super();

// Cada lado do triângulo recebe um valor que vem dos parâmetros da classe
this.a = a;
this.b = b;
this.c = c;

// O resultado esperado recebe o ultimo parâmetro
this.tipo = trianguloEsperado;
}

// Método que retorna uma coleção com os parâmetros que serão usados no construtor instânciado para os testes
@Parameters
public static Collection carregaTriangulosDeTeste(){
return Arrays.asList(
new Object [][]{

// Como array em Java começa no 0, vamos incluir o teste 1 na posição 0 do array e assim por diante

//Test0
{2, 9, 10,"Escaleno"},

//Test1
{20, 20, 20, "Equilátero"},

//Test2
{20, 20, 30, "Isósceles"},

//Test3
{20, 30, 20, "Isósceles"},

//Test4
{30, 20, 20, "Isósceles"},

//Test5
{0, 2, 9, "Lado Nulo"},

//Test6
{3, -2, 9, "Lado Negatívo"},

//Test7
{5, 6, 11, "Soma dos dois lados igual a terceiro"},

//Test8
{5, 11, 6, "Soma dos dois lados igual a terceiro"},

//Test9
{11, 6, 5, "Soma dos dois lados igual a terceiro"},

//Test10
{5, 6, 12, "Soma dos dois lados menor que a terceiro"},

//Test11
{0, 0, 0, "Todos os lados Nulos"},

//Test12
{5, 12, 6, "Soma dos dois lados menor que a terceiro"},

//Test13
{12, 5, 6, "Soma dos dois lados menor que a terceiro"},
}
);

}

// Método que executa o teste a cada instanciação do objeto da classe teste
@Test
public void validaTriangulo() {
// Vamos criar um objeto do tipo Trianglulo (nossa futura classe que ainda vai existir) e passar os parâmetros do seu construtor
Triangulo escalenoValido = new Triangulo(a, b, c);

// Realizamos a comparação entre o valor que foi retornado e o valor que é esperado
assertEquals(escalenoValido.retornarTipo(), tipo);
}
}

2 – Executar os testes e verificar as falhas

Agora vamos executar a primeira vez e verificar o que o JUnit nos retorna:

É importante que todos os testes falhem, para termos certeza que estão corretos (irônico não?). Isso porque os resultados esperados não podem existir, já que nem a classe do objeto que vamos testar existe.

3 – Escrever o código

Agora vou escrever uma classe com alguns erros de lógica e outros no conteúdo da resposta:

public class Triangulo {

private int a, b, c;

public Triangulo(int a, int b, int c) {
this.a = a;
this.b = b;
this.c = c;
}

public String retornarTipo() {

// erro de lógica
if((this.a == 0) || (this.b == 0) || (this.c == 0))
return "Todos os lados Nulos";

if((this.a == 0) || (this.b == 0) || (this.c == 0))
// Erro no retorno
return "Lado Núlo";

if((this.a < 0) || (this.b < 0) || (this.c < 0))
return "Lado Negatívo";

if((this.a == this.b) &amp;amp;amp;amp;amp;amp;amp;amp;&amp;amp;amp;amp;amp;amp;amp;amp; (this.b == this.c))
return "Equilátero";

if(
((this.a != this.b) &amp;amp;amp;amp;amp;amp;amp;amp;&amp;amp;amp;amp;amp;amp;amp;amp; (this.b == this.c))||
((this.a == this.b) &amp;amp;amp;amp;amp;amp;amp;amp;&amp;amp;amp;amp;amp;amp;amp;amp; (this.b != this.c))||
((this.a == this.c) &amp;amp;amp;amp;amp;amp;amp;amp;&amp;amp;amp;amp;amp;amp;amp;amp; (this.b != this.c))
)
// Erro no retorno
return "Isóceles";

if( (this.a + this.b == this.c)||
(this.b + this.c == this.a)||
(this.c + this.a == this.b)
)
return "Soma dos dois lados igual a terceiro";

if( (this.a + this.b < this.c)||
(this.b + this.c < this.a)||
(this.c + this.a < this.b)
)
return "Soma dos dois lados menor que a terceiro";

if((this.a != this.b) &amp;amp;amp;amp;amp;amp;amp;amp;&amp;amp;amp;amp;amp;amp;amp;amp; (this.a != this.c))
return "Escaleno";

return null;
}
}

4 – Rodar os testes para identificar sucesso

Agora vamos verificar a nova execução do testede unidade:

Na imágem acima  podemos ver que o teste nos retorna três informações muito importantes:
1 – Quantos casos de teste de unidade passaram;
2 – Quais casos de teste de unidade passaram;
3 – Qual a diferença entre o resultado esperado e o resultado recebido

Essa ultima informação em especial é que dá o “caminho das pedras” para o desenvolvedor corrigir com maior facilidade.

5 – Refatorar o código para corrigir defeitos e efetuar melhorias

Efetuamos as melhorias:


import static org.junit.Assert.*;
import java.util.Arrays;
import java.util.Collection;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
@RunWith(Parameterized.class)

public class TesteExemplo {

private int a;
private int b;
private int c;

private String tipo;

public TesteExemplo(int a, int b, int c, String trianguloEsperado) {
super();
this.a = a;
this.b = b;
this.c = c;
this.tipo = trianguloEsperado;
}

@Parameters
public static Collection carregaTriangulosDeTeste(){
return Arrays.asList(
new Object [][]{
//Test0
{2, 9, 10,"Escaleno"},

//Test1
{20, 20, 20, "Equilátero"},

//Test2
{20, 20, 30, "Isósceles"},

//Test3
{20, 30, 20, "Isósceles"},

//Test4
{30, 20, 20, "Isósceles"},

//Test5
{0, 2, 9, "Lado Nulo"},

//Test6
{3, -2, 9, "Lado Negatívo"},

//Test7
{5, 6, 11, "Soma dos dois lados igual a terceiro"},

//Test8
{5, 11, 6, "Soma dos dois lados igual a terceiro"},

//Test9
{11, 6, 5, "Soma dos dois lados igual a terceiro"},

//Test10
{5, 6, 12, "Soma dos dois lados menor que a terceiro"},

//Test11
{0, 0, 0, "Todos os lados Nulos"},

//Test12
{5, 12, 6, "Soma dos dois lados menor que a terceiro"},

//Test13
{12, 5, 6, "Soma dos dois lados menor que a terceiro"},
}
);

}
@Test
public void validaTriangulo() {
Triangulo escalenoValido = new Triangulo(a, b, c);
assertEquals(escalenoValido.retornarTipo(), tipo);
}
}

Agora efetuamos as melhorias necessárias e re-executamos os casos de teste até que todos passem:

Esse foi um exemplo de implementação de teste de unidade ou teste de unidade inspirados em TDD, prática ágil muito eficaz na identificação de defeitos. Nem todas as implementações são tão fáceis, ou gastam pouco tempo, mas, com o tempo e alguma prática, esse tipo de atividade pode se tornar menos custosa e mais eficiente.

Peço desculpas se algum conceito apresentado acima está divergente das melhores práticas ou de algum padrão ou conceito, e me prontifico a efetuar quaisquer correções. O exemplo citado aqui é ilustrativo.

TDD, testesde unidade, automação de testes funcionais e de performance, entre outras áreas das disciplinas de Teste de Software e Arquitetura de Software ainda são muito misteriosas e discutidas, mas pouco implementadas, principalmente aqui no Brasil. Porem, é muito importante que nossos analistas de teste busquem essa capacitação técnica para melhorar a nossa posição no mercado, melhorar a qualidade do software e da mão de obra brasileira e acabar com mitos como “o desenvolvedor é um profissional mais estudioso ou mais técnico do que o teste” ou “teste é uma atividade simples de clicar e executar alguns fluxos”.

Mantenho-me disponível para quaisquer esclarecimentos

Essa atividade é baseada em um exercício em sala no curso de Especialização em Ciência da Computação com Ênfase em Engenharia de Software da Universidade Federal de Minas Gerais (UFMG) .

Bons Testes :)

Creative Commons License

This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License.

Post to Twitter

Posted By: Camilo Ribeiro
Last Edit: 16 mar 2010 @ 09:55

EmailPermalinkComments (11)
Tags
 15 out 2009 @ 1:29 
1 Star2 Stars3 Stars4 Stars5 Stars6 Stars7 Stars8 Stars9 Stars10 Stars (2 votes, average: 10,00 out of 10)
Loading ... Loading ...

Meio estranho o título para um blog de tecnologia não?

Mas o ET que estou falando não é o nosso popular amigo de dedo brilhante, nem os assustadores (pelo menos eram para ser) monstros de Hollywood.

et4

Estou falando de um papel que muitas vezes não é explícito nos nossos processos e que se fosse mais explícito e mais valorizado, nossos processos de produção de software seria muito beneficiado.

O papel de Engenheiro de Testes ou Arquiteto de Teste é um papel no mínimo recomendado para que um projeto de produção de software seja entregue com padrões satisfatórios de qualidade.

A necessidade desse papel está diretamente vinculada a complexidade dos requisitos, especialmente dos requisitos não funcionais e do ambiente do sistema.

Se pesquisarmos no glossário do ISTQB, não temos uma declaração explicita para esse papel, nem mesmo nos Syllabus, mas o RUP descreve um pouco desse papel com o nome de Designer de Teste com a seguinte definição:
Designer de Teste: Essa função é responsável por definir a abordagem de teste e assegurar sua correta implementação. Isso inclui identificar as técnicas, ferramentas e diretrizes apropriadas para implementar os testes necessários e fornecer orientação sobre os correspondentes requisitos de recursos para o esforço de teste.Em algumas culturas em desenvolvimento, essa função é referida como Arquiteto de Teste, Arquiteto de Automatização de Teste ou Especialista em Automatização de Teste.

rup
Mas para o RUP, esse profissional ainda está muito vinculado a automação de teste, o que de certa forma é verdade se levarmos em consideração que a maioria dos testes de requisitos não funcionais estão ligados a automação.

Mas e se pensarmos no papel de Engenheiro/Arquiteto de Testes como uma versão do ponto de vista de Controle de Qualidade do arquiteto de Software?

A definição do Arquiteto de Software segundo o RUP é:
->Essa função orienta o desenvolvimento da arquitetura de software do sistema, que inclui promoção e criação de suporte para as principais decisões técnicas que limitam o design e a implementação gerais para o projeto.

Logo o nosso Arquiteto de Testes seria um profissional responsável por boa parte das decisões técnicas do como os testes devem ser realizados. O profissional responsável por escolher as ferramentas mais adequadas, treinar a equipe que irá executar e desenvolver os casos de teste, ajudar na definição de uma massa de teste, selecionar o formato das suítes de teste, definir o nível de detalhamento dos casos de teste, ajudar a definir a complexidade e prioridade de cada caso de teste, entre outras atribuições.

Super Businessman bxp156008h

Quem se habilita a ser um Engenheiro de Testes? Ou melhor, o que é preciso para ser um BOM engenheiro de testes?

•O Engenheiro de Teste assim como o Arquiteto de Software é um profissional que está acima de qualquer Tecnologia, Metodologia ou Suíte de Ferramentas. não tem “religião”. Deve ser neutro, calculista e possuir vasta experiência em todas essas verticais. Um profissional que domine bem a poderosa suíte de ferramentas de engenharia de software da IBM Rational não é simplesmente por esse fator um profissional habilitado em testes de performance, modelagem de dados, engenharia de requisitos e etc. O mesmo se aplica a um profissional que acredita que uma metodologia, seja ela RUP, SCRUM ou qualquer outra, é a melhor em todos as ocasiões. Para um Engenheiro de Testes não existe o melhor universal, existem opções que podem ser combinadas para cada modelo de projeto. Ele acredita na idéia de um projeto ser uma entidade viva, com características próprias, as vezes únicas, que devem ser estudadas, entendidas e suas soluções arquiteturadas e aprovadas por provas de conceitos.

•O Engenheiro de Testes tem vivencia em muitos projetos, dos mais diferentes tipos, de “simples” sistemas de padaria, catraca e controle de acesso a portais eletrônicos de compra, sistemas de bilhetagem e controladores de vôo por exemplo.

•O Engenheiro de Teste é um estudante assíduo das novas tecnologias, de TODAS as disciplinas de engenharia de software, do mercado de fornecedores de ferramentas de teste dos mais diversos e sua pedra angular é a Engenharia de Software.

•O Arquiteto de Testes programa tão bem quanto um desenvolvedor e tem uma excelente capacidade de compreensão de requisitos, assim como possui uma ótima capacidade de identificar requisitos não-funcionais, compreende-los e examinar as soluções propostas de forma crítica e analítica.

•O Engenheiro de Testes é um profissional proativo, crítico por natureza, visionário e ousado. A missão dele deve ser a integridade da qualidade para o SISTEMA e não somente para o SOFTWARE.

•O Engenheiro de Testes é um profissional criativo e oportunista, vislumbra soluções inteligentes em teste para cada tipo diferente de produto de software.

•Deve ter espírito de liderança e ter uma excelente desenvoltura ao lidar com pessoas, ser organizado, metódico e sistemático.

Um artigo que achei muito interessante tratando da relação entre Arquiteto e Líder técnico é o artigo The Seven Leg Sheep do Gerrit Muller, que descreve as macro e micro categorias de características técnicas que um profissional nesses papeis possui. Uma versão crítica em português muito boa está disponível em http://blog.arkhi.com.br/2008/11/03/a-ovelha-de-sete-pernas/.

Acredito que a mesma relação feita nesse artigo também é valida para Engenheiro de Teste e Coordenador de Teste, como na figura abaixo que representa uma relação Arquiteto de Software X Líder Técnico.

perfilarquitetovslider

Quanto mais uma empresa investe em teste, mais ela investe em qualidade, não só do produto, mas também das suas pessoas, dos seus processos, consequentemente na qualidade da sua imagem e dos seus clientes. Uma equipe de teste de software pode trazer ganhos fantásticos, conhecimento partilhado, melhoria continua de processos, novas formas de fazer atividades, novas ferramentas etc. Após uma quantidade X de investimento em testes Funcionais, uma empresa de médio porte já começa a ter projetos que exigem novos padrões de qualidade e cada vez mais os requisitos não funcionais tem sido fator de falha em excelentes projetos de software com poucos “bugs”.

Engenharia de Teste de Software já existe, implicitamente em todos os projetos. A questão é que quando tornamos isso explicito ganhamos uma nova forma de garantir que os requisitos como um todo sejam atendidos, temos um processo de teste sob medida (ou pelo menos mais realista) para o projeto e consequentemente temos um produto com uma qualidade mais próxima do esperado.

Creative Commons License This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License.

Post to Twitter

Posted By: Camilo Ribeiro
Last Edit: 10 fev 2010 @ 22:14

EmailPermalinkComments (2)
Tags
Categories: Arquitetura, Carreira

 Last 50 Posts
 Back
Change Theme...
  • Users » 1
  • Posts/Pages » 35
  • Comments » 105
Change Theme...
  • VoidVoid « Default
  • LifeLife
  • EarthEarth
  • WindWind
  • WaterWater
  • FireFire
  • LightLight

Sobre



    No Child Pages.

Oportun.



    No Child Pages.