SlideShare uma empresa Scribd logo
1 de 62
Introdução ao Desenvolvimento Orientado a Testes (Test-DrivenDevelopment - TDD) Fabrício Matos Nov/2008
TDD é uma técnica de desenvolvimento de software cujo processo é formado por pequenas iterações para o desenvolvimento de uma nova funcionalidade, começando pela implementação de um caso de teste, depois pelo código necessário para fazer o teste passar, e finalmente pela refatoração do código visando melhor acomodar as mudanças feitas. Não é um método para testar software, mas para construir software. TDD vem do conceito de “test-first programming” do XP (Extreme Programming), mas acabou ganhando tanto interesse, que hoje tem sido adotado independente do XP e das técnicas de programação ágil; Introdução Página 2
Objetivo do TDD:  “cleancodethat works” código limpo que funciona “Mantra” do TDD: vermelho-verde-refatorar Codifique o teste; Faça ele compilar e executar (não deve passar - vermelho); Implemente o requisito e faça o teste passar (verde); Refatore o código; Introdução Página 3
Garante a existência de testes unitários completos e atualizados, que: Eliminam o medo de alterarmos alguma coisa que funciona (testada manualmente), e acabarmos introduzindo algum problema; Nos permite utilizar refatoração (substituir uma implementação por outra equivalente) de forma muito mais agressiva devido à facilidade dos testes verificarem o resultado. Diminui a quantidade de erros por linha de código (código-fonte de mais qualidade) Testes unitários servem como especificação de como os componentes do sistema funcionam; Nos leva a produzir componentes de software mais desacoplados, para garantir o isolamento dos testes, o que acaba favorecendo o projeto do sistema. Principais Benefícios do TDD Página 4
Nosso foco é em produtos, e não em serviços, e os produtos precisam acompanhar as mudanças dos processos dos clientes, logo nossos sistemas estarão em constante evolução. Testes automáticos nos ajudarão pois:  Evitarão efeitos colaterais nas futuras alterações. Documentarão bem o sistema para novos profissionais contratados. Permitirão a liberação de releases de muito maior qualidade. Erros reportados serão reproduzidos via caso de teste, corrigidos e nunca mais retornarão pois estarão cobertos pelo teste automático; Importância para Qualidata Página 5
A Metodologia TDD Estudo de Caso: Aplicação do TDD na IBM Tese de Doutorado - MirkeyaCapellán(2006) Measuring Productivity and Code Quality: Test-Driven Development vs. Waterfall Construção de Casos de Testes com NUnit Considerações Finais Organização da Apresentação Página 6
A Metodologia TDDBaseado principalmente emKent BeckTest-DrivenDevelopmentByExample, 2003 Página 7
Testes de Unidade: Testa uma unidade mínima do software; Testes de Integração: Testa a comunicação entre os módulos; Testes de Sistema: Testa todo o sistema para verificar se atende aos requisitos; Testes de Integração de Sistema: Testa a comunicação do sistema com outros sistemas com os quais interage; Testes de Aceitação: Testes realizados pelo usuário final para verificar se o sistema faz o que ele espera; Tipos de Testes Página 8
A Metodologia TDD é conduzida através dos “testes do programador”. Frequentemente esses testes são chamados de “teste de unidade”, mas esse nem sempre é o caso (pode ser teste de integração). É importante destacar que não se trata dos testes de sistema (caixa preta) nem os de aceitação (feitos pelo usuário final) Tipos de Testes Página 9
A “Espiral da Morte” do Teste Página 10 O ciclo mortal do “estou sem tempo para testar”:
1. Construa testes isolados uns dos outros Um caso de teste não deve depender do sucesso de outro para funcionar; Deve ser possível executar um caso de testes isoladamente, sem executar nenhum outro; 2. Comece definindo uma “TestList” De modo geral para uma mesma classe ou método a ser testado, existirão diferentes casos de teste. Liste-os primeiro (brain-storm); Provavelmente ao longo do desenvolvimento você adicionará novos casos de teste à lista; Princípios Página 11
Mas o que testamos? Fluxos Condicionais (IFs, Switches, etc.) Polimorfismos Loops Operações Etc.. Princípios Página 12
Exemplo de “Lista de Testes” para o caso de uso “Realizar Transferência Bancária”: Realizar uma transferência normal (bem sucedida); Tentar transferir uma quantidade superior ao saldo da conta de origem; Verificar atomicidade no caso de falha de sistema antes de concluir a operação; Conta de origem inativa; Conta de destino inativa; Valor transferido menor que zero; Princípios Página 13
Exemplo de “Lista de Testes” para o caso de uso “Matricular Aluno em Disciplina”: Matricular com sucesso; Tentar matricular sem atender disciplinas pré-requisito; Tentar matricular sem atender pré-requisito de crédito; Tentar matricular com conflito de horário; Tentar matricular sem vaga; Tentar matricular em disciplina já cumprida; Tentar matricular em disciplina que já está matriculada (outra turma); Tentar matricular em disciplina que já está matriculada (mesma turma); Princípios Página 14
3. Primeiro o  Teste Oportunidade para pensar no design (projeto) das classes Controlar o escopo do que será implementado – somente o necessário para atender o teste corrente. 4. Primeiro a Assertiva É melhor pensarmos no que significa o sucesso do caso de teste antes de pensarmos no restante: Vou precisar de criar um novo método? Em qual classe? Qual será o nome dele e seus parâmetros? “Primeiro a assertiva” está para o caso de teste assim como “Primeiro o teste” está para o caso de uso; Princípios Página 15
Exemplo: Testar o envio da string “Qualidata” através de um socket. Princípios Página 16 publicvoidTestarComunicacaoSocket()         { Assert.IsTrue(readerSocket.Close()); Assert.AreEqual(“Qualidata”, buf);         } publicvoidTestarComunicacaoSocket()         {                 string buf = reader.Contents(); Assert.IsTrue(readerSocket.Close()); Assert.AreEqual(“Qualidata”, buf);         } publicvoidTestarComunicacaoSocket()         { SocketreaderSocket = newSocket(“localhost”, 8080);                 string buf = reader.Contents(); Assert.IsTrue(readerSocket.Close()); Assert.AreEqual(“Qualidata”, buf);         } publicvoidTestarComunicacaoSocket()         { Serverserver = newServer(8080, “”Qualidata”); SocketreaderSocket = newSocket(“localhost”, 8080);                 string buf = reader.Contents(); Assert.IsTrue(readerSocket.Close()); Assert.AreEqual(“Qualidata”, buf);         }
5. Dados para Teste Não escolha números mágicos se eles não tiverem um significado específico no teste. Por exemplo, se não faz diferença utilizar “1”, “2” ou “1365”, preferia  “1”.  Evite passar o mesmo valor para diferentes parâmetros. Por exemplo, para testar um método Operacao(int x, int y), não utilize Operacao(2,2), pois “Operacao” pode inverter “x” e “y” e o teste ainda assim passar. Prefira, por exemplo, Operacao(2,3). Dê preferência a dados do mundo real, especialmente quando você tem algum sistema legado com dados que podem ser aproveitados Princípios Página 17
6. Dados com Significado Evidente Lembre que está escrevendo um teste para alguém ler, e não somente para ser executado pelo computador. Tente escrever na assertiva expressões que não só representem o valor final esperado, mas o que eles significam. Exemplo: Princípios Página 18         [Test] publicvoid Testar_Fatorial_8()         { Assert.AreEqual(40320, Matematica.Fatorial(8));         }  [Test] publicvoid Testar_Fatorial_8()         { Assert.AreEqual(8 * 7 * 6 * 5 * 4 * 3 * 2, Matematica.Fatorial(8));         }
Trata sobre quando escrever, onde escrever e quando parar de escrever testes. Qual o próximo teste da lista a implementar? Escolha um teste que você esteja confiante que pode implementá-lo facilmente; Não comece pelo teste mais realístico (completo), pois você será forçado a implementar um monte de coisas para atender o teste. Siga na direção “mais conhecidos” para “pouco conhecidos” Cada iteração “red/green/refactor” deve levar apenas alguns minutos. Exercício: Se você estiver construindo uma lista encadeada, qual seria seu primeiro caso de teste? “Red Bar Patterns” Página 19
Testes de Estudo Devemos escrever testes para componentes ou bibliotecas de terceiros que, supostamente, funcionam? Sim. Para estudar e documentar seu uso. Esse é uma forma de assegurar-se sobre como utilizar tal biblioteca de forma a obter os resultados esperados e documentar seu uso (considerando especificamente suas necessidades, e não todos os recursos da biblioteca). “Red Bar Patterns” Página 20
Testes de Outras Funcionalidades Sempre que uma discussão desviar do assunto principal e entrar em outras questões, essa pode ser uma hora de adicionar novos casos de teste à sua lista (para a funcionalidade em questão) e voltar para o assunto principal. Sim. Para estudar e documentar seu uso. Esse é uma forma de assegurar-se sobre como utilizar tal biblioteca de forma a obter os resultados esperados e documentar seu uso (considerando especificamente suas necessidades, e não todos os recursos da biblioteca). “Red Bar Patterns” Página 21
Defeitos Reportados Sempre que um defeito é reportado nossa primeira ação deve ser escrever um caso de teste que reproduza o problema. Se isso for feito certamente o problema será resolvido. Testes de Regressão Consiste em testar novamente uma funcionalidade que foi implementada e testada anteriormente; Teoricamente, após qualquer alteração no sistema, todo o sistema deveria ser testado para garantir que essa alteração não tenha introduzido algum efeito colateral indesejável. Uma boa prática é executar testes de regressão de todo o sistema, todos os dias, à noite, e reportar os problemas encontrados para a equipe. Existem softwares para gerenciar isso. “Red Bar Patterns” Página 22
Técnicas mais detalhadas sobre como escrever testes. Subdividir Testes Quando um teste ficou grande demais e você está demorando muito para conseguir implementá-lo (mais de 10 min já deve te encomodar), pode ser melhor dividir o teste em testes menores até conseguir fazer o teste maior passar. MockObjects Como testar objetos que dependem de recursos externos custosos ou complexos, como bancos de dados e webservices, por exemplo? Crie uma versão falsa ou simulada do objeto (“fake”) que retorne valores constantes. Referência: www.mockobjects.com Ferramentas para .NET: NMock e RhinoMocks. “TestingPatterns” Página 23
Log String Como testar se uma sequência de métodos foi chamada numa certa ordem? Guarde um log (trace log) de cada execução dos métodos chamados em uma string e compare com o valor esperado.  Teste de Falhas Precisamos assumir que “código que não foi testado não funciona”. Mas como testar falhas que são difíceis de se reproduzir (disco cheio, falha de comunicação, etc.)? “Fake it!”, ou seja, construa uma nova classe que gere a exceção e simule a falha. “TestingPatterns” Página 24
Desenvolvendo Sozinho – Teste Quebrado Se você está desenvolvendo uma software sozinho, é sempre melhor encerrar uma sessão de programação deixando um teste vermelho(incompleto).  Isso agiliza a continuação do trabalho no próximo dia. Desenvolvimento em Equipe – Testes Rodando Se você trabalha em equipe, não faça check-in de testes vermelhos. Isso vai ser ruim pois todos vão achar que há um requisito que foi “estragado”, enquanto na verdade ele ainda não foi finalizado. Ao subir suas alterações (check-in), rode todos os testes para garantir a integração entre os módulos. Se os testes não forem muito lentos, procure rodar todos os testes em sua própria estação para antecipar problemas de integração. “TestingPatterns” Página 25
Uma vez que você tenha um teste vermelho, busque torná-lo verde o quanto antes. Use os padrões que serão discutidos para conseguir isso rapidamente, mesmo que o resultado seja algo que você não aceita conviver nem por uma hora. “Green Bar Patterns” Página 26
“Fake it ‘til youmake it” (simule até construir realmente) Por exemplo, qual é a forma mais simples de implementar o código abaixo? A forma mas direta seria: “Green Bar Patterns” Página 27 publicvoidTestarSoma() { Assert.AreEqual(5, Somar(2,3));      } publicvoidTestarSoma() { Assert.AreEqual(5, Somar(2,3));      } publicint Somar(int x, int y) { return 5;      }
Triangulação Quando você tem dois ou mais testes, você precisa de uma implementação que atenda a todos simultaneamente. Agora a solução trivial (constante) não atende mais,  e somos forçados e implementar algo mais abrangente. É claro que esse exemplo é apenas ilustrativo. Se você já tem uma implementação correta óbvia, então implemente. Senão, “fake it”. “Green Bar Patterns” Página 28 publicvoidTestarSoma()       { Assert.AreEqual(5, Somar(2,3)); Assert.AreEqual(7, Somar(3,4));      }
Implementação Óbvia Se você consegue implementar algo diretamente, então implemente. Para que utilizar “fake” ou triangulação? Mas quando você achar que sabe implementar e se deparar com uma barra vermelha? Depois você descobre, errei aqui, e aí outra barra vermelha! Talvez seja hora de dividir o problema em problemas menores. Acreditar que você sempre vai conseguir acertar e escrever o código mais simples para o problema diretamente é exigir de você perfeição. “TestingPatterns” Página 29
Operações Sobre Coleções Implemente primeiro o teste para a operação recebendo um elemento; Depois estenda para a operação recebendo a coleção; Testes de Exceções Como testar se em determinadas condições uma exceção é gerada? Use try ... Teste ... Assert.IsTrue(false) ... catch ... Ou use algum recurso específico do seu framework de testes (um “xUnit” da vida), se houver: “TestingPatterns” Página 30      [ExpectedException(typeof(QException), "O atributo Pessoa.Nome não pode ser nulo.")] publicvoidTestarNomeNaoNulo()       {           Pessoa p = new Pessoa(); Conexao.Save(p);      }
É muito importante pensar em “design patterns” ao projetar seu software; Em TDD, “projeto” (design) não é exatamente uma fase, mas parte do processo “vermelho-verde-refatorar”. Nesse sentido eles recebem um olhar um pouco diferente em TDD. Apenas para ilustrar, vamos destacar um “design patterns” bem interessante. “Design Patterns” Página 31
Objeto NULL Quantas vezes você já viu uma “nullreference exception”? Quantas vezes você precisou proteger o seu código com um “if (obj != null) ...” ? Ao invés de retornar “null”, pode ser melhor retornar um objeto especial, com a mesma interface, mas que não gere problemas. Exemplo (java.io.File): “Design Patterns” Página 32 publicbooleansetReadOnly() { SecurityManagerguard = System.getSecurityManager(); if (guard != null) { guard.canWrite(path);      } returnfileSystem.setReadOnly(this); } publicstaticSecurityManagergetSecurityManager() { returnsecurity; //pode ser null } publicbooleansetReadOnly() { SecurityManagerguard = System.getSecurityManager(); guard.canWrite(path); returnfileSystem.setReadOnly(this); } publicstaticSecurityManagergetSecurityManager() { returnsecurity == null ? newSecurityLiberadoGeral() : security; }
Refatorar é melhorar o “design” de funcionalidades do sistema, sem alterar seu comportamento; Em TDD, devemos refatorar mantendo todos os testes “verdes”; Em TDD, primeiro pensamos em resolver o problema da Por que refatorar o código? Para torná-lo mais legível; Para facilitar sua manutenção, seja na correção de bugs ou na adição de novas funcionalidades, aumentado assim sua vida útil; Para ajustar decisões de projeto estejam impactando negativamente o sistema (limitando, deixando lento, etc..) Para buscar o “clean” de “cleancodethat works” Embora seja um assunto que possa ser trabalhado de forma mais específica, trabalharemos alguns exemplos de técnicas de refatoração de código. “Refactoring” Página 33
Reconcilie Diferenças Se duas partes do código poderem ser iguais, então poderemos eliminar uma delas; Dois loops poderiam ser fundidos em um só; Se dois caminhos em um condicional forem iguais, poderemos eliminar a condição; Se dois métodos foram iguais, podemos eliminar um; Se duas classes forem iguais, podemos eliminar uma; “Refactoring” Página 34
Isole as Alterações Se você precisa alterar uma parte específica de um método divido em partes (seções), primeiro isole essa parte (refatoração) e depois faça a alteração; Migrar Dados Como migrar dados de uma estrutura para outra? (Por exemplo, de um DataSet para uma lista) Duplique os dados primeiro criando uma nova variável (mantenha o DataSet e crie também a lista) Inicialize também a nova variável (lista) em todo lugar que a antiga (DataSet) é inicializada; Substitua a implementação para que seja utilizada a nova estrutura variável (lista) ao invés da antiga (DataSet) Elimine a variável da estrutura original (o DataSet). Entre todos esses passos os testes não devem deixar de permanecer verde. “Refactoring” Página 35
Extraia Métodos Simplifique métodos muito longos, criando métodos menores (variáveis locais utilizadas também fora do trecho devem virar parâmetros) Não se deve ir tão longe ao ponto de criar tantas indireções que acabem dificultando a leitura. Blocos de código com aquele típico comentário no início são excelentes candidatos a novos métodos. Exemplo: “Refactoring” Página 36     //Verifica se o aluno atende a todos os pré-requisitos para ser matriculado      linha 1      linha 2      ...      linha N
Métodos “Inline” Esse é o ato de substituir uma chamada de um método pelo seu conteúdo (o oposto da técnica anterior) Isso é especialmente útil quando você está tendo dificuldade de entender um código confuso, cheio de indireções.  Nesses casos pode ser melhor simplesmente desfazer (via “inline”) algumas camadas de abstração, entender o que o código faz, e depois repensar a melhor forma de reorganizá-lo. “Refactoring” Página 37
Mover Métodos Como mover métodos para outros “lugares” sem exigir uma alteração imediata em todos as suas chamadas? Crie o novo método no lugar que deseja; Mova o conteúdo do método; No método original, faça uma chamada ao novo método, repassando os parâmetros. Adicionar Novo Parâmetro Pode ser visto como um caso de “Migrar Dados” Também pode ser utilizado o próprio compilador para mostrar onde será necessário alterar sua chamada; “Refactoring” Página 38
Mover Parametros de Métodos para Construtores Por que? Se você passa o mesmo parâmetro para vários métodos de uma classe, pode ser melhor passá-lo uma única vez em seu constructor, e simplificar as chamadas dos métodos; Como? Adicione o parâmetro ao constructor; Adicione uma nova variável de instância com o mesmo nome do parâmetro, e inicialize ela no constructor; Um por um, converta todas as ocorrências de “parametro” nos métodos por “this.parametro”. “Refactoring” Página 39
Mover Parametros de Métodos para Construtores (...continuação) Quando não houver mais referências a “parametro”, elimine-o da assinatura do método e de todas suas chamadas; Remova o “this.” que agora é supérfluo; Renomeie a variável de instância apropriadamente. “Refactoring” Página 40
Qual o tamanho ideal dos passos “vermelho-verde-refatorar”? Você pode escrever testes que vão te levar a escrever uma única linha de código; Também pode escrever testes que vão te levar à escrever  centenas de linha de código; Não há uma regra, mas a tendência dos experientes em TDD é clara: Passos pequenos. “Mastering TDD” Página 41
Características de um bom teste Se você tem dificuldade para identificar um lugar comum para inicializações compartilhadas, então você deve ter um problema de projeto – muitos objetos entrelaçados. Quanto feedback (asserts) você precisa? Depende. Por exemplo, pode ser muito improvável um problema de diskfull, e você está confiante que esse é um teste desnecessário no cenário do software em questão. “Mastering TDD” Página 42
Quando excluir um teste? Quanto mais testes, melhor; Se dois testes fazem a mesma coisa, pode ser, mas considere: Na dúvida, não exclua; Se os dois testes seguem o mesmo fluxo de execução, mas comunicam (documentam) questões diferentes, deixe-os assim. TDD é Escalável? O maior sistema totalmente TDD que o autor participou foi na LifeWare: 40 pessoas, por 4 anos 250KLOC de código funcional 250KLOC de código de teste 4000 testes que levam 20min para executar “Mastering TDD” Página 43
Como iniciar TDD em um sistema desenvolvido sem Testes Automatizados? Muitos livros ainda precisam ser escritos sobre isso; Um primeiro problema é que código que não foi escrito pensando nos testes é difícil de ser testado; Outro problema é que alterações nesse código são perigosas pois não temos os testes para garantir que tudo continua funcionando; O ideal seria primeiramente implementar testes automáticos para todo o sistema e depois partir para desenvolver as novas funcionalidades com TDD; Outra opção é explorar outras formas de feedback, como testes de nível de aplicação, que garanta certo nível de confiança. “Mastering TDD” Página 44
A Metodologia TDD Estudo de Caso: Aplicação do TDD na IBM Tese de Doutorado - MirkeyaCapellán (2006) Measuring Productivity and Code Quality: Test-Driven Development vs. Waterfall Construção de Casos de Testes com NUnit Considerações Finais Organização da Apresentação Página 45
Baseado no artigo:  	[1]	E. M. Maximilien and L. Williams, "Assessing test-driven development at IBM", Proceedings of the 25th International Conference on Software Engineering pp. 564-569, Portland, Oregon, USA, IEEE Computer Society, 2003. O sistema: JavaPOS (www.javapos.com)  Um conjunto de serviços (JavaBeans) para permitir o acesso a dispositivos POS (pointofsale), tais como impressoras, caixas (dinheiro), leitores magnéticos, etc.. Implementado através de uma parceria da IBM, NCR, Epson e Sun. TDD na IBM Página 46
Motivação Implementação do JavaPOS original (sem TDD) contava com uma equipe que conehcia muito bem suas especificações e tinha grande experiência com dispositivos POS; Em cada fase de FVT (Functional Verification Test), executada antes de cada novo release, a taxa de defeitosnãodiminuíacomoesperado. Porissodesenvolvedores e gerentesestavamabertos a novas abordagens. TDD na IBM Página 47
Experiência Anterior com Testes Criavam algumas classes de teste de forma ad-hoc para partes mais importantes do código; O processo de construção de testes não era sistemático, sendo uma atividade pós-desenvolvimento; Na maioria das vezes, nenhum teste era criado. Especialmente quando os cronogramas estavam apertados, os desenvolvedores precisavam parar para resolver problemas de desenvolvimentos anteriores, ou ainda os novos requisitos não estavam muito claros TDD na IBM Página 48
Experiência Anterior com Testes (cont.) A maioria dos testes de unidade eram desperdiçados; Eles não eram executados na fase de verificação funcional (FVT) Também não eram aproveitados em versões posteriores (novos releases) do software; Não tinham qualquer experiência com TDD. TDD na IBM Página 49
Adoção da Metodologia TDD - No início havia muitas dúvidas: Taxa de Defeitos – Como TDD vai afetar a taxa de defeitos a curto prazo (próximo release) e a longo prazo (futuros releases)? Produtividade - Qual será o impacto? Trabalhavam com uma média de 400LOC / pessoa-mês. Frequência dos Testes – Qual será o percentual de testes automatizados em relação a testes iterativos? Quão frequentemente cada tipo de teste será executado? Projeto – Como TDD vai afetar a qualidade do projeto (design)? Eles avaliam isso através da capacidade de lidar com requisitos identificados tardiamente, ou a inclusão de novos dispositivos ou serviços. Integração – TDD e seus testes de regressão automatizados irão suavizar os processos de integração? TDD na IBM Página 50
O Trabalho com TDD No início muitos desenvolvedores e gerentes estavam preocupados pois uma metodologia tão rigorosa poderia afetar a produtividade a ponto de inviabilizar a manutenção dos cronogramas existentes. Apesar das metodologias ágeis sugerirem nenhum projeto a priori, no javaPOS os requisitos eram bem estáveis, e a equipe optou por desenvolver diagramas de classes e de sequência; Acrescentaram nas atividades de projeto, além dos diagramas UML, a criação de casos de teste (teste de sistema); TDD na IBM Página 51
O Trabalho com TDD Para cada classe pública A, tinham uma classe TesteA, e para cada método de A, métodos de teste correspondentes em TesteA. Havia casos em que era necessário tratar cenários diferentes do mesmo caso de teste. Por exemplo, impressoras que trabalhavam de modo síncrono ou assíncrono, exigiam casos de teste específicos para cada cenário; Definiram como meta um mínimo de 80% de cobertura de teste automatizado (o restante poderia ser testes iterativos); TDD na IBM Página 52
O Trabalho com TDD Cada documento de especificação de projeto continha uma secção de testes descrevendo todas as classes e métodos importantes que deveriam ser testados; Diariamente todo código era compilado automaticamente, e todos os testes executados. Para cada build, um email era enviado para cada membro da equipe com a lista de testes executados e eventuais erros encontrados. Em um primeiro momento, esses builds eram gerados várias vezes por dia; TDD na IBM Página 53
TDD na IBM Página 54
Resultados Números do Projeto: 71.4 KLOC de código de negócio e 34 KLOC de código Junit; Densidade de erros, que normalmente é de 8 erros/KLOC foi de 4 erros/KLOC (50% de redução) OBS: Atualmente, devido ao TDD, nossa densidade média de erros é de 3.7 erros/KLOC. Foram escritos 2390 casos de teste JUnit. Outros 100 testes foram escritos para avaliar performance; TDD na IBM Página 55
Resultados Taxa de Defeitos – Com TDD, os testes automatizados realmente foram feitos. Como resultado obtiveram um excelente redução de 50% de defeitos na fase de verificação funcional (FVT) Produtividade – Não só manteve-se dentro dos cronogramas, como obtiveram uma pequena melhoria em relação à média de 400LOC/pessoa-mês; Frequência dos Testes – Escreveram aproximadamente 2500 testes automáticos e 400 testes iterativos, ou seja, 86% de cobertura de teste automático, acima da meta de 80%. Projeto – Acreditam que TDD ajudou a produzir um sistema que recebe mais facilmente mudanças. Inclusive alguns dispositivos foram incluídos no projeto quando o mesmo já tinha avançado mais de 2/3 do cronograma. Integração – Antes integravam somente próxima à fase de FVT. Com TDD e integrações (builds) diários, diminuíram muito os riscos pois problemas aparecem bem mais cedo. TDD na IBM Página 56
Lições aprendidas sobre a transição para TDD: Comece TDD no início do projeto; Ajuste as expectativas da equipe pois no início TDD parece menos produtivo e frustrante pelo tempo que se leva para criar os testes; Na prática, no final das contas, não haverá impacto negativo na produtividade. Para uma equipe nova em TDD, inicie builds diários mais adiante um pouco. Não muito cedo nem muito tarde (após 1/3 do cronograma, por exemplo). Enquanto isso cada um deve executar os seus testes em sua estação. TDD na IBM Página 57
Lições aprendidas sobre a transição para TDD: Convença a equipe de adicionar novos casos de tese sempre que um problema for encontrado, não importando onde seja. Isso vai garantir a solução do problema em algum momento à frente; Definimos 80% de cobertura como um objetivo mínimo. É extremamente importante os builds diários automáticos. Eles se tornam a batida que dá o ritmo ao projeto e ao mesmo tempo facilita acompanharmos seu progresso; Encorage a construção de testes que executem rapidamente e de projeto eficiente; Aproveite sempre para encorajar a equipe a escrever mais testes, por exemplo, monitorando qual subsistema tem mais testes implementados. TDD na IBM Página 58
A Metodologia TDD Estudo de Caso: Aplicação do TDD na IBM Tese de Doutorado - MirkeyaCapellán (2006) Measuring Productivity and Code Quality: Test-Driven Development vs. Waterfall Construção de Casos de Testes com NUnit Considerações Finais Organização da Apresentação Página 59
Experimento 24 profissionais de 3 empresas trabalhando em pares. Metade com TDD e a outra metade seguindo um Modelo em Cascata. Apenas uma empresa tinha experiência prévia com TDD; Resultados: TDD produziu um código de mais qualidade do que o Modelo Cascata 18% a mais de sucesso em testes de caixa preta 80% mais eficaz em termos de qualidade de código TDD teve um tempo total de desenvolvimento bem menor: O de programação, especificamente, foi 16% maior;  O projeto como um todo foi 78% mais podutivo; Programadores acharam TDD uma forma mais simples de projetar software; Transição para TDD foi difícil TDD versus ModeloCascata Página 60
A Metodologia TDD Estudo de Caso: Aplicação do TDD na IBM Tese de Doutorado - MirkeyaCapellán (2006) Measuring Productivity and Code Quality: Test-Driven Development vs. Waterfall Construção de Casos de Testes com NUnit Considerações Finais Organização da Apresentação Página 61
A Metodologia TDD Estudo de Caso: Aplicação do TDD na IBM Tese de Doutorado - MirkeyaCapellán (2006) Measuring Productivity and Code Quality: Test-Driven Development vs. Waterfall Construção de Casos de Testes com NUnit Considerações Finais Organização da Apresentação Página 62

Mais conteúdo relacionado

Mais procurados

Padrões para Desenvolvimento de Software Guiado por Testes
Padrões para Desenvolvimento de Software Guiado por TestesPadrões para Desenvolvimento de Software Guiado por Testes
Padrões para Desenvolvimento de Software Guiado por TestesEverton Rodrigues
 
Implementando Testes Unitários em Java - Manoel Pimentel
Implementando Testes Unitários em Java - Manoel PimentelImplementando Testes Unitários em Java - Manoel Pimentel
Implementando Testes Unitários em Java - Manoel PimentelManoel Pimentel Medeiros
 
Paletra sobre TDD, ocorrida no #DevDojo
Paletra sobre TDD, ocorrida no #DevDojoPaletra sobre TDD, ocorrida no #DevDojo
Paletra sobre TDD, ocorrida no #DevDojoflavio1110
 
Treinamento Testes Unitários - parte 1
Treinamento Testes Unitários - parte 1Treinamento Testes Unitários - parte 1
Treinamento Testes Unitários - parte 1Diego Pacheco
 
Testes Unitários/Integrados
Testes Unitários/IntegradosTestes Unitários/Integrados
Testes Unitários/IntegradosGiovanni Bassi
 
Testes de software
Testes de softwareTestes de software
Testes de softwareteste
 
Test-Driven Development (TDD) utilizando o framework xUnit.net
Test-Driven Development (TDD) utilizando o framework xUnit.netTest-Driven Development (TDD) utilizando o framework xUnit.net
Test-Driven Development (TDD) utilizando o framework xUnit.netRenato Groff
 
Testes Automatizados de Software
Testes Automatizados de SoftwareTestes Automatizados de Software
Testes Automatizados de SoftwareMaurício Aniche
 
Introdução a testes automatizados
Introdução a testes automatizadosIntrodução a testes automatizados
Introdução a testes automatizadosThiago Ghisi
 
Por que automatizar testes de software?
Por que automatizar testes de software?Por que automatizar testes de software?
Por que automatizar testes de software?Samuel Lourenço
 
Apresentacao Testes de Unidade
Apresentacao Testes de UnidadeApresentacao Testes de Unidade
Apresentacao Testes de UnidadeAline Ferreira
 

Mais procurados (20)

Java 12
Java 12Java 12
Java 12
 
Padrões para Desenvolvimento de Software Guiado por Testes
Padrões para Desenvolvimento de Software Guiado por TestesPadrões para Desenvolvimento de Software Guiado por Testes
Padrões para Desenvolvimento de Software Guiado por Testes
 
Implementando Testes Unitários em Java - Manoel Pimentel
Implementando Testes Unitários em Java - Manoel PimentelImplementando Testes Unitários em Java - Manoel Pimentel
Implementando Testes Unitários em Java - Manoel Pimentel
 
Testes Unitários
Testes UnitáriosTestes Unitários
Testes Unitários
 
Palestra Testes De Unidade Com JUnit
Palestra Testes De Unidade Com JUnitPalestra Testes De Unidade Com JUnit
Palestra Testes De Unidade Com JUnit
 
Paletra sobre TDD, ocorrida no #DevDojo
Paletra sobre TDD, ocorrida no #DevDojoPaletra sobre TDD, ocorrida no #DevDojo
Paletra sobre TDD, ocorrida no #DevDojo
 
Treinamento Testes Unitários - parte 1
Treinamento Testes Unitários - parte 1Treinamento Testes Unitários - parte 1
Treinamento Testes Unitários - parte 1
 
Testes Unitários/Integrados
Testes Unitários/IntegradosTestes Unitários/Integrados
Testes Unitários/Integrados
 
Testes de software
Testes de softwareTestes de software
Testes de software
 
Testes de Sistema
Testes de SistemaTestes de Sistema
Testes de Sistema
 
TDD com Python
TDD com PythonTDD com Python
TDD com Python
 
Test-Driven Development (TDD) utilizando o framework xUnit.net
Test-Driven Development (TDD) utilizando o framework xUnit.netTest-Driven Development (TDD) utilizando o framework xUnit.net
Test-Driven Development (TDD) utilizando o framework xUnit.net
 
Testes Automatizados de Software
Testes Automatizados de SoftwareTestes Automatizados de Software
Testes Automatizados de Software
 
Introdução a testes automatizados
Introdução a testes automatizadosIntrodução a testes automatizados
Introdução a testes automatizados
 
Por que automatizar testes de software?
Por que automatizar testes de software?Por que automatizar testes de software?
Por que automatizar testes de software?
 
TDD Primeiro Contato
TDD Primeiro ContatoTDD Primeiro Contato
TDD Primeiro Contato
 
TDD na Prática
TDD na PráticaTDD na Prática
TDD na Prática
 
Apresentacao teste
Apresentacao testeApresentacao teste
Apresentacao teste
 
1° Madrugada de Testes
1° Madrugada de Testes1° Madrugada de Testes
1° Madrugada de Testes
 
Apresentacao Testes de Unidade
Apresentacao Testes de UnidadeApresentacao Testes de Unidade
Apresentacao Testes de Unidade
 

Destaque (20)

Síndrome+..
Síndrome+..Síndrome+..
Síndrome+..
 
Tutorial
TutorialTutorial
Tutorial
 
WebQuest
WebQuestWebQuest
WebQuest
 
Ponto de Ônibus para Florianópolis
Ponto de Ônibus para FlorianópolisPonto de Ônibus para Florianópolis
Ponto de Ônibus para Florianópolis
 
IstoÉ Dinheiro - Classe C vai às compras
IstoÉ Dinheiro - Classe C vai às comprasIstoÉ Dinheiro - Classe C vai às compras
IstoÉ Dinheiro - Classe C vai às compras
 
Memorias nal mayores
Memorias nal mayoresMemorias nal mayores
Memorias nal mayores
 
Design fachada e Método Gabarito
Design fachada e Método GabaritoDesign fachada e Método Gabarito
Design fachada e Método Gabarito
 
Mesa Redonda sobre Exportação de Software - B2B Set02
Mesa Redonda sobre Exportação de Software - B2B Set02Mesa Redonda sobre Exportação de Software - B2B Set02
Mesa Redonda sobre Exportação de Software - B2B Set02
 
Licao 05 A RealizaçãO Sexual No Casamento
Licao 05 A RealizaçãO Sexual No CasamentoLicao 05 A RealizaçãO Sexual No Casamento
Licao 05 A RealizaçãO Sexual No Casamento
 
27ª reunião vereadores
27ª reunião vereadores27ª reunião vereadores
27ª reunião vereadores
 
Jornalismo Cient
Jornalismo CientJornalismo Cient
Jornalismo Cient
 
Funcionamento da lingua
Funcionamento da linguaFuncionamento da lingua
Funcionamento da lingua
 
H.s.s.t pedro fonseca
H.s.s.t pedro fonsecaH.s.s.t pedro fonseca
H.s.s.t pedro fonseca
 
Matematica
MatematicaMatematica
Matematica
 
Felipe fernandes foucault
Felipe fernandes foucaultFelipe fernandes foucault
Felipe fernandes foucault
 
Ejercicio 2 luly
Ejercicio 2 lulyEjercicio 2 luly
Ejercicio 2 luly
 
C:\Fakepath\A Mente
C:\Fakepath\A  MenteC:\Fakepath\A  Mente
C:\Fakepath\A Mente
 
Ilha do Pico
Ilha do PicoIlha do Pico
Ilha do Pico
 
Mídia Kit - Extensão Sala de Artes
Mídia Kit - Extensão Sala de ArtesMídia Kit - Extensão Sala de Artes
Mídia Kit - Extensão Sala de Artes
 
Luis Lugo Diario la nacion nota
Luis Lugo Diario la nacion notaLuis Lugo Diario la nacion nota
Luis Lugo Diario la nacion nota
 

Semelhante a Introdução a tdd

ybr789try
ybr789tryybr789try
ybr789tryteste
 
1 2 3 - Testando - Automatizando os testes de software
1 2 3 - Testando - Automatizando os testes de software1 2 3 - Testando - Automatizando os testes de software
1 2 3 - Testando - Automatizando os testes de softwareHeider Lopes
 
Desenvolvimento Dirigido por Testes
Desenvolvimento Dirigido por TestesDesenvolvimento Dirigido por Testes
Desenvolvimento Dirigido por TestesCamilo Ribeiro
 
ALM - Testes Manuais no Microsoft Test Manager
ALM - Testes Manuais no Microsoft Test ManagerALM - Testes Manuais no Microsoft Test Manager
ALM - Testes Manuais no Microsoft Test ManagerAlan Carlos
 
Teste de Integração - Unidade III
Teste de Integração - Unidade IIITeste de Integração - Unidade III
Teste de Integração - Unidade IIIJoão Lourenço
 
Minicurso - Técnicas de Teste e Automatização do Teste de Unidade XII SemanaT...
Minicurso - Técnicas de Teste e Automatização do Teste de Unidade XII SemanaT...Minicurso - Técnicas de Teste e Automatização do Teste de Unidade XII SemanaT...
Minicurso - Técnicas de Teste e Automatização do Teste de Unidade XII SemanaT...Claudinei Brito Junior
 
Testes de Unidade com Junit
Testes de Unidade com JunitTestes de Unidade com Junit
Testes de Unidade com Junitcejug
 
Workshop - Plano de Testes End to End com o Microsoft Test Manager
Workshop   - Plano de Testes End to End com o Microsoft Test ManagerWorkshop   - Plano de Testes End to End com o Microsoft Test Manager
Workshop - Plano de Testes End to End com o Microsoft Test ManagerAlan Carlos
 
Aula12 T EES UFS Testes de SW
Aula12  T EES  UFS  Testes de SWAula12  T EES  UFS  Testes de SW
Aula12 T EES UFS Testes de SWguest8ae21d
 
Noções em teste de software e introdução a automação
Noções em teste de software e introdução a automaçãoNoções em teste de software e introdução a automação
Noções em teste de software e introdução a automaçãoSandy Maciel
 

Semelhante a Introdução a tdd (20)

Test driven development
Test driven developmentTest driven development
Test driven development
 
ybr789try
ybr789tryybr789try
ybr789try
 
1 2 3 - Testando - Automatizando os testes de software
1 2 3 - Testando - Automatizando os testes de software1 2 3 - Testando - Automatizando os testes de software
1 2 3 - Testando - Automatizando os testes de software
 
Testes de Software.ppt
Testes de Software.pptTestes de Software.ppt
Testes de Software.ppt
 
Desenvolvimento Dirigido por Testes
Desenvolvimento Dirigido por TestesDesenvolvimento Dirigido por Testes
Desenvolvimento Dirigido por Testes
 
ALM - Testes Manuais no Microsoft Test Manager
ALM - Testes Manuais no Microsoft Test ManagerALM - Testes Manuais no Microsoft Test Manager
ALM - Testes Manuais no Microsoft Test Manager
 
O que é Teste de Software?
O que é Teste de Software?O que é Teste de Software?
O que é Teste de Software?
 
Testes de Sofware
Testes de SofwareTestes de Sofware
Testes de Sofware
 
Introdução ao design de teste de software
Introdução ao design de teste de softwareIntrodução ao design de teste de software
Introdução ao design de teste de software
 
Teste de Integração - Unidade III
Teste de Integração - Unidade IIITeste de Integração - Unidade III
Teste de Integração - Unidade III
 
Testes de Unidade com JUnit
Testes de Unidade com JUnitTestes de Unidade com JUnit
Testes de Unidade com JUnit
 
Minicurso - Técnicas de Teste e Automatização do Teste de Unidade XII SemanaT...
Minicurso - Técnicas de Teste e Automatização do Teste de Unidade XII SemanaT...Minicurso - Técnicas de Teste e Automatização do Teste de Unidade XII SemanaT...
Minicurso - Técnicas de Teste e Automatização do Teste de Unidade XII SemanaT...
 
Programação Defensiva
Programação DefensivaProgramação Defensiva
Programação Defensiva
 
Unit Testing
Unit TestingUnit Testing
Unit Testing
 
TDD com Python (Completo)
TDD com Python (Completo)TDD com Python (Completo)
TDD com Python (Completo)
 
Testes de Unidade com Junit
Testes de Unidade com JunitTestes de Unidade com Junit
Testes de Unidade com Junit
 
Workshop - Plano de Testes End to End com o Microsoft Test Manager
Workshop   - Plano de Testes End to End com o Microsoft Test ManagerWorkshop   - Plano de Testes End to End com o Microsoft Test Manager
Workshop - Plano de Testes End to End com o Microsoft Test Manager
 
Aula12 T EES UFS Testes de SW
Aula12  T EES  UFS  Testes de SWAula12  T EES  UFS  Testes de SW
Aula12 T EES UFS Testes de SW
 
Aula12 TEES UFS Testes de SW
Aula12 TEES UFS Testes de SWAula12 TEES UFS Testes de SW
Aula12 TEES UFS Testes de SW
 
Noções em teste de software e introdução a automação
Noções em teste de software e introdução a automaçãoNoções em teste de software e introdução a automação
Noções em teste de software e introdução a automação
 

Mais de Fabrício Vargas Matos

Python ES 2017 - Introdução ao Tensorflow
Python ES 2017 - Introdução ao TensorflowPython ES 2017 - Introdução ao Tensorflow
Python ES 2017 - Introdução ao TensorflowFabrício Vargas Matos
 
A tecnologia blockchain (cryptoledger) e ecossistema disruptivo “pós-cloud”
A tecnologia blockchain (cryptoledger) e ecossistema disruptivo “pós-cloud” A tecnologia blockchain (cryptoledger) e ecossistema disruptivo “pós-cloud”
A tecnologia blockchain (cryptoledger) e ecossistema disruptivo “pós-cloud” Fabrício Vargas Matos
 
iMasters Developer Week Vitória - Dev Front-end em Startups
iMasters Developer Week Vitória - Dev Front-end em Startups iMasters Developer Week Vitória - Dev Front-end em Startups
iMasters Developer Week Vitória - Dev Front-end em Startups Fabrício Vargas Matos
 
Meetup Bitcoin Vitoria #1 - Empreendedorismo em Bitcoin
Meetup Bitcoin Vitoria #1 - Empreendedorismo em BitcoinMeetup Bitcoin Vitoria #1 - Empreendedorismo em Bitcoin
Meetup Bitcoin Vitoria #1 - Empreendedorismo em BitcoinFabrício Vargas Matos
 
Meetup Bitcoin Vitoria 2 - Como a blockchain funciona
Meetup Bitcoin Vitoria 2 - Como a blockchain funcionaMeetup Bitcoin Vitoria 2 - Como a blockchain funciona
Meetup Bitcoin Vitoria 2 - Como a blockchain funcionaFabrício Vargas Matos
 
Google I/O Vitoria - Resumo da abertura
Google I/O Vitoria - Resumo da aberturaGoogle I/O Vitoria - Resumo da abertura
Google I/O Vitoria - Resumo da aberturaFabrício Vargas Matos
 
Google I/O Vitoria - Estudo de caso do App Fixity
Google I/O Vitoria - Estudo de caso do App FixityGoogle I/O Vitoria - Estudo de caso do App Fixity
Google I/O Vitoria - Estudo de caso do App FixityFabrício Vargas Matos
 
Google I/O Vitoria - Manipulando numeros de telefone
Google I/O Vitoria - Manipulando numeros de telefoneGoogle I/O Vitoria - Manipulando numeros de telefone
Google I/O Vitoria - Manipulando numeros de telefoneFabrício Vargas Matos
 

Mais de Fabrício Vargas Matos (10)

Python ES 2017 - Introdução ao Tensorflow
Python ES 2017 - Introdução ao TensorflowPython ES 2017 - Introdução ao Tensorflow
Python ES 2017 - Introdução ao Tensorflow
 
Workshop Bitcoin 101 - Links
Workshop Bitcoin 101 - LinksWorkshop Bitcoin 101 - Links
Workshop Bitcoin 101 - Links
 
A tecnologia blockchain (cryptoledger) e ecossistema disruptivo “pós-cloud”
A tecnologia blockchain (cryptoledger) e ecossistema disruptivo “pós-cloud” A tecnologia blockchain (cryptoledger) e ecossistema disruptivo “pós-cloud”
A tecnologia blockchain (cryptoledger) e ecossistema disruptivo “pós-cloud”
 
iMasters Developer Week Vitória - Dev Front-end em Startups
iMasters Developer Week Vitória - Dev Front-end em Startups iMasters Developer Week Vitória - Dev Front-end em Startups
iMasters Developer Week Vitória - Dev Front-end em Startups
 
Meetup Bitcoin Vitoria #1 - Empreendedorismo em Bitcoin
Meetup Bitcoin Vitoria #1 - Empreendedorismo em BitcoinMeetup Bitcoin Vitoria #1 - Empreendedorismo em Bitcoin
Meetup Bitcoin Vitoria #1 - Empreendedorismo em Bitcoin
 
Meetup Bitcoin Vitoria 2 - Como a blockchain funciona
Meetup Bitcoin Vitoria 2 - Como a blockchain funcionaMeetup Bitcoin Vitoria 2 - Como a blockchain funciona
Meetup Bitcoin Vitoria 2 - Como a blockchain funciona
 
Google I/O Vitoria - Resumo da abertura
Google I/O Vitoria - Resumo da aberturaGoogle I/O Vitoria - Resumo da abertura
Google I/O Vitoria - Resumo da abertura
 
Google I/O Vitoria - Estudo de caso do App Fixity
Google I/O Vitoria - Estudo de caso do App FixityGoogle I/O Vitoria - Estudo de caso do App Fixity
Google I/O Vitoria - Estudo de caso do App Fixity
 
Google I/O Vitoria - Manipulando numeros de telefone
Google I/O Vitoria - Manipulando numeros de telefoneGoogle I/O Vitoria - Manipulando numeros de telefone
Google I/O Vitoria - Manipulando numeros de telefone
 
Tdd e zero defeito
Tdd e zero defeitoTdd e zero defeito
Tdd e zero defeito
 

Último

Programação Orientada a Objetos - 4 Pilares.pdf
Programação Orientada a Objetos - 4 Pilares.pdfProgramação Orientada a Objetos - 4 Pilares.pdf
Programação Orientada a Objetos - 4 Pilares.pdfSamaraLunas
 
ATIVIDADE 1 - ESTRUTURA DE DADOS II - 52_2024.docx
ATIVIDADE 1 - ESTRUTURA DE DADOS II - 52_2024.docxATIVIDADE 1 - ESTRUTURA DE DADOS II - 52_2024.docx
ATIVIDADE 1 - ESTRUTURA DE DADOS II - 52_2024.docx2m Assessoria
 
ATIVIDADE 1 - CUSTOS DE PRODUÇÃO - 52_2024.docx
ATIVIDADE 1 - CUSTOS DE PRODUÇÃO - 52_2024.docxATIVIDADE 1 - CUSTOS DE PRODUÇÃO - 52_2024.docx
ATIVIDADE 1 - CUSTOS DE PRODUÇÃO - 52_2024.docx2m Assessoria
 
Padrões de Projeto: Proxy e Command com exemplo
Padrões de Projeto: Proxy e Command com exemploPadrões de Projeto: Proxy e Command com exemplo
Padrões de Projeto: Proxy e Command com exemploDanilo Pinotti
 
ATIVIDADE 1 - GCOM - GESTÃO DA INFORMAÇÃO - 54_2024.docx
ATIVIDADE 1 - GCOM - GESTÃO DA INFORMAÇÃO - 54_2024.docxATIVIDADE 1 - GCOM - GESTÃO DA INFORMAÇÃO - 54_2024.docx
ATIVIDADE 1 - GCOM - GESTÃO DA INFORMAÇÃO - 54_2024.docx2m Assessoria
 
Luís Kitota AWS Discovery Day Ka Solution.pdf
Luís Kitota AWS Discovery Day Ka Solution.pdfLuís Kitota AWS Discovery Day Ka Solution.pdf
Luís Kitota AWS Discovery Day Ka Solution.pdfLuisKitota
 
ATIVIDADE 1 - LOGÍSTICA EMPRESARIAL - 52_2024.docx
ATIVIDADE 1 - LOGÍSTICA EMPRESARIAL - 52_2024.docxATIVIDADE 1 - LOGÍSTICA EMPRESARIAL - 52_2024.docx
ATIVIDADE 1 - LOGÍSTICA EMPRESARIAL - 52_2024.docx2m Assessoria
 
Boas práticas de programação com Object Calisthenics
Boas práticas de programação com Object CalisthenicsBoas práticas de programação com Object Calisthenics
Boas práticas de programação com Object CalisthenicsDanilo Pinotti
 

Último (8)

Programação Orientada a Objetos - 4 Pilares.pdf
Programação Orientada a Objetos - 4 Pilares.pdfProgramação Orientada a Objetos - 4 Pilares.pdf
Programação Orientada a Objetos - 4 Pilares.pdf
 
ATIVIDADE 1 - ESTRUTURA DE DADOS II - 52_2024.docx
ATIVIDADE 1 - ESTRUTURA DE DADOS II - 52_2024.docxATIVIDADE 1 - ESTRUTURA DE DADOS II - 52_2024.docx
ATIVIDADE 1 - ESTRUTURA DE DADOS II - 52_2024.docx
 
ATIVIDADE 1 - CUSTOS DE PRODUÇÃO - 52_2024.docx
ATIVIDADE 1 - CUSTOS DE PRODUÇÃO - 52_2024.docxATIVIDADE 1 - CUSTOS DE PRODUÇÃO - 52_2024.docx
ATIVIDADE 1 - CUSTOS DE PRODUÇÃO - 52_2024.docx
 
Padrões de Projeto: Proxy e Command com exemplo
Padrões de Projeto: Proxy e Command com exemploPadrões de Projeto: Proxy e Command com exemplo
Padrões de Projeto: Proxy e Command com exemplo
 
ATIVIDADE 1 - GCOM - GESTÃO DA INFORMAÇÃO - 54_2024.docx
ATIVIDADE 1 - GCOM - GESTÃO DA INFORMAÇÃO - 54_2024.docxATIVIDADE 1 - GCOM - GESTÃO DA INFORMAÇÃO - 54_2024.docx
ATIVIDADE 1 - GCOM - GESTÃO DA INFORMAÇÃO - 54_2024.docx
 
Luís Kitota AWS Discovery Day Ka Solution.pdf
Luís Kitota AWS Discovery Day Ka Solution.pdfLuís Kitota AWS Discovery Day Ka Solution.pdf
Luís Kitota AWS Discovery Day Ka Solution.pdf
 
ATIVIDADE 1 - LOGÍSTICA EMPRESARIAL - 52_2024.docx
ATIVIDADE 1 - LOGÍSTICA EMPRESARIAL - 52_2024.docxATIVIDADE 1 - LOGÍSTICA EMPRESARIAL - 52_2024.docx
ATIVIDADE 1 - LOGÍSTICA EMPRESARIAL - 52_2024.docx
 
Boas práticas de programação com Object Calisthenics
Boas práticas de programação com Object CalisthenicsBoas práticas de programação com Object Calisthenics
Boas práticas de programação com Object Calisthenics
 

Introdução a tdd

  • 1. Introdução ao Desenvolvimento Orientado a Testes (Test-DrivenDevelopment - TDD) Fabrício Matos Nov/2008
  • 2. TDD é uma técnica de desenvolvimento de software cujo processo é formado por pequenas iterações para o desenvolvimento de uma nova funcionalidade, começando pela implementação de um caso de teste, depois pelo código necessário para fazer o teste passar, e finalmente pela refatoração do código visando melhor acomodar as mudanças feitas. Não é um método para testar software, mas para construir software. TDD vem do conceito de “test-first programming” do XP (Extreme Programming), mas acabou ganhando tanto interesse, que hoje tem sido adotado independente do XP e das técnicas de programação ágil; Introdução Página 2
  • 3. Objetivo do TDD: “cleancodethat works” código limpo que funciona “Mantra” do TDD: vermelho-verde-refatorar Codifique o teste; Faça ele compilar e executar (não deve passar - vermelho); Implemente o requisito e faça o teste passar (verde); Refatore o código; Introdução Página 3
  • 4. Garante a existência de testes unitários completos e atualizados, que: Eliminam o medo de alterarmos alguma coisa que funciona (testada manualmente), e acabarmos introduzindo algum problema; Nos permite utilizar refatoração (substituir uma implementação por outra equivalente) de forma muito mais agressiva devido à facilidade dos testes verificarem o resultado. Diminui a quantidade de erros por linha de código (código-fonte de mais qualidade) Testes unitários servem como especificação de como os componentes do sistema funcionam; Nos leva a produzir componentes de software mais desacoplados, para garantir o isolamento dos testes, o que acaba favorecendo o projeto do sistema. Principais Benefícios do TDD Página 4
  • 5. Nosso foco é em produtos, e não em serviços, e os produtos precisam acompanhar as mudanças dos processos dos clientes, logo nossos sistemas estarão em constante evolução. Testes automáticos nos ajudarão pois: Evitarão efeitos colaterais nas futuras alterações. Documentarão bem o sistema para novos profissionais contratados. Permitirão a liberação de releases de muito maior qualidade. Erros reportados serão reproduzidos via caso de teste, corrigidos e nunca mais retornarão pois estarão cobertos pelo teste automático; Importância para Qualidata Página 5
  • 6. A Metodologia TDD Estudo de Caso: Aplicação do TDD na IBM Tese de Doutorado - MirkeyaCapellán(2006) Measuring Productivity and Code Quality: Test-Driven Development vs. Waterfall Construção de Casos de Testes com NUnit Considerações Finais Organização da Apresentação Página 6
  • 7. A Metodologia TDDBaseado principalmente emKent BeckTest-DrivenDevelopmentByExample, 2003 Página 7
  • 8. Testes de Unidade: Testa uma unidade mínima do software; Testes de Integração: Testa a comunicação entre os módulos; Testes de Sistema: Testa todo o sistema para verificar se atende aos requisitos; Testes de Integração de Sistema: Testa a comunicação do sistema com outros sistemas com os quais interage; Testes de Aceitação: Testes realizados pelo usuário final para verificar se o sistema faz o que ele espera; Tipos de Testes Página 8
  • 9. A Metodologia TDD é conduzida através dos “testes do programador”. Frequentemente esses testes são chamados de “teste de unidade”, mas esse nem sempre é o caso (pode ser teste de integração). É importante destacar que não se trata dos testes de sistema (caixa preta) nem os de aceitação (feitos pelo usuário final) Tipos de Testes Página 9
  • 10. A “Espiral da Morte” do Teste Página 10 O ciclo mortal do “estou sem tempo para testar”:
  • 11. 1. Construa testes isolados uns dos outros Um caso de teste não deve depender do sucesso de outro para funcionar; Deve ser possível executar um caso de testes isoladamente, sem executar nenhum outro; 2. Comece definindo uma “TestList” De modo geral para uma mesma classe ou método a ser testado, existirão diferentes casos de teste. Liste-os primeiro (brain-storm); Provavelmente ao longo do desenvolvimento você adicionará novos casos de teste à lista; Princípios Página 11
  • 12. Mas o que testamos? Fluxos Condicionais (IFs, Switches, etc.) Polimorfismos Loops Operações Etc.. Princípios Página 12
  • 13. Exemplo de “Lista de Testes” para o caso de uso “Realizar Transferência Bancária”: Realizar uma transferência normal (bem sucedida); Tentar transferir uma quantidade superior ao saldo da conta de origem; Verificar atomicidade no caso de falha de sistema antes de concluir a operação; Conta de origem inativa; Conta de destino inativa; Valor transferido menor que zero; Princípios Página 13
  • 14. Exemplo de “Lista de Testes” para o caso de uso “Matricular Aluno em Disciplina”: Matricular com sucesso; Tentar matricular sem atender disciplinas pré-requisito; Tentar matricular sem atender pré-requisito de crédito; Tentar matricular com conflito de horário; Tentar matricular sem vaga; Tentar matricular em disciplina já cumprida; Tentar matricular em disciplina que já está matriculada (outra turma); Tentar matricular em disciplina que já está matriculada (mesma turma); Princípios Página 14
  • 15. 3. Primeiro o Teste Oportunidade para pensar no design (projeto) das classes Controlar o escopo do que será implementado – somente o necessário para atender o teste corrente. 4. Primeiro a Assertiva É melhor pensarmos no que significa o sucesso do caso de teste antes de pensarmos no restante: Vou precisar de criar um novo método? Em qual classe? Qual será o nome dele e seus parâmetros? “Primeiro a assertiva” está para o caso de teste assim como “Primeiro o teste” está para o caso de uso; Princípios Página 15
  • 16. Exemplo: Testar o envio da string “Qualidata” através de um socket. Princípios Página 16 publicvoidTestarComunicacaoSocket() { Assert.IsTrue(readerSocket.Close()); Assert.AreEqual(“Qualidata”, buf); } publicvoidTestarComunicacaoSocket() { string buf = reader.Contents(); Assert.IsTrue(readerSocket.Close()); Assert.AreEqual(“Qualidata”, buf); } publicvoidTestarComunicacaoSocket() { SocketreaderSocket = newSocket(“localhost”, 8080); string buf = reader.Contents(); Assert.IsTrue(readerSocket.Close()); Assert.AreEqual(“Qualidata”, buf); } publicvoidTestarComunicacaoSocket() { Serverserver = newServer(8080, “”Qualidata”); SocketreaderSocket = newSocket(“localhost”, 8080); string buf = reader.Contents(); Assert.IsTrue(readerSocket.Close()); Assert.AreEqual(“Qualidata”, buf); }
  • 17. 5. Dados para Teste Não escolha números mágicos se eles não tiverem um significado específico no teste. Por exemplo, se não faz diferença utilizar “1”, “2” ou “1365”, preferia “1”. Evite passar o mesmo valor para diferentes parâmetros. Por exemplo, para testar um método Operacao(int x, int y), não utilize Operacao(2,2), pois “Operacao” pode inverter “x” e “y” e o teste ainda assim passar. Prefira, por exemplo, Operacao(2,3). Dê preferência a dados do mundo real, especialmente quando você tem algum sistema legado com dados que podem ser aproveitados Princípios Página 17
  • 18. 6. Dados com Significado Evidente Lembre que está escrevendo um teste para alguém ler, e não somente para ser executado pelo computador. Tente escrever na assertiva expressões que não só representem o valor final esperado, mas o que eles significam. Exemplo: Princípios Página 18 [Test] publicvoid Testar_Fatorial_8() { Assert.AreEqual(40320, Matematica.Fatorial(8)); } [Test] publicvoid Testar_Fatorial_8() { Assert.AreEqual(8 * 7 * 6 * 5 * 4 * 3 * 2, Matematica.Fatorial(8)); }
  • 19. Trata sobre quando escrever, onde escrever e quando parar de escrever testes. Qual o próximo teste da lista a implementar? Escolha um teste que você esteja confiante que pode implementá-lo facilmente; Não comece pelo teste mais realístico (completo), pois você será forçado a implementar um monte de coisas para atender o teste. Siga na direção “mais conhecidos” para “pouco conhecidos” Cada iteração “red/green/refactor” deve levar apenas alguns minutos. Exercício: Se você estiver construindo uma lista encadeada, qual seria seu primeiro caso de teste? “Red Bar Patterns” Página 19
  • 20. Testes de Estudo Devemos escrever testes para componentes ou bibliotecas de terceiros que, supostamente, funcionam? Sim. Para estudar e documentar seu uso. Esse é uma forma de assegurar-se sobre como utilizar tal biblioteca de forma a obter os resultados esperados e documentar seu uso (considerando especificamente suas necessidades, e não todos os recursos da biblioteca). “Red Bar Patterns” Página 20
  • 21. Testes de Outras Funcionalidades Sempre que uma discussão desviar do assunto principal e entrar em outras questões, essa pode ser uma hora de adicionar novos casos de teste à sua lista (para a funcionalidade em questão) e voltar para o assunto principal. Sim. Para estudar e documentar seu uso. Esse é uma forma de assegurar-se sobre como utilizar tal biblioteca de forma a obter os resultados esperados e documentar seu uso (considerando especificamente suas necessidades, e não todos os recursos da biblioteca). “Red Bar Patterns” Página 21
  • 22. Defeitos Reportados Sempre que um defeito é reportado nossa primeira ação deve ser escrever um caso de teste que reproduza o problema. Se isso for feito certamente o problema será resolvido. Testes de Regressão Consiste em testar novamente uma funcionalidade que foi implementada e testada anteriormente; Teoricamente, após qualquer alteração no sistema, todo o sistema deveria ser testado para garantir que essa alteração não tenha introduzido algum efeito colateral indesejável. Uma boa prática é executar testes de regressão de todo o sistema, todos os dias, à noite, e reportar os problemas encontrados para a equipe. Existem softwares para gerenciar isso. “Red Bar Patterns” Página 22
  • 23. Técnicas mais detalhadas sobre como escrever testes. Subdividir Testes Quando um teste ficou grande demais e você está demorando muito para conseguir implementá-lo (mais de 10 min já deve te encomodar), pode ser melhor dividir o teste em testes menores até conseguir fazer o teste maior passar. MockObjects Como testar objetos que dependem de recursos externos custosos ou complexos, como bancos de dados e webservices, por exemplo? Crie uma versão falsa ou simulada do objeto (“fake”) que retorne valores constantes. Referência: www.mockobjects.com Ferramentas para .NET: NMock e RhinoMocks. “TestingPatterns” Página 23
  • 24. Log String Como testar se uma sequência de métodos foi chamada numa certa ordem? Guarde um log (trace log) de cada execução dos métodos chamados em uma string e compare com o valor esperado. Teste de Falhas Precisamos assumir que “código que não foi testado não funciona”. Mas como testar falhas que são difíceis de se reproduzir (disco cheio, falha de comunicação, etc.)? “Fake it!”, ou seja, construa uma nova classe que gere a exceção e simule a falha. “TestingPatterns” Página 24
  • 25. Desenvolvendo Sozinho – Teste Quebrado Se você está desenvolvendo uma software sozinho, é sempre melhor encerrar uma sessão de programação deixando um teste vermelho(incompleto). Isso agiliza a continuação do trabalho no próximo dia. Desenvolvimento em Equipe – Testes Rodando Se você trabalha em equipe, não faça check-in de testes vermelhos. Isso vai ser ruim pois todos vão achar que há um requisito que foi “estragado”, enquanto na verdade ele ainda não foi finalizado. Ao subir suas alterações (check-in), rode todos os testes para garantir a integração entre os módulos. Se os testes não forem muito lentos, procure rodar todos os testes em sua própria estação para antecipar problemas de integração. “TestingPatterns” Página 25
  • 26. Uma vez que você tenha um teste vermelho, busque torná-lo verde o quanto antes. Use os padrões que serão discutidos para conseguir isso rapidamente, mesmo que o resultado seja algo que você não aceita conviver nem por uma hora. “Green Bar Patterns” Página 26
  • 27. “Fake it ‘til youmake it” (simule até construir realmente) Por exemplo, qual é a forma mais simples de implementar o código abaixo? A forma mas direta seria: “Green Bar Patterns” Página 27 publicvoidTestarSoma() { Assert.AreEqual(5, Somar(2,3)); } publicvoidTestarSoma() { Assert.AreEqual(5, Somar(2,3)); } publicint Somar(int x, int y) { return 5; }
  • 28. Triangulação Quando você tem dois ou mais testes, você precisa de uma implementação que atenda a todos simultaneamente. Agora a solução trivial (constante) não atende mais, e somos forçados e implementar algo mais abrangente. É claro que esse exemplo é apenas ilustrativo. Se você já tem uma implementação correta óbvia, então implemente. Senão, “fake it”. “Green Bar Patterns” Página 28 publicvoidTestarSoma() { Assert.AreEqual(5, Somar(2,3)); Assert.AreEqual(7, Somar(3,4)); }
  • 29. Implementação Óbvia Se você consegue implementar algo diretamente, então implemente. Para que utilizar “fake” ou triangulação? Mas quando você achar que sabe implementar e se deparar com uma barra vermelha? Depois você descobre, errei aqui, e aí outra barra vermelha! Talvez seja hora de dividir o problema em problemas menores. Acreditar que você sempre vai conseguir acertar e escrever o código mais simples para o problema diretamente é exigir de você perfeição. “TestingPatterns” Página 29
  • 30. Operações Sobre Coleções Implemente primeiro o teste para a operação recebendo um elemento; Depois estenda para a operação recebendo a coleção; Testes de Exceções Como testar se em determinadas condições uma exceção é gerada? Use try ... Teste ... Assert.IsTrue(false) ... catch ... Ou use algum recurso específico do seu framework de testes (um “xUnit” da vida), se houver: “TestingPatterns” Página 30 [ExpectedException(typeof(QException), "O atributo Pessoa.Nome não pode ser nulo.")] publicvoidTestarNomeNaoNulo() { Pessoa p = new Pessoa(); Conexao.Save(p); }
  • 31. É muito importante pensar em “design patterns” ao projetar seu software; Em TDD, “projeto” (design) não é exatamente uma fase, mas parte do processo “vermelho-verde-refatorar”. Nesse sentido eles recebem um olhar um pouco diferente em TDD. Apenas para ilustrar, vamos destacar um “design patterns” bem interessante. “Design Patterns” Página 31
  • 32. Objeto NULL Quantas vezes você já viu uma “nullreference exception”? Quantas vezes você precisou proteger o seu código com um “if (obj != null) ...” ? Ao invés de retornar “null”, pode ser melhor retornar um objeto especial, com a mesma interface, mas que não gere problemas. Exemplo (java.io.File): “Design Patterns” Página 32 publicbooleansetReadOnly() { SecurityManagerguard = System.getSecurityManager(); if (guard != null) { guard.canWrite(path); } returnfileSystem.setReadOnly(this); } publicstaticSecurityManagergetSecurityManager() { returnsecurity; //pode ser null } publicbooleansetReadOnly() { SecurityManagerguard = System.getSecurityManager(); guard.canWrite(path); returnfileSystem.setReadOnly(this); } publicstaticSecurityManagergetSecurityManager() { returnsecurity == null ? newSecurityLiberadoGeral() : security; }
  • 33. Refatorar é melhorar o “design” de funcionalidades do sistema, sem alterar seu comportamento; Em TDD, devemos refatorar mantendo todos os testes “verdes”; Em TDD, primeiro pensamos em resolver o problema da Por que refatorar o código? Para torná-lo mais legível; Para facilitar sua manutenção, seja na correção de bugs ou na adição de novas funcionalidades, aumentado assim sua vida útil; Para ajustar decisões de projeto estejam impactando negativamente o sistema (limitando, deixando lento, etc..) Para buscar o “clean” de “cleancodethat works” Embora seja um assunto que possa ser trabalhado de forma mais específica, trabalharemos alguns exemplos de técnicas de refatoração de código. “Refactoring” Página 33
  • 34. Reconcilie Diferenças Se duas partes do código poderem ser iguais, então poderemos eliminar uma delas; Dois loops poderiam ser fundidos em um só; Se dois caminhos em um condicional forem iguais, poderemos eliminar a condição; Se dois métodos foram iguais, podemos eliminar um; Se duas classes forem iguais, podemos eliminar uma; “Refactoring” Página 34
  • 35. Isole as Alterações Se você precisa alterar uma parte específica de um método divido em partes (seções), primeiro isole essa parte (refatoração) e depois faça a alteração; Migrar Dados Como migrar dados de uma estrutura para outra? (Por exemplo, de um DataSet para uma lista) Duplique os dados primeiro criando uma nova variável (mantenha o DataSet e crie também a lista) Inicialize também a nova variável (lista) em todo lugar que a antiga (DataSet) é inicializada; Substitua a implementação para que seja utilizada a nova estrutura variável (lista) ao invés da antiga (DataSet) Elimine a variável da estrutura original (o DataSet). Entre todos esses passos os testes não devem deixar de permanecer verde. “Refactoring” Página 35
  • 36. Extraia Métodos Simplifique métodos muito longos, criando métodos menores (variáveis locais utilizadas também fora do trecho devem virar parâmetros) Não se deve ir tão longe ao ponto de criar tantas indireções que acabem dificultando a leitura. Blocos de código com aquele típico comentário no início são excelentes candidatos a novos métodos. Exemplo: “Refactoring” Página 36 //Verifica se o aluno atende a todos os pré-requisitos para ser matriculado linha 1 linha 2 ... linha N
  • 37. Métodos “Inline” Esse é o ato de substituir uma chamada de um método pelo seu conteúdo (o oposto da técnica anterior) Isso é especialmente útil quando você está tendo dificuldade de entender um código confuso, cheio de indireções. Nesses casos pode ser melhor simplesmente desfazer (via “inline”) algumas camadas de abstração, entender o que o código faz, e depois repensar a melhor forma de reorganizá-lo. “Refactoring” Página 37
  • 38. Mover Métodos Como mover métodos para outros “lugares” sem exigir uma alteração imediata em todos as suas chamadas? Crie o novo método no lugar que deseja; Mova o conteúdo do método; No método original, faça uma chamada ao novo método, repassando os parâmetros. Adicionar Novo Parâmetro Pode ser visto como um caso de “Migrar Dados” Também pode ser utilizado o próprio compilador para mostrar onde será necessário alterar sua chamada; “Refactoring” Página 38
  • 39. Mover Parametros de Métodos para Construtores Por que? Se você passa o mesmo parâmetro para vários métodos de uma classe, pode ser melhor passá-lo uma única vez em seu constructor, e simplificar as chamadas dos métodos; Como? Adicione o parâmetro ao constructor; Adicione uma nova variável de instância com o mesmo nome do parâmetro, e inicialize ela no constructor; Um por um, converta todas as ocorrências de “parametro” nos métodos por “this.parametro”. “Refactoring” Página 39
  • 40. Mover Parametros de Métodos para Construtores (...continuação) Quando não houver mais referências a “parametro”, elimine-o da assinatura do método e de todas suas chamadas; Remova o “this.” que agora é supérfluo; Renomeie a variável de instância apropriadamente. “Refactoring” Página 40
  • 41. Qual o tamanho ideal dos passos “vermelho-verde-refatorar”? Você pode escrever testes que vão te levar a escrever uma única linha de código; Também pode escrever testes que vão te levar à escrever centenas de linha de código; Não há uma regra, mas a tendência dos experientes em TDD é clara: Passos pequenos. “Mastering TDD” Página 41
  • 42. Características de um bom teste Se você tem dificuldade para identificar um lugar comum para inicializações compartilhadas, então você deve ter um problema de projeto – muitos objetos entrelaçados. Quanto feedback (asserts) você precisa? Depende. Por exemplo, pode ser muito improvável um problema de diskfull, e você está confiante que esse é um teste desnecessário no cenário do software em questão. “Mastering TDD” Página 42
  • 43. Quando excluir um teste? Quanto mais testes, melhor; Se dois testes fazem a mesma coisa, pode ser, mas considere: Na dúvida, não exclua; Se os dois testes seguem o mesmo fluxo de execução, mas comunicam (documentam) questões diferentes, deixe-os assim. TDD é Escalável? O maior sistema totalmente TDD que o autor participou foi na LifeWare: 40 pessoas, por 4 anos 250KLOC de código funcional 250KLOC de código de teste 4000 testes que levam 20min para executar “Mastering TDD” Página 43
  • 44. Como iniciar TDD em um sistema desenvolvido sem Testes Automatizados? Muitos livros ainda precisam ser escritos sobre isso; Um primeiro problema é que código que não foi escrito pensando nos testes é difícil de ser testado; Outro problema é que alterações nesse código são perigosas pois não temos os testes para garantir que tudo continua funcionando; O ideal seria primeiramente implementar testes automáticos para todo o sistema e depois partir para desenvolver as novas funcionalidades com TDD; Outra opção é explorar outras formas de feedback, como testes de nível de aplicação, que garanta certo nível de confiança. “Mastering TDD” Página 44
  • 45. A Metodologia TDD Estudo de Caso: Aplicação do TDD na IBM Tese de Doutorado - MirkeyaCapellán (2006) Measuring Productivity and Code Quality: Test-Driven Development vs. Waterfall Construção de Casos de Testes com NUnit Considerações Finais Organização da Apresentação Página 45
  • 46. Baseado no artigo: [1] E. M. Maximilien and L. Williams, "Assessing test-driven development at IBM", Proceedings of the 25th International Conference on Software Engineering pp. 564-569, Portland, Oregon, USA, IEEE Computer Society, 2003. O sistema: JavaPOS (www.javapos.com) Um conjunto de serviços (JavaBeans) para permitir o acesso a dispositivos POS (pointofsale), tais como impressoras, caixas (dinheiro), leitores magnéticos, etc.. Implementado através de uma parceria da IBM, NCR, Epson e Sun. TDD na IBM Página 46
  • 47. Motivação Implementação do JavaPOS original (sem TDD) contava com uma equipe que conehcia muito bem suas especificações e tinha grande experiência com dispositivos POS; Em cada fase de FVT (Functional Verification Test), executada antes de cada novo release, a taxa de defeitosnãodiminuíacomoesperado. Porissodesenvolvedores e gerentesestavamabertos a novas abordagens. TDD na IBM Página 47
  • 48. Experiência Anterior com Testes Criavam algumas classes de teste de forma ad-hoc para partes mais importantes do código; O processo de construção de testes não era sistemático, sendo uma atividade pós-desenvolvimento; Na maioria das vezes, nenhum teste era criado. Especialmente quando os cronogramas estavam apertados, os desenvolvedores precisavam parar para resolver problemas de desenvolvimentos anteriores, ou ainda os novos requisitos não estavam muito claros TDD na IBM Página 48
  • 49. Experiência Anterior com Testes (cont.) A maioria dos testes de unidade eram desperdiçados; Eles não eram executados na fase de verificação funcional (FVT) Também não eram aproveitados em versões posteriores (novos releases) do software; Não tinham qualquer experiência com TDD. TDD na IBM Página 49
  • 50. Adoção da Metodologia TDD - No início havia muitas dúvidas: Taxa de Defeitos – Como TDD vai afetar a taxa de defeitos a curto prazo (próximo release) e a longo prazo (futuros releases)? Produtividade - Qual será o impacto? Trabalhavam com uma média de 400LOC / pessoa-mês. Frequência dos Testes – Qual será o percentual de testes automatizados em relação a testes iterativos? Quão frequentemente cada tipo de teste será executado? Projeto – Como TDD vai afetar a qualidade do projeto (design)? Eles avaliam isso através da capacidade de lidar com requisitos identificados tardiamente, ou a inclusão de novos dispositivos ou serviços. Integração – TDD e seus testes de regressão automatizados irão suavizar os processos de integração? TDD na IBM Página 50
  • 51. O Trabalho com TDD No início muitos desenvolvedores e gerentes estavam preocupados pois uma metodologia tão rigorosa poderia afetar a produtividade a ponto de inviabilizar a manutenção dos cronogramas existentes. Apesar das metodologias ágeis sugerirem nenhum projeto a priori, no javaPOS os requisitos eram bem estáveis, e a equipe optou por desenvolver diagramas de classes e de sequência; Acrescentaram nas atividades de projeto, além dos diagramas UML, a criação de casos de teste (teste de sistema); TDD na IBM Página 51
  • 52. O Trabalho com TDD Para cada classe pública A, tinham uma classe TesteA, e para cada método de A, métodos de teste correspondentes em TesteA. Havia casos em que era necessário tratar cenários diferentes do mesmo caso de teste. Por exemplo, impressoras que trabalhavam de modo síncrono ou assíncrono, exigiam casos de teste específicos para cada cenário; Definiram como meta um mínimo de 80% de cobertura de teste automatizado (o restante poderia ser testes iterativos); TDD na IBM Página 52
  • 53. O Trabalho com TDD Cada documento de especificação de projeto continha uma secção de testes descrevendo todas as classes e métodos importantes que deveriam ser testados; Diariamente todo código era compilado automaticamente, e todos os testes executados. Para cada build, um email era enviado para cada membro da equipe com a lista de testes executados e eventuais erros encontrados. Em um primeiro momento, esses builds eram gerados várias vezes por dia; TDD na IBM Página 53
  • 54. TDD na IBM Página 54
  • 55. Resultados Números do Projeto: 71.4 KLOC de código de negócio e 34 KLOC de código Junit; Densidade de erros, que normalmente é de 8 erros/KLOC foi de 4 erros/KLOC (50% de redução) OBS: Atualmente, devido ao TDD, nossa densidade média de erros é de 3.7 erros/KLOC. Foram escritos 2390 casos de teste JUnit. Outros 100 testes foram escritos para avaliar performance; TDD na IBM Página 55
  • 56. Resultados Taxa de Defeitos – Com TDD, os testes automatizados realmente foram feitos. Como resultado obtiveram um excelente redução de 50% de defeitos na fase de verificação funcional (FVT) Produtividade – Não só manteve-se dentro dos cronogramas, como obtiveram uma pequena melhoria em relação à média de 400LOC/pessoa-mês; Frequência dos Testes – Escreveram aproximadamente 2500 testes automáticos e 400 testes iterativos, ou seja, 86% de cobertura de teste automático, acima da meta de 80%. Projeto – Acreditam que TDD ajudou a produzir um sistema que recebe mais facilmente mudanças. Inclusive alguns dispositivos foram incluídos no projeto quando o mesmo já tinha avançado mais de 2/3 do cronograma. Integração – Antes integravam somente próxima à fase de FVT. Com TDD e integrações (builds) diários, diminuíram muito os riscos pois problemas aparecem bem mais cedo. TDD na IBM Página 56
  • 57. Lições aprendidas sobre a transição para TDD: Comece TDD no início do projeto; Ajuste as expectativas da equipe pois no início TDD parece menos produtivo e frustrante pelo tempo que se leva para criar os testes; Na prática, no final das contas, não haverá impacto negativo na produtividade. Para uma equipe nova em TDD, inicie builds diários mais adiante um pouco. Não muito cedo nem muito tarde (após 1/3 do cronograma, por exemplo). Enquanto isso cada um deve executar os seus testes em sua estação. TDD na IBM Página 57
  • 58. Lições aprendidas sobre a transição para TDD: Convença a equipe de adicionar novos casos de tese sempre que um problema for encontrado, não importando onde seja. Isso vai garantir a solução do problema em algum momento à frente; Definimos 80% de cobertura como um objetivo mínimo. É extremamente importante os builds diários automáticos. Eles se tornam a batida que dá o ritmo ao projeto e ao mesmo tempo facilita acompanharmos seu progresso; Encorage a construção de testes que executem rapidamente e de projeto eficiente; Aproveite sempre para encorajar a equipe a escrever mais testes, por exemplo, monitorando qual subsistema tem mais testes implementados. TDD na IBM Página 58
  • 59. A Metodologia TDD Estudo de Caso: Aplicação do TDD na IBM Tese de Doutorado - MirkeyaCapellán (2006) Measuring Productivity and Code Quality: Test-Driven Development vs. Waterfall Construção de Casos de Testes com NUnit Considerações Finais Organização da Apresentação Página 59
  • 60. Experimento 24 profissionais de 3 empresas trabalhando em pares. Metade com TDD e a outra metade seguindo um Modelo em Cascata. Apenas uma empresa tinha experiência prévia com TDD; Resultados: TDD produziu um código de mais qualidade do que o Modelo Cascata 18% a mais de sucesso em testes de caixa preta 80% mais eficaz em termos de qualidade de código TDD teve um tempo total de desenvolvimento bem menor: O de programação, especificamente, foi 16% maior; O projeto como um todo foi 78% mais podutivo; Programadores acharam TDD uma forma mais simples de projetar software; Transição para TDD foi difícil TDD versus ModeloCascata Página 60
  • 61. A Metodologia TDD Estudo de Caso: Aplicação do TDD na IBM Tese de Doutorado - MirkeyaCapellán (2006) Measuring Productivity and Code Quality: Test-Driven Development vs. Waterfall Construção de Casos de Testes com NUnit Considerações Finais Organização da Apresentação Página 61
  • 62. A Metodologia TDD Estudo de Caso: Aplicação do TDD na IBM Tese de Doutorado - MirkeyaCapellán (2006) Measuring Productivity and Code Quality: Test-Driven Development vs. Waterfall Construção de Casos de Testes com NUnit Considerações Finais Organização da Apresentação Página 62