NUnit
Testes na camada de dados
0Olá pessoal, vamos falar sobre a qualidade e ROI de testes para a camada de dados.Estava escrevendo uns testes para um projeto e reparei que os testes não me traziam ROI algum. Segue o código de exemplo, acho que vocês vão entender.
O problema!
Interface de repositório
1: /// <summary>
2: /// Repositorio para o tipo ObjectSummary
3: /// </summary>
4: public interface IObjectSummaryRepository
5: {
6: /// <summary>
7: /// Recupera um objectSummary de acordo com o cdObj
8: /// </summary>
9: /// <param name="cdObj"></param>
10: /// <returns></returns>
11: ObjectSummary GetObjectSummary(Int32 cdObj);
12: }
Segue uma implementação SQL do Repositório
1: internal class ObjectSummarySQLRepository : IObjectSummaryRepository
2: {
3: private const string TABLE = "ObjectSummary";
4: QueryManager queryManager;
5:
6: public ObjectSummary GetObjectSummary(int cdObj)
7: {
8: StringBuilder sbSQL = new StringBuilder();
9: sbSQL.AppendLine("SELECT cdObj, dsTitle, dsSubtitle, obsSummary, nmFile, idLstRecipient, cssClassLogoClientCover,");
10: sbSQL.AppendLine(" cssClassLogoASKCover, cssClassLogoClientDetail,cssClassLogoASKDetail, footer, flgShowFooterInCover, idGru");
11: sbSQL.AppendLine(" FROM ObjectSummary WITH(NOLOCK) where cdObj=@cdObj ");
12: String sqlCommand = sbSQL.ToString();
13:
14: NameValueCollection sqlParams = new NameValueCollection();
15: sqlParams.Add("@cdObj", cdObj.ToString());
16: return ConvertRowToEntity(queryManager.FetchSingleObject(sqlCommand, sqlParams).Rows[0]);
17: }
18: }
Uma implementação fake do repositório para testar em memória
1: public class ObjectSummaryFakeRepository : IObjectSummaryRepository
2: {
3: public ObjectSummary GetObjectSummary(int cdObj)
4: {
5: if (cdObj == 1)
6: {
7: ObjectSummary objectSummary = new ObjectSummary();
8: objectSummary.ObjectSummaryID = 1;
9: objectSummary.CssClassLogoASKCover = "CssClassLogoASKCover";
10: objectSummary.CssClassLogoASKDetail = "CssClassLogoASKDetail";
11: objectSummary.CssClassLogoClientCover = "CssClassLogoClientCover";
12: objectSummary.CssClassLogoClientDetail = "CssClassLogoClientCover";
13: objectSummary.FileName = "FileName";
14: objectSummary.Footer = "Footer";
15: objectSummary.GroupID = 1;
16: objectSummary.ListRecipientID = 1;
17: objectSummary.ShowFooterInCover = true;
18: objectSummary.SubTitle = "SubTitle";
19: objectSummary.Summary = "Summary";
20: objectSummary.Title = "Title";
21: return objectSummary;
22: }
23: return null;
24: }
25: }
Alguns testes:
1: [TestFixture]
2: public class TestObjectSummaryRepository
3: {
4: private IObjectSummaryRepository objectSummaryRepository;
5:
6: [SetUp]
7: public void SetUp()
8: {
9: objectSummaryRepository = new ObjectSummaryFakeRepository();
10: }
11: [Test]
12: public void TestGetGetObjectSummary_NonExistent()
13: {
14: Assert.IsNull(objectSummaryRepository.GetObjectSummary(2));
15: }
16: [Test]
17: public void TestGetGetObjectSummary_ShouldReturnValueObject()
18: {
19: Assert.IsNotNull(objectSummaryRepository.GetObjectSummary(1));
20: }
21: }
Como vocês podem ver os testes não trazem ROI algum! Qual o sentido de testar se existe um objeto no contexto fake? esses são tipos de testes para o ego.
Melhores opções
1-Podemos escrever os testes usando transações, inserindo dados para os testes no SetUp e excluindo-os no TearDown. Desta maneira estaremos ao menos testando o código SQL. O problema é o tempo que os testes vão levar..
2-Podemos usar as coleções em memória apenas para testar relacionamentos entre os objetos.
Continuação da discussão
Este assunto é debatido no grupo DNA
TDD com ResharperTDD with Resharper
0Fala galera, após um longo tempo relutante resolvi testar o Resharper. Não gostava muito da idéia de novas ferramentas pois queria conhecer bem o Visual Studio. Após o vídeo do kata feito pelo Bassi. Resolvi fazer meu próprio teste. Realmente a ferramenta aumenta a produtividade de maneira considerável, no entanto as funcionalidades que facilitam o TDD foram as que mais me chamaram a atenção.
Basicamente o fluxo de desenvolvimento TDD é:
1-Criar o teste
2-Testar
3-Criar o código
4-Testar
5-Refatorar
6-Testar
Então vamos ver alguns simples exemplos usando o Resharper
1-Criando o teste
2-Criando o código
3-Criando um arquivo para a nova classe
4-Rodando o teste
Acho que ficou mais facil não é? quem quiser testar aqui está o download.
Nunit, usando SetUp e teardown
0Fala galera,
Desculpe pela ausência nas ultimas duas semanas, eu gastei grande parte do tempo configurando meu novo PC com o Windows 7 além de estudar para as provas da faculdade.Hoje vamos falar de um assunto que deveria ser debatido mais vezes nos blogs e grupos de discussão, estou falando dos testes unitários.Estou trabalhando num projeto com ASP.NET MVC, como você pode imaginar estou utilizando testes unitários(MVC+Testes unitários = agilidade). Eu estou usando um FakeController que pode ser obtido no blog do Stephen Walther. O código fornecido trabalha com um método SetUp que inicializa o FakeControllerContext no controller que está sendo testado. O método SetUp no NUnit é disparado antes da execução de cada teste, então a cada novo teste um novo FakeControllerContext é criado.Até ai não existe problema, A situação fica complicada quando é necessário compartilhar dados entre testes distintos usando como exemplo o objeto applicationContext.Para resolver este problema você precisa realizar apenas uma pequena alteração no método setUp, as mesmas mudanças explicadas para o SetUp são validas. Vamos olhar um exemplo que deixa a ordem de execução mais clara.
1: [TestFixtureSetUp]
2: public void ClassSetUp()
3: {
4: //A lista de produtos e o gerente de produtos podem ser utilizados para todos os métodos
5: // sendo assim, não é necessário inicializar os membros antes de cada método
6: gerenteProduto = new GerenteProdutos();
7: produtos = new List<Produto>();
8: produtos.Add(new Produto() { Nome = "Iphone", Preco = 300 });
9: produtos.Add(new Produto() { Nome = "PSP", Preco = 180 });
10: produtos.Add(new Produto() { Nome = "VSTS", Preco = 500 });
11:
12:
13:
14: }
15: [SetUp]
16: public void SetUp()
17: {
18: // esta variável deve ser inicializada antes de cada execução - exemplo simples para explicação
19: ssomatorio = 0;
20: }
21:
22: [Test]
23: public void TestSomaValorDosProdutos()
24: {
25: ssomatorio = gerenteProduto.SomaValorDosProdutos(produtos);
26: Assert.AreEqual(980, ssomatorio);
27: }
28:
29: [Test]
30: public void TestSomatorioDosProdutosComTaxas()
31: {
32: ssomatorio = gerenteProduto.SomatorioDosProdutosComTaxas(produtos);
33: Assert.AreEqual(1078, ssomatorio);
34: }
Como você pode ver no exemplo o atributo [TestFixtureSetUp] indica que um método será executado apenas uma vez, durante a inicialização da classe. O atributo [SetUp] indica que um método será executa antes de cada teste.
Espero que você escreva muitos testes e que os atributos SetUp e TearDown sejam úteis.
código fonte completoHello folks,
Sorry for being absent the last two weeks, I spent so much time configuring my new PC and the windows 7 besides being studying for college exams. Today let’s talk about a subject that I think that should be discussed, this post talks about NUnit and some tips for this tool. I’m working on an ASP.NET MVC project, so you can realize that I’m working with Unit tests, if you do you are right. I’ve been using a fakeController context to test the UI layer. You can get this code at Stephen Walther’s blog. In this code you have a setup method that sets the fakecontext in the current controller. The setup method in NUnit is called before each test runs, so each new test uses a new fakeContext, there is no problem in this approach. The situation gets worse when you want to test values stored in the applicationContext, for instance if you need to test the session[“index”], To solve this issue you just have to make a little change in your SetUp method, you should execute it before each class Am I right? So if you agree you just have to change the attribute setup to TestFixtureSetUp, you can make the same change to TearDown. Let’s look an example that show what is the execution order in Nunit.
1: [TestFixtureSetUp]
2: public void ClassSetUp()
3: {
4:
5: //the listOfProduct and the ProductManager are available for all methods, so they don't need
6: //to be initialed before each method execution
7: productManager = new ProductManager();
8: productNames = new List<Product>();
9: productNames.Add(new Product() { Name = "Iphone", Price = 300 });
10: productNames.Add(new Product() { Name = "PSP", Price = 180 });
11: productNames.Add(new Product() { Name = "VSTS", Price = 500 });
12:
13:
14:
15: }
16: [SetUp]
17: public void SetUp()
18: {
19: // the variable sum must be initialed before each method -poor example just to show the execution
20: sum = 0;
21: }
22:
23: [Test]
24: public void TestSumOfAllProducts()
25: {
26: sum = productManager.SumProductsValues(productNames);
27: Assert.AreEqual(980, sum);
28: }
29:
30: [Test]
31: public void TestSumOfAllProductsWithTaxes()
32: {
33: sum = productManager.SumProductsValuesWithTaxes(productNames);
34: Assert.AreEqual(1078, sum);
35: }
You can see in the example that the attribute [TestFixtureSetUp] indicates that a method will execute before the class and the attribute [SetUp] indicates that a method will execute before each test runs. You can do the same thing when working with tearDown.
I hope you write tests and that setUp and TearDown methods help you!
Testes unitários ASP.NET MVC
0Fala Galera, ontem estava trabalhando em um dos meus projetos pessoais e me encontrei meio perdido, fiquei uns 10 minutos debuggando.. isso porque? bem neste projeto desenvolvemos usando testes unitários, testes são realmente uma ferramente essencial quando estamos falando de refatorações ou até mudanças comportamentais no código.
Eu participo de um grupo de arquitetura que está rolando uma thread sobre testes unitários, acho que a principal pergunta quando falamos de testes é sobre como vamos escrever testes, que comportamentos devemos testar.. Eu já pesquisei bastante sobre testes unitários e achei poucas dicas sobre como escrever testes, depois de um tempo aprendi que este conhecimento é obtido praticando! sim, praticando!
Meu início com os testes unitários não foi facil, eu escrevia testes me baseando no comportamento default esperado com o uso da função testada, acho que no início está é uma maneira eficiente de escrever testes. Depoisde um tempo vi que testes podem fazer mais, podem validar contratos definidos pelos métodos, sendo assim comecei a testar condições comuns que poderiam fazer o método quebrar, foi então que aprendi que testes podem esperar uma exceção.Hoje eu uso testes de maneira muito mais eficiente se comparado quando comecei, e olha que isso tem mais ou menos 1 ano.
Como foi dito no início do post, eu uso testes unitários no meu projeto. Este projeto usa ASP.NET MVC, no MVC é realmente muito mais facil de testar a execução das páginas pois na verdade testamos os controller(no WebForm é melhor usar o selenium). No ASP.NET MVC, é necessário usar objetos Fake para testar os controller de maneira simples, código para fazer é simples e já foi desenvolvido pelo stephenwalther. O código pode ser acessado aqui no meu projeto(Test->WebUI->FakeObjects), nesta pasta estão os arquivos necessários e aqui um exemplo de uso.
É isso galera, espero que a dica seja boa.. uma maneira facil de testar usando asp.net mvc
Where are the tips about Unit Test and NUnit ?
0Hi folks, A short time ago I bought a book about Nunit with c#, I tell you that I read some blogs but any blog is about UnitTesting, I don’t know if people don’t write tests or they don’t post about it. So, Pragmatic-Unit-Testing-Nunit-Programmers is a nice book, it is really practical but I want know about What and How to write good test, this book shows the most important tips for design and execute tests but How any pragamtic book it is focused in how to write tests, too technically. So fellows I’ll make some posts about UnitTests and NUnit.