O que significa TDD e qual é o seu benefício    

Olá pessoal!

Hoje vou publicar um mini artigo que fiz para a pós-graduação ano passado sobre TDD. Se fosse escrever hoje sobre o mesmo assunto, com certeza falaria de muitas coisas diferentes, mas neste post vou colocar o artigo exatamente como entreguei na faculdade. Provavelmente voltarei a abordar esse tema por aqui, e ai sim colocarei mais informações. Por ser um artigo acadêmico, ele é bem superficial e não técnico. Segue o texto na íntegra.


O que significa TDD e qual é o seu benefício

Fazer software com qualidade não é uma tarefa fácil. Especificações mal definidas e que mudam sempre, tecnologias e conhecimento sempre em evolução e mais uma série de fatores torna a construção de software uma tarefa muitas vezes ingrata. Quando dizemos Software de qualidade, temos que ter em mente que qualidade não é medida apenas por experiência do Usuário ou grau de completude da especificação funcional. Qualidade de Software deve contemplar todos os aspectos do mesmo, como o código. Em código temos vários outros fatores que podemos citar, como legibilidade, complexidade, desempenho e o que mais interessa esse artigo, manutenção. Uma manutenção difícil em código pode acabar com o funcionamento de um sistema e causar perdas inestimáveis.

Teste é a principal ferramenta para alcançar a qualidade de Software. Ao longo de um desenvolvimento de Software, vários tipos de testes são executados, cada tipo é especifico para uma fase do desenvolvimento. Para o escopo do código, o tipo de testes apropriado é o Teste de Unidade ou Unitário, que visa validar cada pequeno trecho de código e conferir que ele está executando conforme esperado. Em um cenário onde a mudança é constante esse risco deve ser mitigado ao mínimo e Test-Driven Development (TDD) ou Desenvolvimento Orientado a Testes, é uma ferramenta que se encaixa perfeitamente nesse cenário. TDD é a prática de desenvolver Testes Unitários antes de desenvolver a unidade, para dessa forma direcionar o desenvolvimento da unidade.

“Código limpo que funciona é o objetivo do TDD. Código limpo que funciona é um objetivo que vale a pena por uma série de razões: Prediz a forma de desenvolver. Você sabe quando terminou, sem a preocupação de uma lista de erros. Permite seu time confiar em você. Melhora a vida do seu usuário. Possibilita aprender do seu código tudo que ele tem para te ensinar.” [1]

TDD prega que você deve codificar o teste do seu código antes mesmo de escrevê-lo, dessa forma, a primeira pergunta que você deve fazer ao iniciar o desenvolvimento não é “Como devo desenvolver este código”, mas sim “Como devo testar esse código”. Um dos benefícios dessa abordagem é que ao pensar nos testes, o desenvolver irá desejar códigos fáceis de testar, dessa forma com os testes prontos, ele será forçado a desenvolver um código limpo, desacoplado, do contrario será muito difícil realizar o teste.

Todo software de qualidade tem a maior parte do seu código testado, métrica essa chamada de Code Coverage. Com o TDD, você tem a certeza que 100% do seu código está testado, pois ele só foi escrito depois que você o testou. Comprovadamente, você gastará menos tempo com código testado ao alterá-lo do que com código sem testes. Código sem teste é legado para o próprio desenvolvedor que o desenvolve.

“Você provavelmente terminará o seu sistema com o mesmo número de linhas de testes que o número de código funcional quando implementar TDD. Para TDD fazer sentido economicamente, você precisa estar apto a desenvolver duas vezes mais linha de código por dia ou a metade de linhas para desenvolver a mesma funcionalidade” [1]. Quando uma pessoa está iniciando em TDD, é normal se questionar apenas com a realidade de ter que desenvolver mais rápido, e isso motiva muitos profissionais a desistirem dessa técnica. Porém, como afirmado anteriormente, o código desenvolvido com TDD é mais limpo, simples e enxuto, logo, no maior número de vezes, o seu código é que vai cair pela metade no número de linhas, e não sua produtividade terá que aumentar.

Ainda que seu código não diminua, em muitos casos você não terá que aumentar a capacidade de velocidade de desenvolvimento, pois se você desenvolver cem linhas de código com testes perderá X tempo para realizar manutenção no mesmo, por outro lado, se você fizer o mesmo número de linhas de código sem testes, o tempo que perderá para fazer manutenção em algum código é imprevisível, mas será sempre maior que X.

Podemos saber que está na hora de começar a desenvolver testes para nosso código no momento que o nível de Stress para realizar uma manutenção nele for alto. Ou seja, quando o desenvolvedor ao deparar com um código necessitado de manutenção o Stress do time aumenta? Então você não sabe o que está falhando. Esse sentimento é comum em projetos sem testes, com TDD o nível de Stress de uma equipe tende a zero, pois o erro é rapidamente explicitado por testes, e você sabe exatamente o momento que a manutenção está completada, pois os novos testes criados antes das alterações estarão passando. Para implementar TDD em uma equipe, comece com indicadores que mostre o nível de Stress ou Medo da sua Equipe. Mostre a evolução desse índice conforme o TDD for sendo adotado.

Todas as práticas utilizadas em testes devem ser adotadas em TDD, como testes isolados, simples, etc; mas com TDD alguns outros passos também devem ser considerados, tais como fazer pequenos passos (baby steps), não ter pressa de fazer um teste passar, etc. Essas são boas práticas que facilitam a vida de pessoas iniciantes no Desenvolvimento Orientado a Testes, mas que devem ser seguidas por todos os desenvolvedores experientes. “Escaladores conservadores têm uma regra de que pelo menos três dos quatro membros do corpo devem estar presos à montanha ao mesmo tempo. Movimentos rápidos onde são tirados dois membros ao mesmo tempo são muito arriscados.” [1]. Essa mesma regra deve ser seguida por desenvolvedores, não ter pressa de pular os pequenos passos ao desenvolver os testes, dessa forma, terá certeza que a maior parte do código está sendo testado, e seu Nível de Medo será praticamente zero ao entregar o software.

Apesar de TDD ser muito aplicado quando o time segue Metodologias Ágeis de desenvolvimento, essa técnica pode e até mesmo deve ser adotada por qualquer tipo de time, como aqueles que utilizam RUP, por exemplo. Com testes, você pode confiar em refatoração, Builds automáticos, e com TDD você pode confiar, além de tudo isso, que seu time entrega software não só que roda, mas que faz o que é certo, pois você codificou o que ele precisava fazer de acordo com um teste previamente escrito, e não testou algo que já estava escrito sem garantia que ele fizesse o que deveria.

Com TDD, concluí-se que é possível fazer “código limpo que funciona” e que é possível ser agradável criar software de qualidade sem altos níveis de Stress.

[1] Beck, Kent; Test-Driven Development by Example. Addison Wesley,2003


É isso. Até o próximo post.

31. janeiro 2013 09:21 by Frederico B. Emídio | Comments (0) | Permalink

Testando propriedades e métodos privados com PrivateObject.    

Olá pessoal! Estou retomando o Blog em 2013 e agora pretende realmente manter a regularidade.

Para iniciar essa nova fase vou falar de um assunto importante já abordado aqui de forma rápida, e que esse ano talvez eu dê mais foco: Testes. Hoje vou falar de uma característica bem específica dos testes, que é a dificuldade de testar propriedades e métodos privados.

De forma geral, é dito que propriedades e métodos privados e não precisam ser testados porque em teoria o método público que acessa o método privado uma vez testado, também testará o método privado. Infelizmente na prática muitas vezes precisamos testar esses métodos privados, talvez porque a lógica deles seja complexa, ou porque o design da classe não seja bom, ou mesmo porque a classe não é nossa, e não podemos alterá-la, mas precisamos testá-la.

O que devemos ter em mente é que nossos códigos precisam ser testados, e devemos fazer de tudo para que isso seja possível, seja com Mocks, Stubs ou até testando métodos privados.

Vamos ao código!

No exemplo abaixo apenas vou mostrar como testar, ignore a necessidade do método ser privado ou não, ou se eu podia fazer um código diferente, o objetivo aqui é mostrar a possibilidade do teste quando ele se faz necessário.

Minha classe de exemplo que deve ser testada:

   1:  public class ClasseTestada
   2:  {
   3:      private int SomaPrivado(int a, int b)
   4:      {
   5:          return a + b;
   6:      }
   7:  }

E o meu teste:

   1:  [TestMethod]
   2:  public void Testar_a_Soma_de_dois_numeros()
   3:  {
   4:   
   5:      var a = 2;
   6:      var b = 3;
   7:      var expected = 5;
   8:   
   9:      var teste = new ClasseTestada();
  10:      var pv = new PrivateObject(teste);
  11:   
  12:      var actual = (int)pv.Invoke("SomaPrivado", a, b);
  13:   
  14:      Assert.AreEqual(expected, actual);
  15:  }
  16:   

E o resultado

Resultado do Teste

Vejam que o teste passou como o esperado. O segredo é bem simples. Apenas utilizo a classe PrivateObject, essa classe basicamente utiliza reflection para invocar métodos e propriedades. Uma vez que passo minha instância a ser testada no construtor da PrivateObject, posso utilizar seus métodos para chamar os membros da classe a ser testada. No caso do exemplo acima estou utilizando o método Invoke para invocar um método privado.

Essa classe pertence ao Namespace Microsoft.VisualStudio.TestTools.UnitTesting, que fica automaticamente disponível ao criar um projeto de testes. Ela tem uma série de outros métodos que auxiliam no trabalho de acesso a membros privados. Abaixo tem toda a lista de métodos:

clip_image003

É isso. Bem simples e curto para começar o ano e retomar as postagens, mas em breve tem mais.

Abraços e feliz ano novo!

10. janeiro 2013 01:13 by Frederico B. Emídio | Comments (0) | Permalink

Testando seu código JavaScript com QUnit    

Olá pessoal!

Depois de muito tempo sem escrever, volto falando de um dos meus temas preferidos: JavaScript!

Hoje vou falar de um tema complicado mesmo para linguagens compiladas como C# ou Java, para uma linguagem de script esse tema é ainda mais complicado. Como o título já mostra, vou falar de Testes em JavaScript.

Não pretendo aqui falar de todos os conceitos de Teste abordado para tantas linguagens e de seus inúmeros benefícios, mas apenas apresentar uma boa ferramenta que facilita muito a validação do seu código JavaScript. De qualquer forma, não posso deixar de falar que validar código não é o único benefício dos testes, na realidade, na minha opinião, um dos principais benefícios de criar código para testar seu código é melhorar o design do mesmo, deixando ele mais claro e organizado, além de facilitar futuras refatorações.

Organizar código JavaScript é uma tarefa difícil, e o teste facilita muito isso.

Então vamos lá, conhecendo o QUnit

QUnit é a uma ferramenta de teste criada pela equipe do JQuery, para testar sua biblioteca, que mais tarde foi exposta ao mundo para quem quiser utilizar. Só por ser utilizado pela equipe do JQuery já é um motivo para também querermos adotar essa suite de teste para nossos projetos, afinal, não é fácil encontrar erros na biblioteca do JQuery.

QUnit pode ser utilizada para testar código JavaScript puro ou mesmo o comportamento do DOM. Por exemplo, os plugins do JQuery são testados com QUnit, e não somente os códigos de lógica e classes.

Como qualquer ferramenta de teste, o QUnit é perfeito para teste de regressão, afinal, uma vez que um bug é encontrado, você pode criar um teste para validar a existência dele, e após corrigi-lo, verificar a correção, rodando novamente o teste toda vez que você trabalhar sobre o código.

Você não precisa instalar nada de especial para rodar o QUnit, é necessário apenas referenciar o script do Qunit, que pode ser encontrado aqui, e rodar seus testes no Browser.

Vamos ao código!

Utilizando o QUnit

Para utilizar o QUnit, você deve referenciar o script que realiza os testes e o CSS que dá o layout básico da página que mostra os resultados do teste, além de um HTML padrão para organizar os testes, da seguinte forma:

.

   1: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
   2: <html xmlns="http://www.w3.org/1999/xhtml">
   3: <head>
   4:     <title></title>  
   5:     <link rel="stylesheet" href="http://code.jquery.com/qunit/git/qunit.css" type="text/css" media="screen" />
   6:     <script type="text/javascript" src="http://code.jquery.com/qunit/git/qunit.js"></script>
   7:   
   8: </head>
   9: <body>
  10:     <h1 id="qunit-header">
  11:         QUnit example</h1>
  12:     <h2 id="qunit-banner">
  13:     </h2>
  14:     <div id="qunit-testrunner-toolbar">
  15:     </div>
  16:     <h2 id="qunit-userAgent">
  17:     </h2>
  18:     <ol id="qunit-tests">
  19:     </ol>
  20:     <div id="qunit-fixture">
  21:         test markup, will be hidden</div>
  22: </body>
  23: </html>

Explicando o código HTML acima: na tag HEAD adiciono o CSS e o Script necessários para funcionar os testes, e no Body as tags (h1, h2 e div) com id qunit-header, banner, testrunner-toolbar e qunit-userAgent são para criar um layout bonito e para auxiliar na execução dos testes, você não deve mexer nessas tags. A tag com id qunit-tests é onde será exibido os resultados dos seus testes, você também não deve adicionar conteúdo a essa tag. Por fim a tag com id qunit-fixture você deve utilizar no caso de testar algo com HTML, e não somente com código JavaScrit puro. É onde você adiciona HTML de teste. O conteúdo dessa tag não é exibido no browser.

O resultado do código acima é algo como a imagem abaixo:

image

Testando o código

Vamos fazer um código simples para testar. A classe abaixo será utilizada:

   1: var Calculadora = function () {
   2:     this.somar = function (a, b) {
   3:         return a + b;
   4:     }
   5:     this.subtrair = function (a, b) {
   6:         return a / b;
   7:     }
   8: };

Para utilizar o QUnit, precisamos conhecer alguns métodos básicos da biblioteca:

module (nome) – Para separar os testes em módulos

test (nome,testMethod) – Método que executa o teste, o primeiro parâmetro recebe o nome do método e o segundo é um método anonimo responsável por realizar o teste. Esse método tem um overload, podendo receber no segundo parâmetro, chamado expected, a quantidade de assets esperados dentro do método definido no parâmetro testMethod.

expect (total) – Define a quantidade de asserts esperados em um testMethod. É utilizado no caso de não ser utilizado o parâmetro expeted do método test.

Além do métodos acima, também têm os métodos responsáveis pelos Asserts dos testes, abaixo listo os principais:

ok(resultado, mensagem) – Realiza uma validação booleana do parâmetro resultado e exibe a mensagem como resultado.

equal(valor_real,valor_esperado, mensagem). Valida se o Valor Real é igual ao Valor Esperado.

notEqual(valor_real,valor_esperado, mensagem). Valida se o Valor Real NÃO é igual ao Valor Esperado.

Para testar meu código acima, vou fazer o seguinte código de teste:

   1: module("Testes de Somar");
   2: test("Testar Soma", 1, function () {
   3:    var calc = new Calculadora();
   4:    equal(calc.somar(1, 2), 3, "O resultado deve ser 3");
   5: });
   6:  
   7: test("Testar Soma Com Erro", 1, function () {
   8:    var calc = new Calculadora();
   9:    notEqual(calc.somar(2, 2), 3, "O resultado não pode ser 3");
  10: });

O resultado do código acima seria como a imagem abaixo:

image

Caso meu código tenha algum erro, o resultado seria como a imagem abaixo, mostrando inclusive o local onde ocorre o erro:

image

O código é bem simples, mas vou fazer uma pequena explicação.

No método test eu passo o nome do teste e a quantidade de assert que eu quero fazer no teste. Se eu definir um número de assert diferente do número que eu executo, o teste vai falhar (os possíveis métodos de assert do QUnit está acima). Por último parâmetro eu passo o método responsável por realizar os testes. O QUnit verifica os asserts dentro deste método, e se todos estiverem de acordo com o esperado, os testes passarão.

E se eu quiser testar um HTML? Bom vamos aos códigos abaixo:

Primeiro vou adicionar referência aos scripts do JQuery e JQuery.UI:

   1: <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
   1:  
   2: <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js">
</script>

Vou criar um JQuery Ui Widget simples, e testar se meu código está funcionando conforme o esperado:

   1: (function ($, undefined) {
   2:     $.widget('teste.bolder', {
   3:     _create: function () {
   4:  
   5:         $(this.element).append("<p class='bolder'/>");
   6:     }
   7: });
   8: } (jQuery));

O que meu código faz é apenas adicionar uma tag P com uma classe “bolder” ao controle selecionado pelo JQuery, ou seja, se eu fizer:

$(“div#teste”).bolder();

Um div vazio deve ficar assim:

<div><p class=”bolder”/></div>

Vamos ao teste. Primeiro devo alterar a tag com id qunit-fixture:

   1: <div id="qunit-fixture">
   2:     <div id="teste"></div>
   3: </div>

Após fazer isso, crio meu código de teste:

   1: test("Testando widget Bolder", 1, function () {
   2:    //Crio o controle executando o widget
   3:   $("#teste").bolder();
   4:   //faço um teste básico para ver  se fpo criado como o esperado.
   5:   equal($("p.bolder").length, 1, "Testando criação");
   6: });

É um teste bem simples, mas dá para ver como podemos fazer coisas mais complexas se quisermos. Lembre-se: A equipe do JQuery teste seu código dessa forma!

O resultado do meu teste está abaixo:

image

Bom, acredito que com isso você já consegue codificar seus métodos de testes de JavaScript. É só aplicar os mesmo conceitos que você já utiliza para testar seu código C#.

Para mais informações sobre o QUnit, visite o site do JQuery específico para essa ferramenta.

Abraços e até o próximo!

25. janeiro 2012 00:03 by Frederico B. Emídio | Comments (0) | Permalink

Sobre mim

Minha Imagem

Meu nome é Frederico Batista Emídio, trabalho com desenvolvimento de sistemas profissionalmente a oito anos, porém, já faço sites pessoais a pelo menos dez anos.

Para saber mais clique aqui.

Páginas

Calendário

<<  novembro 2017  >>
seteququsedo
303112345
6789101112
13141516171819
20212223242526
27282930123
45678910

Visualizar posts em um Calendário
Sigua @fredemidio

MCP Asp.NET