Testes unitários no MonoDevelop

NetCoders
netcoders
Published in
9 min readMar 30, 2016

Assim como os desenvolvedores que utilizam o Visual Studio com o .NET Framework, aqueles que trabalham com o Mono e o MonoDevelop como IDE também estão aptos a aplicarem as melhores práticas de programação, utilizando as principais bibliotecas e recursos de produtividade.

Neste artigo veremos como realizar testes unitários em projetos C# utilizando o framework NUnit no MonoDevelop em ambiente Linux. Os recursos que veremos aqui habilitam o desenvolvedor a aplicar o TDD (Test-Driven Development) em seus projetos.

Antes de avançarmos para a parte prática, no entanto, é importante conhecer alguns dos conceitos, ferramentas e termos que serão utilizados neste artigo.

Test-Driven Development

Proposto por Kent Beck como uma das práticas da XP (Extreme Programming), TDD é uma técnica de desenvolvimento de software que consiste na realização de ciclos curtos que envolvem a escrita e validação dos testes, a implementação da unidade testada e sua posterior refatoração.

A Figura 1 ilustra o ciclo principal aplicado no TDD.

Ciclo d oTDD

Figura 1. Ciclo do TDD

Uma das características mais marcantes dessa técnica é que os testes são escritos antes mesmo das unidades testadas. Como isso geralmente impede até mesmo a compilação do código, pratica-se implementar a funcionalidade da forma mais simples possível (geralmente apenas a assinatura de um método com retorno padrão qualquer). Este será, então, o primeiro motivo para o teste falhar, pois de fato o código testado não atende aos requisitos para aprovação. Este é o passo 1, em vermelho na figura, ou RED.

Para que o teste passe, o próximo passo é proceder com a correta implementação da unidade que está sendo testada, sem se preocupar inicialmente com as melhores práticas ou com qual seria a melhor forma de escrever aquele código. O objetivo, neste momento, é apenas que o teste seja validado. Aqui temos o passo 2, em verde na figura, ou GREEN.

Uma vez que a unidade está funcionando (um método retornando o valor esperado, por exemplo), pode-se agora refatorar o código inicial a fim de melhorar sua qualidade, aplicando boas práticas de codificação, padrões de projeto, etc. Este é o terceiro passo do ciclo, o azul REFACTOR.

Caso durante a refatoração o código testado, que antes funcionava, passe a falhar, então será necessário corrigi-lo e repetir o ciclo.

Não é o objetivo central deste artigo discorrer detalhadamente sobre o Test-Driven Development, no entanto conhecer estes conceitos principais é importante para que se entenda a forma de utilização do framework NUnit na execução de testes unitários no MonoDevelop.

Mono

O Mono é uma implementação open source e multiplataforma do .NET Framework, construído para permitir que desenvolvedores já acostumados com o .NET pudessem criar aplicações para vários sistemas operacionais sem abrir mão de sua linguagem e framework favoritos.

O projeto está disponível no GitHub e atualmente possui, além de desenvolvedores individuais, empresas que colaboram com seu desenvolvimento, entre elas a Xamarin.

Além de C#, é possível desenvolver com o Mono utilizando outras linguagens, como VB.NET, F# e Java.

MonoDevelop

Para auxiliar os desenvolvedores na criação de seus projetos com o Mono, surgiu o MonoDevelop, um ambiente de desenvolvimento também open source e multiplataforma (disponível para Windows, Mac OS e Linux). Esse IDE conta com suporte a várias das técnicas e recursos presentes no Visual Studio, como itellisense, designer gráfico, gerenciamento de pacotes via NuGet, criação de vários tipos de projetos e com várias linguagens.

O Xamarin Studio, IDE componente do conjunto de ferramentas Xamarin, baseia-se no MonoDevelop e evolui junto com este.

NUnit

O NUnit é um framework para realização de testes unitários disponível para .NET e que pode ser instalado tanto no Visual Studio quando no MonoDevelop. Este framework foi originalmente baseado no JUnit, famoso framework de testes unitários para a linguagem Java.

Esse framework possui classes e métodos que, integrados ao IDE, permitem a realização de testes unitários com base em avaliações dos resultados esperados e dos valores obtidos, reportando os resultados em uma seção específica do ambiente de programação.

TDD no MonoDevelop com NUnit

O primeiro passo aqui será instalar o NUnit no MonoDevelop, o que pode ser feito com a execução do seguinte comando no terminal do Linux:

sudo apt-get install monodevelop-nunit

Em seguida, basta abrir o MonoDevelop e criar um novo projeto. Aqui trabalharemos com uma Class Library, como pode ser visto na Figura 2. Esta escolha se dá porque neste momento apenas implementaremos uma classe cujos métodos serão validados através de testes unitários. Outros tipos de projeto poderiam ser igualmente escolhidos nesta etapa.

Criando projeto Class Library no MonoDevelop

Figura 2. Criando novo projeto do tipo Biblioteca de Classes (Library)

Clicando em Next seremos solicitados a informar um nome e um diretório para o projeto. Basta preencher esses campos, como na Figura 3, e clicar em Next novamente.

Configurando novo projeto

Figura 3. Definição do nome e diretório do projeto

O projeto criado conterá, além dos arquivos de configuração, uma classe chamada MyClass, que renomaremos para CalculadoraSalario, de acordo com a Figura 4.

Estrutura do projeto criado

Figura 4. Estrutura do projeto criado

O próximo passo será adicionar um novo projeto de testes, clicando com a direita sobre a solução e em seguida no menu Add > Add new Project, como mostra a Figura 5.

Adicionando novo projeto à solução

Figura 5. Adicionando novo projeto à solução

Na tela seguinte devemos selecionar o template NUnit Library Project, de acordo com a Figura 6, e clicar em Next. Na tela seguinte, onde será solicitado o nome do projeto, vamos informar “TDDNUnit.Testes” e clicar no botão Create.

Adicionando novo projeto de testes

Figura 6. Adicionando novo projeto de testes

No novo projeto teremos uma classe de testes chamada Test.cs, que renomearemos aqui para TesteCalculadoraSalario, conforme mostra a Figura 7. Essa classe será responsável por executar, neste caso, os testes referentes à classe CalculadoraSalario definida na biblioteca anteriormente.

Estrutura do projeto de testes

Figura 7. Estrutura do projeto de testes

Assim como no Visual Studio, para que um projeto possa acessar o conteúdo de outro, é preciso adicionar uma referência a ele. Para isso, clicaremos com a direita sobre a pasta References do projeto de testes e então em Edit References. Também se pode clicar no botão que aparece na linha de seleção da pasta quando clicamos sobre ela, como mostra a Figura 8.

Adicionando referência à biblioteca de classes

Figura 8. Adicionando referência à biblioteca de classes

Na janela que será aberta devemos ir até a aba Projects, onde estarão listados os projetos da solução aberta, e lá selecionar a biblioteca de classes criada inicialmente. Note também que nessa tela, que aparece na Figura 9, do lado direito, estão listadas as referências já adicionadas por padrão e que nas outras abas é possível selecionar outros assemblies do framework.

Referências do projeto

Figura 9. Referências do projeto

O próximo passo, seguindo o TDD à risca, é escrever o teste (antes mesmo de escrever o método a ser testado). Os testes serão implementados na forma de métodos da classe TestaCalculadoraSalario, marcados com o atributo [Test]. Assim, o primeiro teste é o que consta na Listagem 1.

Listagem 1. Primeiro teste

[Test()]
public void TestarCalculoBonusNormal()
{
CalculadoraSalario calculadora = new CalculadoraSalario();
double bonus = calculadora.CalcularBonus(1000, TipoBonus.Normal);
Assert.AreEqual(100, bonus);
}

Como já era esperado, esse código nem mesmo irá compilar, pois o método CalcularBonus ainda nem existe. Para que possamos executar o teste pela primeira vez, será necessário implementar esse método na classe CalculadoraSalario. O código completo dessa classe pode ser visto na Listagem 2, que inclui um enum utilizado para o cálculo do bônus sobre o salário.

Listagem 2. Classe que será testada

public enum TipoBonus
{
Normal,
Extra,
Especial
}
public class CalculadoraSalario
{
public double CalcularBonus(double salarioBase, TipoBonus tipoBonus)
{
return 0;
}
}
Agora podemos ir ao menu Run > Run Unit Tests (ou pressionar CTRL + T) para que o teste seja executado. A janela Test Results, que fica na parte inferior do editor, será então aberta e nela poderemos ver o resultado da execução dos testes (Figura 10).Como era esperado, o teste falhou, pois o valor esperado é diferente do que foi realmente obtido do método CalcularBonus.
Resultados dos testes que falharam
Figura 10. Resultados dos testes que falharamNo topo dessa janela, como vemos na figura acima, há uma série de botões que permitem habilitar ou desabilitar a visualização dos testes executados, separando-os por categoria, e executar novamente os testes.Seguindo o ciclo proposto para o TDD, vamos agora implementar o método testado, de acordo com a Listagem 3, a fim de que o teste passe sem erros. Porém, neste momento incluiremos apenas o código necessário para fazer esse método  ser aprovado no teste, o que pode precisar de ajustes posteriormente.Listagem 3. Implementando o método para passar no testepublic double CalcularBonus(double salarioBase, TipoBonus tipoBonus)
{
if(tipoBonus == TipoBonus.Normal)
return salarioBase * 0.1;
return 0;
}
Se executarmos os testes novamente, veremos que agora o teste para o bônus normal agora obtém sucesso, como mostra a Figura 11, pois os valores esperado e obtido foram iguais.
Teste bem-sucedido
Figura 11. Teste bem-sucedidoDando continuidade aos testes desse método, escreveremos agora métodos para testar os bônus do tipo Extra e Especial, que devem atribuir um bônus de 20% e 50% sobre o salário base, respectivamente. Os novos testes podem ser vistos na Listagem 4.Listagem 4. Novos testes[Test()]
public void TestarCalculoBonusExtra()
{
CalculadoraSalario calculadora = new CalculadoraSalario();
double bonus = calculadora.CalcularBonus(1000, TipoBonus.Extra);
Assert.AreEqual(200, bonus);
}
[Test()]
public void TestarCalculoBonusEspecial()
{
CalculadoraSalario calculadora = new CalculadoraSalario();
double bonus = calculadora.CalcularBonus(1000, TipoBonus.Especial);
Assert.AreEqual(500, bonus);
}
Quando executarmos o teste novamente veremos que apesar do primeiro continuar passando, os dois novos falham (Figura 12). Isso indica que o método testado ainda não está atendendo a todas as possibilidades esperadas e que precisa ser ajustado.
Novos testes falhando
Figura 12. Novos testes falhandoPara que o método CalcularBonus seja aprovado nos três testes, alteraremos sua implementação para que fique como na Listagem 5, que é uma forma simples para que o funcionamento desejado seja obtido, porém não é necessariamente o melhor código.Listagem 5. Nova implementação do método testadopublic double CalcularBonus(double salarioBase, TipoBonus tipoBonus)
{
if(tipoBonus == TipoBonus.Normal)
return salarioBase * 0.1;
else if (tipoBonus == TipoBonus.Extra)
return salarioBase * 0.2;
else
return salarioBase * 0.5;
}
Dessa vez todos os testes serão aprovados quando executarmos o comando Run Unit Tests novamente, como mostra a Figura 13.
Todos os testes aprovados
Figura 13. Todos os testes aprovadosNeste momento, com todos os métodos aprovados, podemos voltar à classe testada e melhorar sua codificação, aplicando as práticas que mais se adequarem a cada situação para obter um código mais eficiente e esteticamente melhor. Caso após essa refatoração os testes falharem, deve-se então voltar à classe testada e corrigir os erros que foram inseridos, até que todos os testes sejam aprovados novamente.Por se tratar do mesmo framework, desenvolvedores que já utilizaram NUnit no Visual Studio podem aproveitar completamente essa experiência no MonoDevelop, bem como efetuar o caminho inverso. Além disso, pode-se utilizar outros recursos do framework para melhorar a escrita dos testes. Na seção Links, a seguir, podem ser encontrados links para as páginas oficiais de todas as ferramentas utilizadas neste artigo, com suas devidas documentações.Links
Já conhece o Canal .NET? Hangouts periódicos com convidados especiais abordando diversas tecnologias e compartilhando suas experiências, além de artigos e demonstrações ao vivo de programação. Conheça o Canal .NET no YouTube.

--

--