Minha resposta para aqueles que acreditam que o valor do TDD é exagerado

Uma vez conversei com um desenvolvedor de uma empresa cliente sobre software. Devo entender que a conversa deu errado quando o interlocutor disse sobre como nós, os desenvolvedores de software, tivemos sorte: "Enganamos as organizações a nos pagar pelo que parece ser um trabalho simples". Não importa o quanto alguém tenha avançado na escrita de código, mas acredito que não vale a pena falar sobre toda a indústria de desenvolvimento de software como algo como uma gangue de golpistas.

Eu não me concentrei nisso, a conversa chegou ao Agile. O cliente, em geral, estava aberto à idéia de testar novas metodologias e melhorar seus processos de trabalho. Mas - somente até eu mencionar o desenvolvimento através de testes (TDD, Test-Driven Development). A única resposta para isso foi a seguinte frase: "O valor do TDD é exagerado".



Não foi apenas doloroso para mim ouvi-lo, mas me fez perceber que o TDD é outra daquelas metodologias ágeis que podem parecer uma espécie de "lenda urbana". Foi isso que me levou a escrever este material, no qual gostaria de apelar para aqueles que duvidam do valor do TDD.

O que é TDD?


Deixe-me começar definindo TDD. Essa é uma estratégia de desenvolvimento de software, durante a implementação da qual, ao criar um programa, elas são completamente guiadas pela elaboração de testes. De fato, isso é compreensível pelo nome dessa metodologia. Essa idéia foi proposta por Kent Beck em seu livro Development Through Testing, escrito em 2003. O uso do TDD envolve as três etapas a seguir:

  1. Escrevendo um teste que falha em uma pequena parte da funcionalidade.
  2. Implementação do funcional que leva à aprovação do teste.
  3. Refatorar código antigo e novo para mantê-lo em um estado bem estruturado e legível.

Esse processo também é conhecido como ciclo "Vermelho, Verde, Refatoração".

Aqui está um exemplo simples de uso do TDD. Aqui, queremos escrever um método em Python projetado para calcular uma variável Cpelo teorema de Pitágoras.

Aqui está o código de teste (arquivo test.py):

#!/usr/bin/env python

"""
test.py
"""

import unittest

from main import *

class TestDrivenDevelopment(unittest.TestCase):

        def test_pythagorean_theorem(self):
                a, b = 3, 4
                self.assertEqual(calculate_side_c(a, b), 5)

if __name__ == '__main__':
    unittest.main()

Aqui está o código do método ( main.py), no qual nada acontece até agora:

#!/usr/bin/env python

"""
main.py
"""

def calculate_side_c(side_a, side_b):
    return True

Agora tente executar o teste.


O teste falhou (a parte "Vermelha" do ciclo TDD)

Reescreva o código, trazendo o conteúdomain.pypara o seguinte formato:

#!/usr/bin/env python

"""
main.py
"""

def calculate_side_c(side_a, side_b):
    c_squared = (side_a * side_a) + (side_b * side_b)
    c = c_squared ** 0.5
    return c 

Execute o teste novamente.


O teste correu bem (a parte “Verde” do ciclo TDD)

Agoramain.pyrefatoramos ocódigo:

#!/usr/bin/env python

"""
main.py
"""

def calculate_side_c(side_a, side_b):
    return ((side_a ** 2) + (side_b ** 2)) ** 0.5


O teste foi bem-sucedido para o código sujeito à refatoração (Parte “Refatoração” do ciclo TDD)

17 anos se passaram desde a publicação do livro de desenvolvimento por meio de testes. Mas ainda hoje, em 2020, ainda não há uma resposta definitiva para a pergunta que é muito importante para muitas pessoas sobre se os benefícios do TDD valem o tempo e o esforço para implementar essa metodologia. Como resultado, muitos desenvolvedores nem tentam desenvolver através de testes.

Em apoio ao TDD, perguntei aos desenvolvedores por que eles não usavam essa metodologia. Aqui estão 4 respostas que eu ouvi com mais frequência:

  1. Temos um departamento de controle de qualidade. Escrever testes é o trabalho deles.
  2. Criar testes nos quais moki e stubs possam ser necessários pode levar muito tempo e energia.
  3. TDD não tem vantagens sobre o desenvolvimento convencional.
  4. TDD é lento.

Vamos analisar essas idéias.

Temos um departamento de controle de qualidade. Escrever testes é o trabalho deles


Esta resposta à minha pergunta sobre por que alguém não está usando TDD sempre me faz rir um pouco. Eu sou um grande defensor do princípio " Você constrói, executa ", quando quem escreveu o código é responsável por isso. Portanto, isso me incomoda quando vejo que os desenvolvedores se comportam como se sua única tarefa fosse escrever código funcional.

Estou profundamente convencido de que os desenvolvedores são responsáveis ​​por garantir que seu código tenha as seguintes qualidades:

  • Correção - atender às necessidades de negócios.
  • Clareza.
  • Testabilidade.
  • Extensibilidade.
  • Simplicidade.

A transferência da tarefa de escrever testes para o departamento de controle de qualidade, acredito, não pertence à lista de tarefas do desenvolvedor. Os especialistas do departamento de controle de qualidade têm assuntos mais importantes. Eles não devem gastar seu tempo de trabalho, principalmente, testando o código usando o método "caixa preta".

Criar testes nos quais moki e stubs podem ser necessários pode levar muito tempo e energia


Eu entendo os sentimentos daqueles que dizem isso. Por exemplo, você precisa implementar um método que aceite três valores de entrada diferentes. Cada um deles é um objeto e cada um desses objetos não possui atributos opcionais. Tudo isso precisa ser testado, verificando as diferentes opções para o método. Para fazer isso, você precisa configurar stubs e mokas , além de escrever uma grande quantidade de código adicional. E tudo isso é para testar apenas um método. Eu já estive em situações semelhantes. Mas eu vejo tudo isso de outra perspectiva.

Quando penso em reduzir o esforço e o tempo gasto na escrita de testes, venho com os princípios da programação SOLID e da pirâmide de testes.

Comece com o SOLID a partir daqui.. Aqui, gostaria de me debruçar sobre o fato de que na abreviatura SOLID é representada pela letra S, ou seja, no princípio da única responsabilidade (O princípio da responsabilidade única). Essa é uma ideia segundo a qual métodos e classes devem resolver apenas um problema. Eles devem funcionar para que suas atividades não afetem o resto do sistema.

Entendo que a maioria dos métodos no software corporativo executa tarefas mais difíceis do que encontrar a soma de vários números passados ​​para esses métodos. Mas não se pode negar o fato de que o uso de métodos destinados a resolver um problema em um projeto facilita muito o teste.

Vamos falar sobre a pirâmide de teste.


Pirâmide de teste (imagem obtida aqui )

A pirâmide de teste é frequentemente usada para encontrar a proporção correta de diferentes tipos de testes em um projeto.

Os testes de interface do usuário (testes da interface do usuário) e os testes de serviço (testes de serviço) exigem muito tempo para sua implementação. Portanto, a maior parte dos testes deve ser representada por testes de unidade (testes de unidade), uma vez que são necessários milissegundos para executar um número ainda grande desses testes. Obviamente, isso ajuda a melhorar o ciclo de feedback, que é um dos principais objetivos do DevOps.

A realização de testes de unidade para testar uma pequena parte do sistema também requer um nível muito mais baixo de integração com o restante do sistema. Isso facilita a escrita desses testes. A metodologia TDD é projetada exclusivamente para o uso de testes de unidade.

Obviamente, qualquer coisa é mais fácil dizer do que fazer e, para escrever a maioria dos testes, mesmo os testes de unidade, você precisa fazer algum esforço. No entanto, se parecer que escrever um teste de unidade exige muito esforço, você pode testar a si mesmo fazendo algumas perguntas:

  • É um teste modular, ou deve ser considerado como um teste de nível superior, como um teste de serviço?
  • O código está bem projetado, cada classe e método é consistente com o princípio de responsabilidade exclusiva (o código está muito bem acoplado)?

Se os testes de gravação exigirem muito tempo e esforço, isso geralmente indica que o código pode e provavelmente precisa ser refatorado.

TDD não tem vantagens sobre o desenvolvimento convencional


Ironicamente, o fato de o TDD não ter vantagens sobre o desenvolvimento convencional é dito principalmente pelos programadores que nem sequer tentaram trabalhar no estilo TDD. Mas até tentar algo, você não consegue entender se isso é bom ou ruim. Até a banda do Coldplay sabe que "se você nunca tentar, nunca saberá".

TDD tem dois pontos fortes principais.

A primeira vantagem do TDD é bastante óbvia. Se, antes de escrever um código de trabalho, alguém sempre escreve testes para esse código, então, por definição, o programador sempre tem um código de autoteste à sua disposição. Aqui está o que Martin Fowler escreve sobre isso: "Você tem um código de autoteste se pode executar uma sequência de testes automatizados em uma base de código e, após a conclusão bem-sucedida dos testes, pode ter certeza de que o código está livre de defeitos significativos".

Em outras palavras, usar TDD significa que o código funciona exatamente como o programador precisa.

Esse é um fato maravilhoso, pois confia seriamente na estabilidade do código a qualquer alteração adversa. O uso do TDD permite que o programador descubra instantaneamente se algo na base de código se deteriorou como resultado da refatoração ou extensão do código. Melhor ainda, ele permite saber se há algum erro no sistema.

O código de autoteste permite que as equipes de desenvolvimento aproveitem verdadeiramente os benefícios da integração contínua e dos sistemas de implantação de código.

A segunda principal vantagem do TDD é que essa metodologia de desenvolvimento faz com que os programadores, mesmo antes de escrever o código de trabalho, pensem sobre o que vão escrever e como vão escrever.

Pensar no código antes de escrever leva ao fato de que o desenvolvedor está realmente imerso na essência das necessidades dos negócios e leva em consideração casos limítrofes e possíveis dificuldades na implementação de mecanismos apropriados. Como resultado, ao escrever código de trabalho, o esforço é gasto exatamente no que você precisa. Além disso, o uso do TDD leva ao fato de que os desenvolvedores estão planejando um futuro sistema de dispositivos em termos de estrutura e arquitetura. Se essas coisas forem planejadas e levadas em consideração desde o início do trabalho no sistema, isso melhorará seriamente sua capacidade de escalar e expandir.

TDD está lento


Os desenvolvedores que dizem que o TDD é lento, geralmente aqueles que trabalham com essa metodologia há algum tempo e depois voltam a escrever testes que foram executados após a criação do código. Em geral, esse é o motivo mais frequentemente mencionado ao falar sobre por que alguém não usa TDD.

Eu também posso entender por que os programadores pensam assim. Pensar no código antes de escrever leva tempo. É gasto tempo na criação de testes para tudo o que está planejado para ser implementado, mesmo para métodos para os quais, em condições normais, os testes podem não ter sido gravados. Encontrar maneiras de usar efetivamente stubs e mobs também pode às vezes não ser a tarefa mais rápida e agradável.

A situação também é agravada pelo fato de que a produtividade e a eficiência dos programadores são frequentemente avaliadas em termos da velocidade de seu trabalho e do tempo gasto na criação do produto final. Tudo isso leva a equipe de programadores ao desejo de trabalhar o mais rápido possível, ao desejo de se encaixar nos horários apertados do trabalho.

Em este papel o sistema dos quatro indicadores para avaliar a eficácia de DevOps:

  1. Frequência de implantação.
  2. Alterar o tempo de execução.
  3. Tempo de recuperação do serviço.
  4. A frequência de falhas com alterações.

Estou particularmente interessado nos indicadores "Frequência de implantação" e "Frequência de falhas com alterações".

Ao usar o TDD, como eu disse, com base na suposição de que o sistema foi construído exclusivamente usando o TDD, a equipe de desenvolvimento, imediatamente após fazer uma alteração no sistema, saberá se essa alteração não afetou o desempenho de nenhuma de partes do sistema. O uso do TDD, além disso, aumenta a velocidade de encontrar erros. O fato de os testes serem projetados para testar fragmentos muito pequenos de código permite descobrir rapidamente o local do projeto em que a falha ocorreu. Isso leva ao fato de que erros são detectados com menos frequência em uma versão atualizada já implantada do sistema, o que reduz a taxa de "Taxa de falhas durante alterações".

O fato de a equipe de desenvolvimento ter um alto nível de confiança na sustentabilidade do projeto e em seu trabalho correto significa que a equipe pode decidir se deseja implantar o projeto quando os testes forem concluídos com êxito. Alguém já fez a implantação do projeto sob demanda?

O Projeto Phoenix abrange quatro tipos de trabalho. Um deles é trabalho inesperado. Esse trabalho precisa ser feito quando os desenvolvedores precisam desviar o pensamento do que estão fazendo e fazer outra coisa. Geralmente uma correção de algum tipo de erro. Se o projeto for criado a partir do código de autoteste, isso minimizará a quantidade de erros. Isso, por sua vez, leva à minimização da quantidade de "trabalho inesperado". E quanto menos “surpresas” na vida do desenvolvedor, melhor ele se sente, mais produtivo e melhor ele trabalha.

Se os desenvolvedores puderem se preocupar menos com bugs na produção, isso significa que eles podem dedicar mais tempo ao desenvolvimento de novas funcionalidades úteis do produto. E se os desenvolvedores pensam no código com antecedência, aplicam princípios úteis como o SOLID e se envolvem constantemente na refatoração, isso minimiza o valor da "dívida técnica". Quando uma equipe está confiante na funcionalidade e qualidade do código, pode literalmente implantá-lo em duas contagens. Tudo isso aumenta a velocidade do trabalho.

Sumário


Como qualquer outra ferramenta, como qualquer outra abordagem de desenvolvimento, a metodologia TDD pode parecer estranha no começo. E antes que os programadores dominem adequadamente essa metodologia, isso pode parecer um pouco lento para eles. O que posso dizer? Para citar Jez Humble: "Se algo causa desconforto, faça-o com mais frequência e você pode lidar com isso."

E agora sugiro que pratique a metodologia TDD e faça-a até que o TDD deixe de causar desconforto :)

Caros leitores! Você usa a metodologia TDD ao trabalhar em seus projetos?

Source: https://habr.com/ru/post/undefined/


All Articles