segunda-feira, 6 de julho de 2009

Utilizando o NUnit - Parte 1

Introdução
Neste post demonstrarei como utilizar o NUnit para geração de testes unitários para a plataforma .Net. O NUnit é uma ferramenta muito útil e de fácil utilização, mas antes de descrever o seu funcionamento, comentarei um pouco a respeito de Testes de Software.
Desenvolver software é uma tarefa complexa e, para desenvolver um software com qualidade, é preciso estar atento a diversos fatores como: conseguir capturar requisitos que reflitam a necessidade de negócio, elaborar uma arquitetura flexível e escalável, utilizar um processo que suporte facilmente mudanças e por último, porém não menos importante, é preciso ter um processo de Testes muito bem definido.
O objetivo deste post não é discutir se RUP (Rational Unified Process) é melhor que XP (eXtreme Programming), ou se XP é melhor que MSF (Microsoft Solution Framework), ou se o PMBoK (Project Management Body of Knowledge) é melhor ou pior que Scrum. Até mesmo porque cada método / prática têm o seu lugar em contextos específicos. O ponto que quero enfatizar é a suma importância de ter um processo de Testes bem definido, como ponto chave para o desenvolvimento de software com qualidade. Discussões mais, digamos, calorosas sobre processos ficarão para outros posts. :-)

Processo de Teste
Também não é objetivo deste post entrar em detalhes teóricos de Testes de Software. Farei apenas um apanhado geral do processo e dos tipos de teste que podem ser aplicados no desenvolvimento de um software.
Um modelo bastante utilizado para planejamento e execução de testes é o chamado “V Model” (modelo em “V”). O “V” é para ilustrar como o processo é organizado (ver figura 1). A idéia do modelo é que, à medida que se avança nas atividades do desenvolvimento de um software, planejamos um tipo de teste específico. Seguindo a figura, uma vez que tem-se os requisitos (ou parte deles) definidos, podemos planejar os testes de Aceite (realizados pelo Cliente para validação do software) e de Sistema (realizados internamente, comparando o software desenvolvido com os requisitos definidos). Ao definir os componentes, pode-se planejar os testes de Integração (que focam no funcionamento integrado dos módulos que compõe o software) e, uma vez definidas as classes, procedures e scripts de banco de dados, é possível planejar os testes Unitários (que focam nas unidades de software a serem testadas). Neste post, comentarei sobre o NUnit que, como mencionado, é uma ferramenta utilizada para execução de testes Unitários.
Existem ainda outras abordagens para o processo de software e de testes, como o TDD (Test Driven Development). Em posts futuros, comentarei também sobre isso.


Figura 1: V-Model




Instalando o NUnit
Voltando para o foco principal do post: o NUnit é uma ferramenta “open source”, escrita em C# e pode ser encontrada no link: http://www.nunit.org/. Baixem o instalador através da opção “Download” do site. A versão utilizada neste post é a 2.5.0.9122. Execute o instalador e observe que o NUnit aparecerá no diretório “C:\Arquivos de Programas\NUnit 2.5”, caso as opções padrão não tenham sido alteradas na instalação. Um link para a IDE do NUnit será adicionado no menu “Iniciar à Todos os Programas à NUnit 2.5 à NUnit”. É esta IDE que utilizaremos para execução dos nossos testes unitários (ver figura 2).


Figura 2 – IDE do NUnit




Criando um projeto de exemplo
Neste exemplo, utilizaremos o Visual Studio 2008 como IDE de desenvolvimento, mas as versões 2003 e 2005 também podem ser utilizadas. Crie uma solution em branco e adicione um novo projeto do tipo Class Library. No meu caso, utilizei a linguagem C#.
Neste projeto, modifique o nome da classe “Class1” para “Cliente”, crie dois atributos e as operações básicas de CRUD (“Create” – gravação, “Read” – leitura, “Update” – atualização e “Delete” – exclusão). Veja o código abaixo. Essa será a classe que testaremos, utilizando o NUnit. Notem que não estou preocupado com o conteúdo de cada método.

1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5
6 namespace Cliente
7 {
8 public class Cliente
9 {
10 public Cliente(string nome, string rg)
11 {
12 this.Nome = nome;
13 this.RG = rg;
14 }
15
16 public string Nome { get; set; }
17 public string RG { get; set; }
18
19 public void gravar()
20 {
21 // código para gravação do Cliente...
22 }
23
24 public IList pesquisar()
25 {
26 // código para pesquisa de Clientes...
27 return null;
28 }
29
30 public IList pesquisarPorNome(string nome)
31 {
32 // código para pesquisa de Clientes, dado o nome...
33 return null;
34 }
35
36 public void excluir()
37 {
38 // código para exclusão do Cliente...
39 }
40 }
41 }


Criando um projeto de Testes para ser executado no NUnit
Adicione a solution do Visual Studio um novo projeto do tipo “Class Library” e dê o nome TestesCliente. Adicione uma referência ao projeto “Cliente”, clicando com o botão direito no nome do projeto e escolhendo a opção “Add reference...”. Na guia “Projects”, selecione o projeto “Cliente” e clique em “Ok”.
Criaremos agora um caso de teste neste novo projeto, para testar a inclusão de um novo cliente. Para isso, crie um método que instancie um novo objeto Cliente, atribuindo valores às propriedades Nome e RG e, em seguida, chame a operação gravar, conforme código abaixo.

1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5
6 namespace TestesCliente
7 {
8 public class TestesCliente
9 {
10 public void gravarCliente()
11 {
12 Cliente.Cliente cliente = new Cliente.Cliente("Renato", "12345");
13 cliente.gravar();
14 }
15 }
16 }


Agora, para que essa classe seja testável pelo NUnit, precisamos fazer algumas configurações:

  1. Adicione uma referência à biblioteca do NUnit: clique com o botão direito no projeto TestesCliente à “Add Reference...” à “Browse” à nunit.framework.dll (no meu caso, a DLL encontra-se em “c:\arquivos de programas\NUnit 2.5\bin\net-2.0\tests”);

  2. Adicione a referência ao NUnit na classe (“using NUnit.Framework;” no topo do código);

  3. Adicione o atributo “TestFixture” à classe “TestesCliente”;

  4. Adicione o atributo “Test” ao método “gravarCliente”; e,

  5. Compile a solution.

Pronto! A classe está pronta para ser testada no NUnit! Veja como ficou o código final, depois dessa configuração:

1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using NUnit.Framework;
6
7 namespace TestesCliente
8 {
9 [TestFixture]
10 public class TestesCliente
11 {
12 [Test]
13 public void gravarCliente()
14 {
15 Cliente.Cliente cliente = new Cliente.Cliente("Renato", "12345");
16 cliente.gravar();
17 }
18 }
19 }



Executando os testes via interface gráfica do NUnit
Nesta seção, veremos como executar os testes pela interface gráfica do NUnit.

  • Abra o aplicativo NUnit (pode ser através do atalho do menu iniciar, ou através do diretório de instalação, ambos citados na seção “Instalando o NUnit”);

  • No menu “File”, selecione a opção “Open Project...”;

  • Localize o seu projeto “TestesCliente” (pode ser a DLL ou o projeto do Visual Studio);

  • Repare que o método “gravarCliente” aparece na árvore de testes. Opcionalmente, selecione a opção do menu “View” à “Tree” à “Show CheckBoxes”;

  • Selecione o checkbox do método “gravarCliente”;

  • Clique na opção “Run”;

  • Repare que seu teste foi executado com sucesso.

Veja na figura 3 a execução do teste “gravarCliente”.

Figura 3: execução do teste “gravarCliente”.

Conclusão
É muito fácil utilizar o NUnit para execução de testes unitários. É interessante observar também a facilidade da ferramenta referente aos testes de regressão: caso uma funcionalidade seja alterada, é importante que todos os métodos já existentes sejam testados novamente. Com o NUnit, basta selecionar todos os métodos e executar os testes. Muito simples e extremamente útil para produzirmos software de melhor qualidade.
Para complementar este meu exemplo, sugiro que sejam adicionados outros casos de teste, para testar os demais métodos da classe Cliente.
Outros pontos que explorarei no próximo post:

  • Execução de testes que devem retornar uma Exception;
  • Configuração do Setup de uma classe de teste.

Até lá!

Nenhum comentário:

Postar um comentário