Precisamos de Log ao fazer TDD?

40

Ao executar o ciclo Vermelho, Verde e Refatorador, devemos sempre escrever o código mínimo para passar no teste. Foi assim que aprendi sobre TDD e quase todos os livros descrevem o processo.

Mas e o registro?

Honestamente, raramente usei o logon em um aplicativo, a menos que houvesse algo realmente complicado, mas vi várias postagens que falam sobre a importância do log adequado.
Portanto, além de registrar uma exceção, eu não poderia justificar a real importância de efetuar logon em um aplicativo testado adequado (testes de unidade / integração / aceitação).

Então, minhas perguntas são:

  1. Precisamos fazer logon se estivermos fazendo TDD? um teste falho não revelará o que há de errado com o aplicativo?
  2. Devemos adicionar teste para o processo de log em cada método em cada classe?
  3. Se alguns níveis de log estiverem desativados no ambiente de produção, por exemplo, isso não introduzirá uma dependência entre os testes e o ambiente?
  4. As pessoas falam sobre como os logs facilitam a depuração, mas uma das principais vantagens do TDD é que eu sempre sei o que há de errado devido a uma falha no teste.

Há algo que estou perdendo por aí?

Songo
fonte
5
Eu acho que o log é o caso especial de muitas regras. Uma classe / função deve fazer uma coisa e apenas uma coisa ... exceto para o log. As funções devem preferencialmente ser puras, exceto para o registro. E assim por diante. O registro quebra as regras.
Phoshi
11
O registro de log não é ortogonal a nenhuma metodologia de desenvolvimento de software utilizada? Portanto, talvez você deva apenas reduzi-lo e perguntar: Precisamos de casos de teste para registrar ao fazer TDD?
hyde 24/02

Respostas:

50

1) Precisamos registrar se estamos fazendo TDD? um teste falho não revelará o que há de errado com o aplicativo?

Isso pressupõe que você tenha todos os testes possíveis de que seu aplicativo precisa, o que raramente é verdade. Os logs ajudam a rastrear bugs para os quais você ainda não escreveu testes.

2) Devemos adicionar teste para o processo de registro em cada método em cada classe?

Se o próprio criador de logs for testado, ele não precisará ser testado novamente em cada classe, semelhante a outras dependências.

3) Se alguns níveis de log estiverem desativados no ambiente de produção, por exemplo, isso não introduzirá uma dependência entre os testes e o ambiente?

Seres humanos (e agregadores de logs) dependem dos logs, os testes não devem depender deles. Normalmente, existem vários níveis de log, e alguns são usados ​​na produção e alguns níveis adicionais são usados ​​no desenvolvimento, semelhantes a:

"O nível do log do Rails é informações no modo de produção e depuração no desenvolvimento e teste" - http://guides.rubyonrails.org/debugging_rails_applications.html

Outros aplicativos usam uma abordagem semelhante.

4) As pessoas falam sobre como os logs facilitam a depuração, mas uma das principais vantagens do TDD é que eu sempre sei o que há de errado devido a uma falha no teste.

Os bugs de produção passaram em todos os testes; portanto, você pode precisar de outra referência para investigar esses problemas.

FMJaguar
fonte
26
Até o perfeito TDD rigorosamente executado não impedirá problemas de produção com desempenho, interação do sistema, interação de terceiros. Os problemas de simultaneidade também são muito difíceis de cobrir totalmente por teste. Uma cobertura de teste de 100% "apenas" significa que 100% do seu código foi executado, e isso não está correto em todos os estados ou ambientes.
Holstebroe
34

O registro é útil para explicar o comportamento não excepcional de um aplicativo:

Os logs de eventos registram os eventos que ocorrem na execução de um sistema para fornecer uma trilha de auditoria que pode ser usada para entender a atividade do sistema e diagnosticar problemas. Eles são essenciais para entender as atividades de sistemas complexos, principalmente no caso de aplicativos com pouca interação do usuário (como aplicativos de servidor ) ...

Independentemente de como o aplicativo foi testado e de quão bem as exceções são registradas, seus usuários podem perguntar,

a saída do seu programa é 0, enquanto esperávamos que fosse 1, por que isso?

Você precisa fazer o log para verificar o que foi configuração do aplicativo, parâmetros e outros detalhes de tempo de execução para explicar seu comportamento (não excepcional).

Da perspectiva acima, o log é mais orientado ao suporte do que ao desenvolvimento. Depois que o aplicativo entra no ar, é desejável permitir que outra pessoa lide com perguntas dos usuários, para permitir que os programadores se concentrem no desenvolvimento futuro.

Registrar o que o aplicativo faz permite que outra pessoa entenda o comportamento do programa sem se aprofundar no código e sem distrair os desenvolvedores com solicitações para explicar o que está acontecendo.

mosquito
fonte
5
+1 para "o log é mais orientado para o suporte". Realmente bata na unha na cabeça.
Tibos
11
+1 para "comportamento não excepcional" e também para "o log é mais orientado para o suporte". Mas você poderia editar sua resposta para listar a fonte do parágrafo que você citou?
logc
A fonte @logc da citação é referida no link na primeira palavra aqui, "Logging" - se você clicar nela, será exibida no artigo da Wikipedia: en.wikipedia.org/wiki/Logfile
gnat
16

A maioria das respostas aqui se concentra no aspecto da correção. Mas o registro também tem um propósito diferente: o registro pode ser uma maneira de reunir dados relevantes de desempenho. Assim, mesmo quando o sistema funciona sem erros, um log pode dizer por que é lento. Mesmo com cobertura de teste completa de todos os aspectos, uma suíte de testes não conta.

É claro que um sistema crítico de desempenho pode / deve fornecer as principais métricas de desempenho para algum painel operacional, mas o log "clássico" pode fornecer um nível diferente de detalhes.

johannes
fonte
2
Também não se esqueça do log para fins de trilha de auditoria. Ou cobrança. Ou vários tipos de estatísticas. Ou registro de eventos para corresponder a outros tipos de estatísticas de outros sistemas.
PlasmaHH
A criação de perfil não é algo que você faria sem o log? Ou você apenas quer dizer que pode registrar continuamente os resultados da criação de perfil?
Bergi
@ Bergi: depende inteiramente de como o seu aplicativo funciona. Se, por exemplo, for um aplicativo da web, o registro do tempo de serviço de cada solicitação e a tentativa posterior de agrupar esses eventos para "maus desempenhos" também podem funcionar.
PlasmaHH
A criação de perfil do @Bergi ocorre no desenvolvimento, mas há efeitos nos sistemas ativos a serem lembrados: o uso de discos pode ficar lento, a CPU pode ser mais carregada, os serviços podem não responder a tempo, os threads paralelos podem ter problemas de bloqueio ...
johannes
A auditoria do @PlasmaHH faz parte dos requisitos principais e deve ser coberta por testes. Na maioria dos casos, não o executo em rotas de registro "normais". O registro normal pode falhar, não a auditoria. "várias estatísticas" que reuni em desempenho;)
johannes
8

A resposta curta para sua pergunta principal é: como regra geral, os erros no seu código NÃO serão expostos pelo TDD. Alguns podem, idealmente muitos, mas a ausência de testes com falha não implica a ausência de bugs. Essa é uma máxima muito importante nos testes de software.

Como você não pode saber se terá um comportamento incorreto em seu sistema, talvez em condições raras, o log é uma ferramenta útil que pode ajudar a entender o que está errado quando as coisas inevitavelmente dão errado.

O registro e o TDD abordam diferentes preocupações.

Andres F.
fonte
7
  1. A menos que você tenha uma cobertura de teste de 100%, o que geralmente não é o caso, você não pode saber que seu software nunca trava (EDIT: e - como foi dito nos comentários - mesmo que isso aconteça, algo independente do seu software pode causar uma colisão); é o mesmo que pensar que você pode fazer um software que não tem absolutamente nenhum erro (nem mesmo a NASA pode fazer isso). Portanto, no mínimo, é necessário registrar possíveis falhas, caso seu programa falhe, para que você possa saber o porquê.

  2. O registro deve ser feito por uma biblioteca externa ou estrutura interna, dependendo da tecnologia que você está usando. O que quero dizer com isso é que deve ser algo que já foi testado antes e que você não precisa se testar. É um exagero testar que todos os métodos registram as coisas que deveriam.

  3. Os logs não se destinam a testes, não deve haver dependência alguma. Dito isso, você não precisa desativar o log para testes se isso parecer uma restrição para você, embora os logs devam ser mantidos em um arquivo correspondente ao ambiente (você deve ter um arquivo diferente para o ambiente de teste, desenvolvimento e produção pelo menos).

  4. Um erro pode não ser muito claro e nem sempre é óbvio o que deu errado quando um teste TDD falhou. Os logs devem ser mais precisos. Por exemplo, se você estiver executando um algoritmo de classificação e todo o caso de teste falhar, deverá ter logs para todos os testes do algoritmo que ajudarão a identificar onde o problema realmente está.

Pierre Arlaud
fonte
3
Mesmo que você tenha 100% de cobertura, você o tem para todas as coisas possíveis que podem acontecer? E se a conexão de rede ao seu banco de dados cair? Seus testes lhe dirão isso?
Zachary K
Você nunca pode saber que seu software nunca travará, mesmo que você tenha 100% de cobertura. A cobertura de 100%, embora desejável, fornece muito menos informações sobre correção do que parece.
Andres F.
Sim, você está certo sobre isso também. O ponto é que não ter possibilidade de falha não é factível. Eu vou editar.
Pierre Arlaud 24/02
11
A edição ainda está incorreta. Mesmo se você tiver 100% de cobertura de teste, pode haver um erro no seu código (não é necessário culpar causas externas). Os testes NÃO implicam no trabalho do seu código; a única coisa que isso implica com certeza é que você não conseguiu escrever um teste que encontrou um bug :) A cobertura do teste é uma métrica importante, mas não está diretamente relacionada à ausência de erros.
Andres F.
3
É trivial provar que "100% de cobertura de teste que passa! = Sem erros". Contraexemplo: add(x, y) = 2(sempre retorna 2). O seguinte teste passa e proporciona uma cobertura completa: assert(2 == add(1,1)). 100% de cobertura de teste para uma função de buggy :)
Andres F.
5

Sim, no caso geral, você precisa fazer logon.

O registro não é sobre depuração. Bem, ok, algumas vezes, parte do log refere-se à depuração e você pode pular essa parte se não precisar dela durante o desenvolvimento.

Mas a parte mais importante do registro é sobre manutenção. O log bem projetado pode responder às seguintes perguntas:

  • O aplicativo ainda está vivo e chutando? (Registrando um batimento cardíaco a cada 1000 segundos.)
  • O desempenho do aplicativo mudou nos últimos 10 meses? (Registrando estatísticas do desempenho de casos de uso.)
  • A carga do aplicativo mudou nos últimos 10 meses? (Registrando o número de solicitações por tipos de solicitação.)
  • Alguma de nossas interfaces mudou suas características de desempenho?
  • A nova versão causa uma característica de uso diferente para alguns dos subsistemas?
  • Estamos sob um ataque de negação de serviço ?
  • Que tipos de erros estão acontecendo?

Tudo isso pode ser conseguido registrando-se. E sim, deve ser planejado, projetado e testado, de preferência automático.

O registro é um recurso que merece tratamento, assim como outros recursos.

Jens Schauder
fonte
4

TL; DR: Log e TDD são ortogonais. Ter um não tem relação com a necessidade do outro

Precisamos fazer logon se estivermos fazendo TDD? um teste falho não revelará o que há de errado com o aplicativo?

De maneira geral, a maioria dos logs que eu implementei e que eu vi implementados é para solução de problemas operacionais, não para depuração de desenvolvimento (embora possa ajudar). O público-alvo principal desse registro são os administradores e as operações que executam seus servidores, dão suporte às pessoas que têm registros enviados a eles para análise e os clientes que desejam ver os registros e tentar descobrir o que está acontecendo.

Esses logs estão lá para ajudar a solucionar problemas, em grande parte dos pontos de integração. Isso pode incluir serviços de rede (banco de dados, sabão, etc), recursos locais (disco, memória, etc), dados inválidos (entrada do cliente, fontes de dados corrompidas / corrompidas, etc.), etc. Captura de exceções, falhas de registro e até registro informativo (configurações, configurações etc.) podem ajudar na solução de problemas.

Devemos adicionar teste para o processo de log em cada método em cada classe?

Adicione testes sempre que precisar para testar o log. Se você tiver chamadas ad hoc para desconectar informações, elas deverão ser testadas. Embora se você implementar o registro e o teste de log usando a Programação Orientada a Aspectos ou a metaprogramação, isso poderá reduzir o ônus do teste.

Se alguns níveis de log estiverem desativados no ambiente de produção, por exemplo, isso não introduzirá uma dependência entre os testes e o ambiente?

Se você estiver escrevendo seu código usando a IoC e fizer uso de zombarias, poderá testar efetivamente todos os seus logs sem depender de uma configuração ambiental específica.

dietbuddha
fonte
3

O TDD geralmente ajuda a reduzir os erros de codificação. Isso ajuda muito menos com erros na especificação ou apenas mal-entendidos sobre como as coisas funcionam.

"Ah? Você pode receber uma mensagem de dados antes de obter a confirmação de que o logon teve êxito? Eu nunca soube disso, bem, não vai lidar com isso!" ... Esse tipo de coisa. O registro é muito útil para dizer o que o software tentou fazer, para que você possa identificar o que fez de errado.

JohnB
fonte
2

Na minha experiência, um ótimo nível de registro é adicionado ao aplicativo quando não fazemos TDD. Então, o nível de incerteza se torna alto; portanto, adicionamos o log para ver o que está acontecendo.

Enquanto que ao fazer TDD (ou talvez testar sempre), vejo-me adicionando muito menos instruções de log. Por sua vez, isso significa menos LOC e pode (nem sempre) afetar o desempenho.

Mas adicionamos logs de entrada e saída de funções de maneira semi-automática na minha empresa na maioria dos casos, independentemente do método de desenvolvimento. Como eu sei, isso foi considerado obrigatório para a análise do problema de produção.

Exemplo podem ser métodos de um bean de serviço EJB que estão presentes na interface pública. Outro pode ser um caso em que uma função faz cálculos complexos. Pode ser muito útil ter números entrando no método (por exemplo, você pode escrever um teste de unidade para voltar ao tópico geral em questão).

dbalakirev
fonte
você poderia expandir os motivos pelos quais você adiciona logs de entrada e saída de funções? por que isso é necessário na sua empresa?
Gnat
sim absolutamente. Espero que esteja melhor agora.
26414 dbalakirev