Resistência à automação de teste

Apesar de as tecnologias de teste de unidade existirem há 30 anos (Kent Beck escreveu o artigo "Simple Smalltalk Testing: With Patterns" em 1989), nem todos os programadores são donos dessa tecnologia e nem todas as empresas fizeram do teste automático uma parte de sua cultura corporativa. . Mesmo apesar das vantagens óbvias dos testes automáticos, a resistência comportamental ainda é bastante forte. Quem tentou implementar testes automatizados sabe que sempre há alguma razão para que isso não possa ser feito.


Da minha experiência pessoal em implementar métodos de programação confiáveis ​​em minha empresa, nas empresas que consultei, comunicando em conferências e também de fontes publicamente disponíveis, formulei objeções e resistências típicas que impedem a implementação de uma cultura de teste automático.


Agrupei todas as objeções em uma pirâmide de programação confiável, que inclui quatro níveis:


  • A cultura profissional (o mais alto nível, a base da programação confiável) é um conjunto de normas, regras não escritas, crenças dos funcionários que o guiam em seu trabalho. Por exemplo: “O envio de código descoberto por testes para o repositório é ruim”, “Silenciar os erros encontrados no código é uma pena”.
  • Gestão são os procedimentos, políticas, regras adotadas pela organização, bem como a vontade (decisão) dos líderes. Por exemplo: “Cada função de aplicativo desenvolvida deve passar um código de revisão. Sem exceções!
  • Métodos são abordagens científicas, métodos para resolver um problema específico. Por exemplo: "Se a função do aplicativo for difícil de testar, você precisará aumentar a testabilidade do aplicativo aplicando o modelo de injeção de dependência".
  • Tecnologias (o nível mais baixo) são linguagens de programação, bibliotecas, estruturas, ferramentas. Por exemplo, JUnit, Selenium, XCTest e assim por diante.


Por que essa divisão é necessária? Como o problema de um nível é resolvido por métodos do mesmo nível ou por métodos de nível superior. Por exemplo, se não é habitual que uma organização escreva testes automáticos (o problema da cultura profissional), esse problema não pode ser resolvido descrevendo o processo de negócios de teste em detalhes (nível "gerenciamento") ou instalando uma estrutura moderna (nível "tecnologia"). Eu garanto que em uma semana ninguém fará testes, apesar do processo comercial aprovado.


Objeções culturais


“Meus programas não quebram. Não vejo a necessidade de testar. "


Eu ouvi essa afirmação de iniciantes ou programadores excessivamente confiantes.
Obviamente, uma vez que uma função escrita não possa ser interrompida por si mesma. Mas aqui é importante entender que, com o tempo, o programa pode exigir suporte, a introdução de novas funções ou acréscimos às funções existentes. A complexidade dos programas - o número de classes e as dependências entre elas - é bastante grande e, eventualmente, depois de criar outra nova função ou melhorar uma existente, um erro ocorrerá mais cedo ou mais tarde. Um teste automático detectaria essa regressão.


Além disso, muitas vezes essa objeção pode ser ouvida por programadores iniciantes que não têm nenhum conceito de teste. Por exemplo, apenas falhas são consideradas uma avaria, não erros funcionais.


Em uma das entrevistas que conduzi, ocorreu o seguinte diálogo:


- Você tem as habilidades de teste automático?
- Não, eu escrevi programas simples, não havia nada para quebrar.
- Qual é a sua motivação para mudar de emprego?
Quero escrever aplicações complexas.


Eu sei muito bem como isso acaba. O programador tem a confiança de desenvolver um programa mais complexo, mas ele não conhece os métodos de teste automático, não pode testar a aplicação qualitativamente e não consegue lidar com a escala do projeto, o que levará à interrupção do projeto, custo excessivo de desenvolvimento e perda de reputação. Porque eu pessoalmente gerenciei projetos, onde não consegui lidar com a escala do projeto e falhei exatamente por causa da falta de testes automáticos.


Relutância em assumir a responsabilidade pela qualidade do código, pelos testes.


Os testes automatizados são a única fonte de informações operacionais e objetivas sobre a verdadeira qualidade de um produto de software. Em outras palavras, o programador sempre tem um supervisor nas costas, que pode reportar à gerência a qualquer momento o quão bem o programador faz seu trabalho. Os testes automatizados permitem vincular a produtividade do trabalho não com tickets fechados no Jira, mas com a verdadeira qualidade do produto de software. E aqui você já precisa pensar em como escrever de maneira confiável, para que todas as próximas alterações no código não quebrem as funções existentes. Para que cada nova função funcione não apenas no script, quando tudo estiver bem, mas também processe corretamente os erros.


Responsabilidade é o compromisso voluntário de garantir um resultado positivo do trabalho. O funcionário aceita essa obrigação em virtude de seu caráter e educação. Infelizmente, devido à crise cultural e profissional, nem todo programador está pronto para assumir essas obrigações.


"Escreva agora mesmo sem erros"


Pessoas que não estão familiarizadas com o funcionamento do desenvolvimento de software podem ter uma atitude negativa em relação aos desenvolvedores que mencionam algum tipo de erro.


- Vamos cobrir o aplicativo com testes automáticos.
Porque?
- Para garantir que tudo funcione corretamente e que não haja erros.
- Você escreve com erros? Você tem baixa qualificação? Escreva imediatamente sem erros.
"Sim, mas todo mundo comete erros ..."
- Mas a empresa XYZ disse a um amigo que eles têm os principais programadores que escrevem sem erros!


Assim, é difícil "vender" o desenvolvimento de testes para clientes que não são tecnicamente esclarecidos. Como resultado, o gerenciamento é forçado a desenvolver um projeto sem testes automáticos, o que leva a problemas conhecidos.


Objeções de gerenciamento


“Com testes, escrever um programa é duas vezes maior. Não cumpriremos os prazos. ”


À primeira vista, esta tese parece justa. É realmente necessário gastar tempo do programador escrevendo testes. Porém, programadores e gerenciamento não levam em consideração que o tempo total de desenvolvimento do produto inclui não apenas programação, mas também depuração e suporte, além do enorme custo do teste de regressão manual após as correções.


Testes automatizados têm várias funções:


  1. Verificando .
    1.1 Os testes verificam se o objeto de teste está funcionando corretamente.
    1.2 Os testes verificam a qualidade do trabalho do programador: se a tarefa está resolvida, se existem efeitos colaterais na forma de regressões.
  2. Diagnosticando . Os testes de diagnóstico podem reduzir significativamente o tempo para procurar um defeito. Os testes permitem determinar a localização do erro com precisão para a classe e método e, às vezes, com precisão para a linha de código.
  3. Automatizando . Os testes permitem inserir rápida e facilmente o objeto de teste no estado desejado para depuração.
  4. Documentação .
    4.1 Os testes de aceitação registram os requisitos do cliente para o produto que está sendo desenvolvido.
    4.2 Os testes mostram exemplos de uso do componente desenvolvido, reduzindo assim o tempo gasto no estudo do trabalho do sistema por outro programador.

Em uma das organizações que consultei, o gerente resistiu à introdução de uma cultura de teste automático:


- Mas afinal, escrevendo testes há muito tempo! Não cumpriremos os prazos!
- Você tem erros que procura e corrige há muito tempo?
- Sim, existem alguns.
- Qual é o caso mais difícil?
- Pesquisamos um erro por 80 horas.
- 80 horas são duas semanas de trabalho do programador. Se você passasse uma semana inteira testando a automação, economizaria meses em diagnosticar e depurar seu aplicativo!


Nossa organização tem o postulado: "Com testes, escrever um programa é duas vezes mais rápido!" e este postulado não é discutido. Somente o coeficiente 2 é discutido - às vezes existem 3 e 4. E alguns projetos simplesmente não podem ser concluídos sem testes automáticos competentes (veja o projeto sobrecarregado).


"Já temos um departamento de testes manuais, deixe-os testar."


À primeira vista, a separação de especializações em teste e programação parece lógica.


Mas vejamos as desvantagens do teste manual:


  • É muito caro
  • Demora muito tempo. Por exemplo: o script de teste para o testador de aplicativo móvel "Cinema Online" dura 40 horas. E isso é apenas para uma plataforma! Se você precisar testar o aplicativo no iPhone, iPad, Apple TV, Android, Fire TV, precisará gastar 40 × 6 = 240 horas de tempo de trabalho, isto é, um mês e meio, o que é inaceitável para curtos ciclos de desenvolvimento.
  • O teste manual está sujeito a erros humanos comuns - não fornece um resultado objetivo e verdadeiro.

Além disso, alguns tipos de testes não podem ser executados dentro de um tempo razoável, porque o número de combinações de formatos e vários scripts de teste é muito grande. Por exemplo:


  1. Função para importar arquivos CSV.
  2. Analisadores para documentos de texto.
  3. Instrumentos financeiros.

Objeções no nível do método


Ignorância de métodos de teste automático.


Devido à crise na educação, não há disciplinas de teste automático em nenhum lugar nas universidades. Existem muito poucos cursos em escolas comerciais de TI. E os cursos existentes são superficiais e de baixa qualidade. Portanto, muitas vezes encontrei um estupor entre os programadores: eles não sabem como testar aplicativos não triviais (mais difícil que 2 + 2 = 4).


De fato, a ciência dos testes é bastante extensa. Por exemplo, nem todo programador responderá imediatamente às perguntas: a) o que é testabilidade? b) o que é controlabilidade e observabilidade? c) quais padrões de design melhoram a testabilidade do aplicativo? E assim por diante


Os programadores não sabem o que escrevem, como fica, quais funções e interfaces serão.


É muito difícil testar o que não está claro como parece. Em outras palavras, sem os requisitos predefinidos para o aplicativo, o programador não pode entender o que é esperado dele.


A peculiaridade de alguns projetos é que eles são desenvolvidos usando a tecnologia Produto Mínimo Viável, que em outras palavras pode ser descrita da seguinte forma: “Vamos fazer pelo menos algo pelo tempo mínimo e pelo orçamento mínimo”, e o programador é considerado pelo cliente ou gerência como analista, designer, arquiteto, programador e testador em uma garrafa. Com essa abordagem, exclui-se o estágio formal de criação de um sistema de software: a definição da lógica de negócios, domínio, interfaces de componentes, bem como a organização interna do relacionamento entre eles. Não há arquitetura formalizada, nem interfaces, nem processos de negócios prescritos - não está claro o que testar, através de quais interfaces e qual é o resultado esperado.


Código inapropriado.


A testabilidade é uma propriedade do projeto que diz com que facilidade pode ser testada. A adequação do teste é determinada por duas outras propriedades: controlabilidade e observabilidade. Gerenciabilidade - uma propriedade que determina como é fácil inserir um aplicativo no estado desejado para teste (atender às pré-condições). Observabilidade - com que facilidade é possível considerar o estado após o teste, compará-lo com o esperado.


Por exemplo, a autenticação de dois fatores usando o SMS é muito difícil de testar automaticamente, porque a função de receber SMS está fora do escopo do ambiente de teste automatizado. Esse sistema é inadequado.


Diante de um sistema inadequado, o programador desiste e evita testar esse sistema.


Preparação de dados de teste.


Uma das resistências não óbvias é a preparação de dados e padrões de teste. Por exemplo: o estado inicial do banco de dados no qual o teste é realizado. A preparação dos dados de teste pode levar muito tempo e trabalho rotineiro, portanto esse trabalho é considerado ingrato e desinteressante entre os programadores.


Solução:


  • desenvolvimento de valores e exemplos de referência na fase de desenvolvimento de testes de aceitação - eles também ajudarão a resolver conflitos com o cliente na fase de aceitação do trabalho;
  • desenvolvimento de valores de referência na fase de projeto do sistema. Por exemplo, solicitações e respostas HTTP padrão - ajudarão a integrar mais facilmente o cliente e o servidor;
  • desenvolvimento de procedimentos especiais para montagem de bancos de dados, nos quais o estado necessário do banco de dados é criado automaticamente e não manualmente
  • uso do modelo Mãe do Objeto [Fowler, Schuh, Peter e Stephanie Punke. "Facilitando a criação de objetos de teste no XP." XP Universe. 2003], que ajuda a alocar e inicializar facilmente objetos no estado requerido.

Serviço de teste.


Durante o desenvolvimento de um projeto, os requisitos para ele (esclarecimento, mudança) podem mudar. Ou refatoração interna pode ocorrer, o que levará a uma alteração nas interfaces de classe. Com a mudança nos requisitos, os critérios de aceitação de uma função específica também serão alterados e, com eles, os testes. Em algum momento, o programador pode se recusar a prestar serviços de manutenção aos testes - ou seja, mantê-los atualizados.


Solução:


  • usando o modelo “adaptador” para dissociar a lógica do teste da interface que está sendo testada;
  • uso de testes de alto nível (pepino, pepino, quando e quando);
  • veja a solução para resistência "preparação de dados de teste".

Conclusão


Não há dúvida de que o software deve ser confiável: exceda as expectativas do cliente. Testes automatizados não são o único, mas importante componente no desenvolvimento de software confiável.


Formulei objeções e obstáculos típicos à implementação de testes automáticos, que encontrei pessoalmente em minha organização e nas organizações que consultei.


O artigo descreve apenas problemas e mal toca em maneiras de resolvê-los. Em geral, a estratégia para resolver esses problemas me parece assim:


  1. Formação e promoção de uma nova cultura de design de TI, que é confiabilidade, orgulho e responsabilidade pessoal pelo resultado.
  2. Desenvolvimento de novos padrões elevados para teste de código.
  3. Desenvolvimento e implementação de cursos de treinamento.
  4. A introdução de motivação na carreira de programadores e gerentes, ligada à qualidade dos produtos de software em desenvolvimento, bem como às habilidades de teste automático.

O mais importante que consegui entender é que os problemas estão em diferentes níveis: tecnológico, metodológico, gerencial e cultural. E eles precisam ser abordados em níveis apropriados. É muito difícil implementar testes automatizados se o programador não for treinado em métodos de design adequados para teste ou se o gerenciamento não suportar uma cultura de programação confiável na organização.


Serei grato por exemplos de sua prática de quão fácil ou difícil foi implementar testes automatizados em sua organização. Que problemas você enfrentou? Como você os resolveu?

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


All Articles