O número e as linhas por trás dele

Prévia grátis 5 min de leitura

Esta aplicação reporta 82,99% de cobertura de linhas. Esse número é quase inútil e a coisa por trás dele não é, e a distância entre os dois é o assunto deste curso.

O número

$ bundle exec rspec
1206 examples, 1 failure
Line Coverage: 82.99% (4190 / 5049)

(A única falha é um spec de fuso horário que depende do tzdata da máquina local.) O que você faz com 82,99%? Dá para pôr num slide. Dá para ver subir ou descer. Não dá para agir sobre ele, porque ele não nomeia nada, e nem diz o que mediu.

As linhas por trás

O SimpleCov escreve o coverage/.resultset.json, que contém os dados por linha de onde a porcentagem foi calculada. Lê-lo dá algo totalmente diferente:

uncovered lines: 859, in 40 files
  727 in lib/tasks/ and lib/course_revision/ (this repository's course-authoring tooling)
    6 in lib/execution/ (the grading sandbox)
  126 in app/, across 23 files, for example:
    app/services/partners/webhook_transport.rb: 10, 12, 13, 14, 15, 17, 18, 20, 21, 23
    app/services/partners/fetch_site_icon_service.rb: 37, 59
    app/jobs/partners/fetch_site_icon_job.rb: 6, 7
    app/jobs/partners/deliver_webhook_job.rb: 19, 23
    app/controllers/admin/partners/partners_controller.rb: 29, 38, 39, 40

Dois achados antes de ler uma única linha de código. A maior parte da lacuna nem é a aplicação: são tarefas rake que a suíte carrega e nunca roda. E a lacuna da própria aplicação são 126 linhas em 23 arquivos, cada uma com um número. É a mesma medição, e é acionável de um jeito que a porcentagem não é, porque cada linha pode ser olhada e receber uma decisão.

(O resto deste curso trabalha com as 126 linhas da aplicação e deixa as ferramentas fora do escopo.)

O que as linhas acabam sendo

Três delas valem um olhar direto.

# app/services/partners/fetch_site_icon_service.rb, line 37
rescue URI::InvalidURIError, SocketError, Timeout::Error,
       OpenSSL::SSL::SSLError, Errno::ECONNREFUSED => e
  Result.new(success: false, url: nil, errors: [ e.message ])   # ← line 37
# app/jobs/partners/fetch_site_icon_job.rb
def perform(partner_id)
  partner = ::Partners::Partner.find_by(id: partner_id)                          # ← line 6
  ::Partners::FetchSiteIconService.call(partner: partner) if partner && ...      # ← line 7
end
# app/services/partners/webhook_transport.rb, lines 10 to 23
uri = URI.parse(url)
http = Net::HTTP.new(uri.host, uri.port)
# ...
response = http.request(request)
return response if response.code.to_i.between?(200, 299)
raise DeliveryError, "#{url} responded #{response.code}"

A cláusula de resgate de cinco classes de exceção, o corpo inteiro do job de ícones, e o corpo inteiro do adaptador que entrega webhooks a parceiros.

As duas primeiras são o código que roda quando o site de um parceiro está fora: justamente a situação para a qual o serviço foi escrito. A terceira é toda linha que fala com a rede quando a aplicação avisa um parceiro, inclusive o ramo que levanta DeliveryError para o job tentar de novo; o spec do job o substitui por um stub, então nada dele rodou num teste.

flowchart TB
  A["82,99% de cobertura de linhas"] --> B["um número para pôr num slide"]
  A --> C[".resultset.json: 126 linhas da aplicação em 23 arquivos"]
  C --> D["o resgate de 5 classes de exceção"]
  C --> E["o corpo inteiro do job de ícones"]
  C --> H["o adaptador inteiro de entrega de webhooks"]
  D --> F["o código que roda quando o site de um parceiro está fora"]
  E --> F
  H --> I["o código que roda toda vez que um parceiro é avisado"]

O ponto

Ninguém precisou dos 82,99% para achar isso. Um grep por rescue e Net::HTTP e uma pergunta sobre quais deles têm specs teriam achado a mesma coisa mais rápido. E ler as linhas da aplicação leva alguns minutos.

A porcentagem não revelou isso, escondeu o formato disso, e misturou tudo com setecentas linhas de ferramentas que ninguém jamais testaria.

Esse é o padrão de que este curso trata: uma métrica é um ponteiro, e o valor está sempre naquilo para que ela aponta. Um número reportado sem a coisa por trás dele é um número que encerrou uma conversa em vez de começar uma.

A regra para toda métrica deste curso

Se não pode ser transformada de volta numa lista de coisas específicas, não vale acompanhar.

82,99% falha nesse teste. "126 linhas da aplicação descobertas, e três grupos delas são o caminho de falha de uma chamada HTTP de saída e o todo da outra" passa. E é a mesma medição: lida de outro jeito.

Pontos-chave

  • Esta aplicação reporta 82,99% de cobertura de linhas em 1.206 exemplos.
  • O coverage/.resultset.json transforma isso em 859 linhas descobertas, 727 delas em ferramentas de autoria de cursos e 126 em 23 arquivos da aplicação.
  • Três grupos valem um olhar direto. A cláusula de resgate de cinco classes, o corpo inteiro do job de ícones, e o adaptador inteiro de entrega de webhooks.
  • Essas são as linhas que rodam quando o site de um parceiro está fora, ou toda vez que um parceiro é avisado.
  • Uma métrica que não pode ser transformada de volta numa lista de coisas específicas não vale acompanhar.
Aula 1 de 7 · grátis

Continue com a aula 2

O que cada métrica responde

Liga dez métricas de saúde à pergunta que cada uma responde e separa indicadores antecedentes de consequentes.

Com uma conta grátis você também tem os quizzes, seu progresso e suas anotações, e a discussão.

Digite para buscar...