2. TDD x TESTES DE UNIDADES–
parte 1
O
material a seguir foi
extraído da DevMedia,
artigos digitais e
complemetado.
3. Testes de Unidades–
Conceito e Prática com NUnit
De que se trata o artigo
Este artigo trata de conceitos que estão relacionados direta ou
indiretamente com testes de unidades. Veremos a definição,
como funcionam e como criar testes de unidades para seus
projetos. Além disso, abordaremos os mitos comuns e
mostraremos na prática como criar seus primeiros testes com o
framework NUnit.
Em que situação o tema é útil
Este tema é útil na garantia da qualidade dos projetos de software.
Com testes de unidades bem definidos e implementados, você
consegue identificar e corrigir erros em tempo de desenvolvimento,
você aumenta a confiança da equipe e do cliente no projeto,
consegue-se aumentar a produtividade da equipe, além de
identificar quais os pontos de seu sistema que possuem maior risco
de incidência de exceções, através da análise da cobertura dos
testes.
Resumo Devman Testes de
Unidades- Primeiros Passos: Neste
artigo começaremos com a parte
conceitual, explicando o que são
testes de unidades , onde podem ser
aplicados, além de discutirmos alguns
mitos que cercam este assunto, por
exemplo, a questão da produtividade e
custo de implementação de testes de
unidades. Vencida esta fase
partiremos para um esclarecimento
sobre as diferenças entre testes de
unidades e TDD. Daí então
entraremos na parte mais prática com
a criação de exemplos de testes de
unidades usando o NUnit
4. Testes de Unidades– Conceito e Prática com NUnit
A indústria de software, assim como as demais, possui diversas técnicas e metodologias empregadas para garantir a qualidade e o
bom funcionamento do mesmo. Por exemplo, testes funcionais, testes de carga etc.
Enfim, existe uma infinidade de tipos e técnicas de testes de software, cada uma com o seu propósito. Alguns destes testes devem
ser executados por “testes”, outros por usuários comuns e outros pelo próprio desenvolvedor, como é o caso do teste de unidade ,
que veremos neste artigo.
Testes de Unidades
Testes de unidades e TDD são coisas diferentes
O teste de unidade é o teste de menor nível no desenvolvimento
Um equívoco muito comum que vejo as pessoas
de software, ou seja, com ele testamos as menores estruturas que
cometerem no início de seus estudos sobre testes de
temos em nossos softwares, que são os métodos. Sendo assim,
unidades é a confusão com TDD. No início muita
quando estamos falando de testar unitariamente o software,
gente acha que escrevendo testes de unidades está
estamos falando em criar métodos para testar os comportamentos
desenvolvendo orientado a testes.
de nosso sistema. Por exemplo, se temos um método somar,
teríamos o método de testes “somarTest”.
TDD é mais do que uma técnica, é um processo de
Quando escrevemos um teste de unidade para um método,
desenvolvimento onde todo código novo da aplicação
desejamos garantir que o comportamento do mesmo seja
é escrito a partir de um teste falho, ou seja, você
exatamente como o esperado nas mais variadas possibilidades. A
primeiro escreve um teste sem que exista o recurso,
ideia é pegar os bugs logo que eles nasçam. Além disso, o teste de
este teste obviamente falhará, somente então você
unidade se torna um ativo do projeto, ou seja, pode ser reutilizado
escreve a implementação do recurso.
e executado diversas vezes sem onerar o seu tempo.
5. Testes de Unidades– Conceito e Prática com NUnit
Este processo possui três passos simples, conhecidos
como Red, Green, Refactor, onde:
• Red: você escreve o teste sem existir o código. Logo ele
falhará.
• Green: implementa a solução, escrevendo o código
necessário para que o teste passe.
• Refactor: refatora a solução dada no item dois, de acordo
com as boas práticas de programação.
Enquanto testes de unidades têm como objetivo principal
garantir que cada parte do sistema tenha exatamente o
comportamento esperado, o TDD tem como motivação
principal o design do código. Um dos grandes benefícios
do uso do TDD é o design da solução. Quando se pensa
na ótica do consumidor do código antes mesmo do código
existir, você se obriga a pensar e avaliar as melhores e
mais simples formas de implementação da solução, o que
traz um grande benefício para o design da solução.
Nota Devman 1: Refatoração é uma boa prática
de desenvolvimento que consiste em uma série de
técnicas para melhorar a qualidade e legibilidade
do código sem afetar o comportamento conhecido
do sistema.
Pois bem, é preciso entender que testes de
unidades e TDD estão intimamente relacionados,
porém são coisas bem diferentes. O fato de você
usar testes de unidades não significa que você use
TDD.
Uma das diferenças chaves, é a ótica do tempo em
que são realizados os testes. Se você implementa
seu código e depois cria seus testes, você
simplesmente usa testes de unidades. Agora, a
partir do momento em que você começa a escrever
seus testes antes mesmos de implementar a
solução que eles testarão, aí você está mais
próximo do TDD.
Porém, o ponto fundamental é a motivação das
duas técnicas
6. Testes de Unidades– Conceito e Prática com NUnit
Mitos dos testes de unidades
Assim como diversas outras técnicas, os testes de unidades
são alvos de críticas que na verdade não passam de mitos.
Alguns destes mitos são:
• Implementar testes de unidades é muito caro: Esta opinião
normalmente vem de quem pensa que será necessário ter
uma equipe de desenvolvedores de testes de unidades , que
farão praticamente outro projeto só de testes ou da visão de
que precisa-se de ferramentas muito caras para fazer este
tipo de testes e que automatizar os mesmos custa uma
fortuna.
Na prática não é isso que acontece quem escreve os testes
de unidades são os próprios desenvolvedores que
desenvolvem a solução e existem diversas frameworks free
e open-source para a criação e automatização de testes de
unidades .
• Testes de unidades impactam o cronograma do
projeto: Isto só é verdade quando a equipe está
no início da adoção dos testes de unidades ,
porém isso não é um privilégio, qualquer técnica
ou prática que a equipe ainda não detenha
conhecimento, fará com que o tempo seja
estendido, porém essa é uma fase temporária,
quando a equipe já tem uma certa maturidade no
desenvolvimento de testes, estes não impactam
no cronograma do projeto.
Nota Devman 2: Quando nos referimos a
design da solução, não estamos nos
referindo à parte estética, mas sim na
parte arquitetural, na forma como os
elementos do projeto, os objetos, se
comportam e colaboram entre si.
7. Testes de Unidades– Conceito e Prática com NUnit
• A equipe fica mais improdutiva, pois tem uma tarefa
adicional a fazer: Bom, para quebrar este mito vamos
analisar a rotina tradicional de um desenvolvedor para
criar, por exemplo, uma tela de cadastro. Criam-se as
classes do modelo, implementa-se as regras de negócio,
criam-se as classes de persistência, daí, cria-se a interface
com o usuário e somente então testa-se tudo o que foi
desenvolvido.
Inclusão, alteração, exclusão, validações de campos,
regras de negócio etc. Agora vamos analisar este
processo de testes manuais do desenvolvedor, rodamos a
aplicação, acessamos o recurso, preenchemos o
formulário e então clicamos em gravar para avaliar se o
comportamento foi como esperado. É comum as coisas
não funcionarem de primeira, então percebemos que falta
um ajuste. Vamos ao código, acertamos, executamos de
novo a aplicação, acessamos o recurso, preenchemos o
formulário etc.
Já parou para pensar no tempo que se gasta com este
processo “Executa, simula, verifica, corrige...”, quantas
vezes ele é executado no seu dia a dia? E se amanhã
for feita uma alteração no requisito, você repetirá isso
mais N vezes. Sem contar que ao longo do
desenvolvimento você acaba se perdendo nos cenários
em que já testou, faltando sempre testar um cenário
específico. Vejamos com testes de unidades . Você cria
o modelo e suas regras de negócio, cria os testes para
eles, executa. Se passar, parte para o próximo passo e
programa a persistência e seus respectivos testes e
assim sucessivamente. Quando você for realizar um
teste do recurso todo, as pequenas partes já estarão
validadas e os ajustes serão muito menores a se fazer.
Se amanhã alterarem um requisito, você altera o
sistema e roda os testes (que já estão escritos).
8. Testes de Unidades– Conceito e Prática com NUnit
Revisa apenas os testes necessários sem ter que refazer
toda a bateria de testes do cenário anterior. Outro ponto que
não percebemos, mas que nos toma muito tempo e, com os
testes de unidades diminuímos consideravelmente, é a
realização de Debug. Colocando isso tudo na ponta do lápis,
você verá que a produtividade final da equipe tende a
aumentar com a prática de testes de unidades .
• Tenho testes de unidades , tenho qualidade e não preciso
de mais nada: Vamos lá, não existe bala de prata em
desenvolvimento de software. Na verdade existe, a
verdadeira bala de prata no desenvolvimento de software é o
bom censo. Em testes, vale a mesma regra. Testes de
unidades têm seu escopo limitado, eles não garantem a
qualidade total do sistema, mas ajudam a pegar e prevenir
bugs e garantir que as pequenas partes do sistema façam
exatamente aquilo que se espera.
Um problema que pode ocorrer, é que com o teste
de unidade você garante que cada parte faz seu
trabalho como deveria ser feito, mas isso não lhe
garante que quando você juntar todas as partes não
haverá algum tipo de conflito não previstos. Além
disso, requisitos como usabilidade e acessibilidade
não podem ser validados com testes de unidades
. Sendo assim, o uso dos mesmos não descarta a
necessidade de outros testes como funcional,
aceitação, integração, dentre outros.
Nota Devman 3: Frameworks são
bibliotecas de classes altamente
reutilizáveis, que juntas, colaboram entre
si para atender uma demanda específica
de parte de um software. Por exemplo,
Frameworks de persistência e Frameworks
de Inversão de Controle.
9. Testes de Unidades– Conceito e Prática com NUnit
Como funcionam os testes de unidades
Conforme citamos anteriormente, o teste de unidade se aplica a menor unidade comportamental que você tem em
seus projetos, os métodos. Quando estamos realizando um teste de unidade, queremos garantir que um determinado
método tenha exatamente o comportamento que esperamos dele, de maneira geral os testes consistem em criar
objetos, alimentá-los com determinados valores, executar determinados métodos e verificar se o resultado é igual ao
valor esperado.
Imagine um método somar da classe OperacaoMatematica. Suponhamos que o método somar receba dois
parâmetros, valor1 e valor2 e retorne o resultado da soma. Em nosso teste, instanciaríamos um objeto da classe
OperacaoMatematica e em seguida chamaríamos o método somar deste, passando dois valores quaisquer, por
exemplo “5” e “3”. Após chamar o método, verificaríamos se o retorno foi “8”. Caso tenha sido, consideramos que o
teste de unidade passou, caso contrário assumimos que ele falhou.
10. Testes de Unidades– Conceito e Prática com NUnit
Criando aplicação de exemplo
A prática de testes de unidades é independe de
tecnologia, portanto, não faz diferença se seu
projeto é em Windows Forms, Web ou WCF. Para
fins didáticos usaremos apenas uma aplicação
Windows Forms. Em nosso exemplo criaremos um
cenário onde teremos três classes de domínio, que
serão Cliente, Pedido e ItemPedido. Além disso,
teremos um tipo enumerado para representar a
categoria de cada cliente. Teremos ainda uma regra
simples de desconto por categoria de cliente.
Para criar nosso projeto de exemplo, abra o Visual
Studio, opção File => New Project => Windows
Forms Application, conforme mostra a Figura 1.
Figura 1