Ir para o conteúdo

Escrever, executar e testar código

Para corrigir um bug ou implementar um recurso, será necessário escrever um novo código.

Para começar a trabalhar no código, certifique-se de ter um [ambiente de desenvolvimento] configurado e de estar [trabalhando em um branch].

Temos um guia de estilo de código que descreve nossas diretrizes para escrever código para o BeeWare.

Desenvolvimento orientado por testes

Uma boa maneira de garantir que seu código funcione conforme o esperado é, primeiro, escrever um caso de teste para verificá-lo. Esse caso de teste deve falhar inicialmente, já que o código que ele está testando ainda não está presente. Você pode então fazer as alterações necessárias no código para que o teste seja aprovado e ter a certeza de que o que escreveu está resolvendo o problema que esperava resolver.

Execute seu código

Depois de escrever o código, é preciso garantir que ele funcione. Você precisará executá-lo manualmente para verificar se ele está fazendo o que você espera. Se ainda não o fez, é recomendável escrever um caso de teste para as alterações; conforme mencionado acima, esse teste deve falhar se o código estiver comentado ou ausente.

Você adicionará seu caso de teste ao conjunto de testes, para que ele possa ser executado junto com os outros testes. O próximo passo é executar o conjunto de testes.

Executando testes e cobertura

BeeWare utiliza tox para gerenciar o processo de testes e pytest para seu próprio conjunto de testes.

O comando padrão tox inclui a execução de:

  • ganchos de pré-confirmação
  • Verificação das notas de lançamento
  • verificação de conformidade da documentação

  • conjunto de testes para as versões disponíveis do Python

  • relatórios de cobertura de código

Isso é basicamente o que a CI executa quando você envia uma solicitação de pull.

Para executar o conjunto completo de testes, digite:

(.venv) $ tox
(.venv) $ tox
(.venv) C:\...>tox

A execução do conjunto completo de testes pode demorar algum tempo. Você pode acelerar consideravelmente o processo executando tox em paralelo, ou seja, executando tox p (ou tox run-parallel). Ao executar o conjunto de testes em paralelo, você receberá menos feedback sobre o andamento dos testes durante a execução, mas ainda assim obterá um resumo de quaisquer problemas encontrados ao final da execução. Você deverá ver alguma saída indicando que os testes foram executados. Você pode ver SKIPPED testes, mas nunca deve receber resultados de teste FAIL ou ERROR. Executamos nosso conjunto completo de testes antes de mesclar cada patch. Se esse processo detectar algum problema, não mesclamos o patch. Se você encontrar um erro ou falha no teste, ou há algo estranho em seu ambiente de teste, ou você encontrou um caso extremo que não vimos antes — de qualquer forma, nos avise!

Além da aprovação dos testes, isso deve indicar 100% de cobertura de teste.

Executando variações de teste

Executar testes em várias versões do Python

Por padrão, muitos dos comandos tox tentarão executar o conjunto de testes várias vezes, uma vez para cada versão do Python compatível com o BeeWare. Para isso, porém, cada uma das versões do Python deve estar instalada em seu computador e disponível para o processo de [detecção]tox do Python do (https://virtualenv.pypa.io/en/latest/explanation.html#python-discovery). Em geral, se uma versão do Python estiver disponível via PATH, então o tox deverá ser capaz de encontrá-la e utilizá-la.

Execute apenas o conjunto de testes

Se você estiver fazendo iterações rápidas em um novo recurso, não precisa executar o conjunto completo de testes; você pode executar apenas os testes unitários. Para fazer isso, execute:

(.venv) $ tox -e py
(.venv) $ tox -e py
(.venv) C:\...>tox -e py

Executar um subconjunto de testes

Por padrão, tox executa todos os testes do conjunto de testes unitários. Ao desenvolver um novo teste, pode ser útil executar apenas esse teste específico. Para isso, você pode passar qualquer especificador pytest como argumento para tox. Esses caminhos de teste são relativos ao diretório briefcase. Por exemplo, para executar apenas os testes contidos em um único arquivo, execute:

(.venv) $ tox -e py -- tests/path_to_test_file/test_some_test.py
(.venv) $ tox -e py -- tests/path_to_test_file/test_some_test.py
(.venv) C:\...>tox -e py -- tests/path_to_test_file/test_some_test.py

Você ainda receberá um relatório de cobertura ao executar uma parte do conjunto de testes — mas os resultados de cobertura mostrarão apenas as linhas de código que foram executadas pelos testes específicos que você executou.

Execute o conjunto de testes para uma versão específica do Python

Por padrão, tox -e py será executado usando o interpretador que for identificado como python no seu computador. Se você tiver várias versões do Python instaladas e quiser testar uma versão específica entre as que estão instaladas, é possível especificar a versão do Python a ser usada. Por exemplo, para executar o conjunto de testes no Python 3.10, execute:

(.venv) $ tox -e py310
(.venv) $ tox -e py310
(.venv) C:\...>tox -e py310

É possível executar um subconjunto de testes adicionando -- e uma especificação de teste à linha de comando.

Execute o conjunto de testes sem cobertura (rápido)

Por padrão, tox executará o conjunto de testes pytest no modo de thread único. É possível acelerar a execução do conjunto de testes executando-o em paralelo. Esse modo não gera arquivos de cobertura devido às complexidades envolvidas na captura de cobertura dentro dos processos criados. Para executar uma única versão do Python no modo "rápido", execute:

(.venv) $ tox -e py-fast
(.venv) $ tox -e py-fast
(.venv) C:\...>tox -e py-fast

É possível executar um subconjunto de testes adicionando -- e uma especificação de teste à linha de comando; é possível usar uma versão específica do Python adicionando a versão ao destino do teste (por exemplo, py310-fast para executar o fast no Python 3.10).

Cobertura de código

BeeWare mantém 100% de cobertura de ramificação em seu código-fonte. Ao adicionar ou modificar código no projeto, é necessário adicionar código de teste para garantir a cobertura de todas as alterações realizadas.

No entanto, BeeWare é compatível com várias plataformas, bem como com várias versões do Python, pelo que não é possível verificar a cobertura total em uma única plataforma e versão do Python. Para contornar isso, várias regras de cobertura condicional são definidas na seção tool.coverage.coverage_conditional_plugin.rules do pyproject.toml (por exemplo, no-cover-if-is-windows pode ser usado para sinalizar um bloco de código que não será executado ao rodar o conjunto de testes no Windows). Essas regras são usadas para identificar seções de código que são cobertas apenas em plataformas ou versões específicas do Python.

É importante notar que a geração de relatórios de cobertura entre diferentes versões do Python pode apresentar algumas peculiaridades. Por exemplo, se os arquivos de cobertura forem gerados usando uma versão do Python, mas a geração do relatório for feita em outra, o relatório poderá incluir falsos positivos para ramificações não verificadas. Por esse motivo, a geração de relatórios de cobertura deve sempre utilizar a versão mais antiga do Python usada para gerar os arquivos de cobertura.

Entendendo os resultados da cobertura

No final da saída do teste de cobertura, deve haver um relatório com os dados de cobertura coletados:

Nome    Extratos   Filial ausente   Parte da conta   Cobertura   Ausente
 ---------------------------------------------------
 TOTAL    7540 0   1040 0  100,0%

Isso nos indica que o conjunto de testes executou todos os caminhos de ramificação possíveis no código. Isso não é uma garantia de 100% de que não há bugs, mas significa que estamos testando cada linha de código da base de código.

Se você fizer alterações no código-fonte, é possível que surja uma lacuna nessa cobertura. Quando isso acontecer, o relatório de cobertura indicará quais linhas não estão sendo executadas. Por exemplo, digamos que tenhamos feito uma alteração em some/interesting_file.py, adicionando uma nova lógica. O relatório de cobertura poderia ficar mais ou menos assim:

Nome Instruções   Erros de ramificação BrPart  Cobertura   Ausências
 -------------------------------------------------------------------------------
 src/some/interesting_file.py 111 1     26 0  98,1%   170, 302-307, 320->335
 -------------------------------------------------------------------------------
 TOTAL 7540 1   1726 0  99,9%

Isso indica que a linha 170, as linhas 302 a 307 e um salto de execução da linha 320 para a linha 335 não estão sendo executados pelo conjunto de testes. Você precisará adicionar novos testes (ou modificar um teste existente) para restaurar essa cobertura.

Relatório de cobertura para a plataforma de execução e a versão do Python

Você pode gerar um relatório de cobertura para a sua plataforma e versão do Python. Por exemplo, para executar o conjunto de testes e gerar um relatório de cobertura no Python 3.10, execute:

(.venv) $ tox -m test310
(.venv) $ tox -m test310
(.venv) C:\...>tox -m test310

Relatório de cobertura para a plataforma de hospedagem

Se todas as versões compatíveis do Python estiverem disponíveis para tox, a cobertura para a plataforma hospedeira pode ser gerada executando:

(.venv) $ tox p -m test-platform
(.venv) $ tox p -m test-platform
(.venv) C:\...>tox p -m test-platform

Relatórios de cobertura em HTML

É possível gerar um relatório de cobertura HTML acrescentando -html a qualquer um dos nomes de ambiente de cobertura tox, por exemplo:

(.venv) $ tox -e coverage-platform-html
(.venv) $ tox -e coverage-platform-html
(.venv) C:\...>tox -e coverage-platform-html

Não se trata apenas de escrever testes!

Embora nos certifiquemos de testar todo o nosso código, a tarefa não se resume apenas a manter esse nível de testes. Parte da tarefa consiste em revisar o código à medida que se avança. Você poderia escrever um conjunto abrangente de testes para um colete salva-vidas de concreto… mas um colete salva-vidas de concreto continuaria sendo inútil para o fim a que se destina!

À medida que você desenvolve testes, deve verificar se o módulo principal também é consistente internamente. Se você notar algum nome de método que não seja internamente consistente (por exemplo, algo chamado on_select em um módulo, mas chamado on_selected em outro), ou onde os dados não estejam sendo tratados de forma consistente, sinalize isso e nos informe criando um ticket. Ou, se você tiver certeza do que precisa ser feito, crie uma pull request que corrija o problema que você encontrou.

Depois de ter tudo funcionando, você pode enviar uma solicitação pull com suas alterações.