Testes Automatizados como Ferramenta de Desenho

Olá a todos! Para os que ainda não me conhecem e tiveram a curiosidade de conferir a minha bio no final deste artigo, já ficou claro que não sou Analista de Testes. Sou programador e, como tal, sou o principal responsável pela qualidade dos programas que escrevo.
Isso, por si só, já seria motivo suficiente para que eu me interessasse por alguma forma de garantir a qualidade do meu código, por exemplo, através da implementação de testes automatizados, mas não é sobre essa motivação que falarei hoje. Falarei sobre o uso de testes automatizados como ferramenta de desenho* de software.

Recentemente fui responsável pela implementação de um conjunto de rotinas responsáveis pelo fornecimento de informações referentes ao número de mensagens trafegadas em uma plataforma de mensageria. Informações como: número de mensagens enviadas em um dado dia, número de mensagens que tiveram confirmação de recebimento pelo seu destinatário e diversas outras contagens do tipo.
Após algumas conversas com a equipe de desenvolvimento e alguns esboços de projeto, chegamos à conclusão de que uma boa solução seria implementar tais rotinas como procedimentos armazenados, também conhecidos como stored procedures, em um banco de dados destinado exclusivamente ao armazenamento de tais informações. Tais rotinas seriam então executadas de modo automático através de agendamento prévio, pelo próprio sistema de gerenciamento de banco de dados (SGBD).
Tal solução pareceu bastante interessante, pois simplifica o processo de implantação e faz uso do desempenho otimizado que os bancos de dados relacionais oferecem para esse tipo de procedimento. No entanto, como saber se as rotinas estão de fato funcionando? Se fazem o que deveriam? Se, conforme definidas e implementadas, são suficientes para cumprir o objetivo final? É importante lembrar também que esse tipo de contagem deve considerar dados computados ao longo de meses de uso do sistema, algo que simplesmente não se pode “testar em produção“.
Sendo assim, como garantir a correção de tudo isso?
Para tornar o problema mais claro, listo abaixo, com alguma simplificação, algumas das rotinas que foram definidas para atender a uma das contagens solicitadas:

  • Contar mensagens trafegadas por usuário nos últimos 5 minutos.
  • Contar mensagens trafegadas por usuário na última hora.
  • Contar mensagens trafegadas por usuário no dia de hoje.
  • Contar mensagens trafegadas por usuário este mês.
  • Contar mensagens trafegadas por usuário este ano.

A ideia era implementar a primeira rotina contando os registros diretamente no banco de dados de origem, enquanto as demais seriam implementadas somando-se os valores das contagens anteriores.
Vejam bem, o tão polêmico Test Driven Design (TDD), em seu formato tradicional, contando com o conhecido ciclo Red, Green, Refactor, em nenhum momento foi considerado. No entanto, podemos sim dizer que o modo como implementei tais rotinas foi um desenho guiado por testes.
Para começar, gastei algumas boas horas implementando todas as rotinas usando Transact-SQL, a linguagem das stored procedures do Microsoft SQL Server, sem escrever nenhum teste antes. Revisei a implementação, conferi cada lógica e concluí minha tarefa. Entreguei a bomba para a Samantha, Analista de Testes da nossa equipe, e aguardei pelos bugs que ela por ventura pudesse encontrar.

De modo algum. Por mais que muitos programadores não gostem dessa definição, uma implementação não está concluída até que o programador que a realizou possa por a mão no fogo por ela. E se não puder, que ao menos deixe isso bem claro e registre as pendências no backlog, como débito técnico.
De fato, não escrevi nenhum testes antes, mas após concluir a primeira rotina, escrevi uma outra stored procedure para testar a primeira. Através dela, inseri alguns registros simulando mensagens trafegadas no banco de origem, executei a rotina de contagem, e verifiquei o resultado obtido. Sucesso. Funciona demais.
Em seguida, inseri algum ruído nos dados de teste. Estava tudo limpinho demais. E ai, bomba. Resultado incorreto. Revisei a lógica da rotina e encontrei o problema. Corrigi e fui mais uma vez executar os testes. Dessa vez, tudo certo novamente.
Bom, agora preciso inserir mais dados de testes e verificar a segunda rotina, a que conta as mensagens agrupando os resultados por hora. Nessa aí, tudo certo. Sem problemas.
Agora vamos agrupar por dia, e no mês e no ano. Espera aí, a contagem por dia parou de funcionar. O que deu errado? Outro problema? Ah, agora funciona. Mas e aquele outro caso? Droga. E nisso minha paz acabou. Parecia que quanto mais eu cavava, mais fundo o buraco ficava. Mas os testes sempre me diziam o que funcionava e o que ainda não estava de acordo. E assim foram sete dias escrevendo testes e depurando stored procedures no SQL Server Management Studio, até que todas estivessem funcionando corretamente.
Acho que já deu pra entender o meu ponto. Para verificar o correto funcionamento de cada uma dessas stored procedures, identificar os erros que elas continham,e corrigi-las, foi necessária a implementação de diversas rotinas de teste, stored procedures destinadas exclusivamente a inserir dados de teste no banco de origem, executar as contagens a serem testadas e verificar o resultado obtido, de modo semelhante ao que um Analista de Teste faz para uma aplicação Web, utilizando ferramentas como o bem conhecido Selenium.
No entanto e apesar de esses testes poderem a qualquer momento ser usados para verificar a correção das rotinas de contagem, o objetivo deles não era simplesmente testar, mas sim me ajudar, como programador, a identificar os problemas e garantir que foram resolvidos, sejam eles erros de implementação ou falhas lógicas. de desenho*. Isso é o que quero dizer com a expressão testes automatizados como ferramenta de desenho, indo além dos clássicos TDD e BDD**.
E claro, apesar do exemplo ser bem peculiar, usando Transact-SQL, o mesmo pode e deve ser feito com qualquer linguagem de programação, seja ela Java, C#, JavaScript ou qualquer outra.
No fim das contas, esses testes podem não ser usados nos processos de integração contínua, não é esse seu objetivo principal. E, particularmente no exemplo que dei, inserir meses de dados simulados em um banco de dados e realizar inúmeros cálculos sobre eles não é algo lá tão performático. Mas em todo caso, eles estarão lá, disponíveis para auxiliar os próximos programadores que no futuro trombarão com esse código e o chamarão de macarrão. Ou aos Analistas de Testes que quiserem desafiar meus dotes como programador e usá-los como base para a construção de testes ainda mais escalafobéticos, mas possivelmente necessários.
* Desenho do inglês design, e não do inglês drawing, para os que ainda não estão familiarizados com o termo.
** BDD. Behavior Driven Design.
 
por Rafael Romão

0 comentários
  1. Muito bom! Muitas vezes tratamos bancos de dados – e infra-estrutura em geral – de forma diferente do resto do código. Temos sim que controlar versão e testar.
    Vendo este artigo acabei achando este outro falando sobre recursos que já existem no Visual Studio/SQL Server para testes de banco de dados, que poderiam agregar bastante nestes casos:
    https://blogs.msdn.microsoft.com/ssdt/2012/12/07/getting-started-with-sql-server-database-unit-testing-in-ssdt/

    1. Luciano, não é tão simples assim. Já não sou desenvolvedor a mais de 10 anos – sou analista de negócios – mas tenho que dizer que, apesar do nosso colega Rafael Romão estar corretíssimo em tentar garantir a qualidade do seu objeto de desenvolvimento, normalmente, com os prazos cada vez mais apertados, é muito pouco provável que os desenvolvedores, na maioria das empresas de T.I. que conheço pelo menos, tenham o tempo apropriado para tal. Na verdade na maioria das vezes o tempo não é suficiente nem para utilizar a melhor abordagem de desenvolvimento, quanto mais de testes.

      1. Vinicius, de fato a realidade muitas vezes nos coloca em uma posição em que devemos escolher entre abaixar a cabeça, entregar qualquer coisa que seja dentro do prazo, e manter o nosso emprego, ou insistir em dizer que o prazo não é suficiente e acabar sendo visto como aquele cara que vê problema em tudo. Vivi essa realidade por muitos anos e sei o quanto isso é estressante e contraproducente.
        No entanto, isso não pode ser usado como justificativa para entregar um trabalho de má qualidade, sabendo-se que poderia ser feito melhor.
        Felizmente, muitas empresas já perceberam que perdem muito mais com os problemas causados por bugs em produção e pela guerra que se segue à entrega de um software bugado à equipe de qualidade do que tendo o cuidado de dividir e priorizar bem o que será implementado e dar ao time o devido tempo para sua implementação. Como consequência disso, programadores disciplinados e rigorosos com a qualidade do que produzem chegam a ser disputados por essas empresas.
        Meu conselho a desenvolvedores que se veem forçados a brigar com seus gerentes para ter condições de realizar um bom trabalho: Busque outro emprego. Há muito mercado para bons profissionais.

        1. Seu comentário foi excelente Rafael. Inclusive estava falando sobre este aspecto com meus amigos hoje. As empresas estão cada vez mais delimitando prazos curtos sem se preocupar com a qualidade do que esta sendo produzido. Trabalho na área de Testes/Qualidade e meu perfil é aquele de não se submeter aos prazos impostos para as atividades. Meu foco é entregar sim no mínimo de tempo possível, mas com o máximo de qualidade possível.
          Sobre o seu post, foi muito bom esta definição como \”Desenho\”. Estou estudando para a certificação ITIL, na qual define em uma de suas fases do ciclo de vida o Desenho de Serviço. Vou estudar mais sobre isso, mas vejo grande sincronia entre o que você comentou e a fase de Desenho de Serviço como boas práticas para a Gestão de TI.

        2. Ainda não entendo o porquê muitas pessoas/empresas insistem com essa convicção de que pular testes automatizados faz com que o time entregue valor de forma mais rápida.
          Não vejo nenhum dado que prove isso.
          O que vejo são conclusões tiradas de forma equivocadas sem nenhuma análise crítica do real contexto.
          Temos de parar de pensar na velocidade em que entregamos histórias e começar a pensar na velocidade que entregamos valor, e por valor quero dizer mudanças no projeto, menor número de bugs e maior velocidade ao acrescentar novas features.

        3. Rafael, parabéns pelo artigo.
          Ainda não entendo o porquê muitas pessoas/empresas insistem com essa convicção de que pular testes automatizados faz com que o time entregue valor de forma mais rápida.
          Não vejo nenhum dado que prove isso.
          O que vejo são conclusões tiradas de forma equivocadas sem nenhuma análise crítica do real contexto.
          Temos de parar de pensar na velocidade em que entregamos histórias e começar a pensar na velocidade que entregamos valor, e por valor quero dizer mudanças no projeto, menor número de bugs e maior velocidade ao acrescentar novas features.

      2. Shashi Hou hiukset ratkaisu MBP lämpö ongelma minulla kumarra sinua! [ ] 8. kesäkuuta 2010 kello 22:23 Vastaa: Ensin esittää MBP lÃimm¤ttää sen minulle? Kuitenkin tekninen tuki ostaa tyhjän Käytin katsoa [ ]

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Talvez você goste desses conteúdos também: