Uma tradução do artigo foi preparada especificamente para os alunos do curso Python QA Engineer .
Vivemos uma época em que o software está se movendo muito rapidamente para o mercado. Por isso, o processo de desenvolvimento se torna muito estressante. Altas taxas de implementação de software e entrega rápida parecem uma boa parte do modelo de negócios, mas surge a questão aqui sobre como fornecer software da qualidade certa.
Por que precisamos de testes automatizados
Existem muitas vantagens nos testes automatizados, eis três principais:
Reutilização: Não há necessidade de escrever novos scripts sempre, mesmo quando uma nova versão do sistema operacional é lançada, a menos que haja uma necessidade urgente.
Confiabilidade: as pessoas tendem a cometer erros e os carros as tornam menos prováveis. E eles funcionam mais rápido ao executar etapas / testes repetidos que precisam ser executados continuamente.
Trabalho 24/7: você pode começar a testar a qualquer hora do dia, mesmo que remotamente. Se você começar a testar à noite, ele será executado mesmo enquanto você dorme.
Desenvolvida a ferramenta de teste pytest com recursos completos em Python
Atualmente, existem muitas estruturas e ferramentas para teste. Existem diferentes tipos de estruturas, por exemplo, orientada a dados, orientada a palavras-chave, híbrida, BDD etc. Você pode escolher o que melhor se adapte às suas necessidades.
Devo dizer que Python e
pytest
ocupam um nicho enorme nesse assunto. O Python e suas ferramentas relacionadas são amplamente utilizados, provavelmente porque são mais acessíveis para pessoas com pouca experiência em programação em comparação com outras linguagens.
A estrutura
pytest
facilita a gravação de pequenos testes, mas também é dimensionada para oferecer suporte a testes funcionais sofisticados de aplicativos e bibliotecas.
Alguns recursos principais do
pytest
:
- Detecção automática de módulos e funções de teste;
- CLI eficaz para melhorar o controle sobre o que você deseja executar ou pular;
- Grande ecossistema de plugins de terceiros;
- Luminárias - tipos diferentes, aplicações diferentes;
- Trabalhe com a estrutura tradicional de teste de unidade.
Detecção de teste automática e configurável
Por padrão, o
pytest
espera encontrar testes nos módulos Python cujos nomes começam com
test_
ou terminam com
_test.py
. Além disso, por padrão, espera que os nomes das funções de teste iniciem com o prefixo
test_
. No entanto, esse protocolo de detecção de teste pode ser alterado adicionando sua própria configuração a um dos
pytest
configuração
pytest
.
Vejamos uma função de teste muito simples:
class CheckClass(object): def one_check(self): x = "this" assert 'h' in x def two_check(self): x = "hello" assert hasattr(x, 'check')
Você notou alguma coisa? Não existe
assertEqual
ou
assertDictEqual
, apenas uma
assert
acessível e compreensível. Não há necessidade de importar essas funções para simplesmente comparar dois objetos. Afirmar é o que o Python já possui e não há necessidade de reinventar a roda.
Código do modelo? Não se preocupe, os equipamentos correm para o resgate!
Veja as funções de teste que testam as operações básicas no programa Wallet:
// test_wallet.py from wallet import Wallet def test_default_initial_amount(): wallet = Wallet() assert wallet.balance == 0 wallet.close() def test_setting_initial_amount(): wallet = Wallet(initial_amount=100) assert wallet.balance == 100 wallet.close() def test_wallet_add_cash(): wallet = Wallet(initial_amount=10) wallet.add_cash(amount=90) assert wallet.balance == 100 wallet.close() def test_wallet_spend_cash(): wallet = Wallet(initial_amount=20) wallet.spend_cash(amount=10) assert wallet.balance == 10 wallet.close()
Ah, interessante! Você já reparou? Há muito código padrão. Outra coisa que vale a pena notar é que esse teste faz outra coisa além de testar a parte funcional, por exemplo, criar uma carteira e fechá-la com
wallet.close()
.
Agora vamos ver como você pode se livrar do código padrão usando os
pytest
pytest.
import pytest from _pytest.fixtures import SubRequest from wallet import Wallet
Legal, não é? As funções de teste agora são compactas e fazem exatamente o que devem fazer. A carteira é configurada, instalada e fechada usando o
wallet
da
wallet
. As luminárias não apenas ajudam a escrever códigos reutilizáveis, mas também adicionam o conceito de compartilhamento de dados. Se você observar atentamente, a quantidade na
wallet
faz parte dos dados de teste fornecidos externamente pela lógica do teste e não é rigidamente fixada dentro da função.
@pytest.mark.parametrize('wallet', [(10,)], indirect=True)
Em um ambiente mais controlado, você pode ter um arquivo com dados de teste, por exemplo
test-data.ini
em seu repositório ou shell, que pode lê-lo, enquanto sua função de teste pode chamar vários shells para ler dados de teste.
No entanto, é recomendável colocar todos os seus equipamentos em um arquivo
conftest.py
especial. Este é um arquivo especial no pytest que permite ao teste detectar equipamentos globais.
Mas tenho casos de teste que quero executar em diferentes conjuntos de dados!
Não se preocupe, o
pytest
possui um recurso interessante para parametrizar seu equipamento. Vejamos um exemplo.
Suponha que seu produto tenha uma CLI gerenciada localmente. Além disso, seu produto possui muitos parâmetros padrão definidos na inicialização e você deseja verificar todos os valores desses parâmetros.
Você pode escrever um caso de teste separado para cada um desses parâmetros, mas com o
pytest
tudo é muito mais simples!
@pytest.mark.parametrize(“setting_name, setting_value”, [('qdb_mem_usage', 'low'), ('report_crashes', 'yes'), ('stop_download_on_hang', 'no'), ('stop_download_on_disconnect', 'no'), ('reduce_connections_on_congestion', 'no'), ('global.max_web_users', '1024'), ('global.max_downloads', '5'), ('use_kernel_congestion_detection', 'no'), ('log_type', 'normal'), ('no_signature_check', 'no'), ('disable_xmlrpc', 'no'), ('disable_ntp', 'yes'), ('ssl_mode', 'tls_1_2'),])def test_settings_defaults(self, setting_name, setting_value): assert product_shell.run_command(setting_name) == \ self.”The current value for \'{0}\' is \'{1}\'.”.format(setting_name, setting_value), \ 'The {} default should be {}'.format(preference_name, preference_value)
Legal, não é? Você acabou de escrever 13 casos de teste (cada um define um valor de configuração diferente) e, no futuro, se você adicionar um novo parâmetro ao seu produto, tudo o que você precisa fazer é adicionar outra tupla.
Como o pytest se integra aos testes de interface do usuário com os testes Selenium e API?
Bem, seu produto pode ter várias interfaces. CLI - como dissemos acima. Semelhante à GUI e API. Antes de implantar seu produto de software, é importante testar todos eles. No software corporativo, onde vários componentes estão interconectados e dependem um do outro, uma mudança em uma parte pode afetar todas as outras.
Lembre-se de que o
pytest
é apenas uma estrutura para testes fáceis, não um tipo específico de teste. Ou seja, você pode criar testes para a GUI usando o Selenium ou, por exemplo, testes para a API com a biblioteca de
requests
do Python e executá-los com o
pytest
.
Por exemplo, em um nível alto, isso pode ser uma verificação da estrutura do repositório.

Como você pode ver na imagem acima, é uma boa oportunidade para separar os componentes:
apiobjects : um bom lugar para criar wrappers para chamar pontos de extremidade da API. Você pode ter um
BaseAPIObject
e uma classe derivada que atenda aos seus requisitos.
ajudantes : você pode adicionar seus métodos auxiliares aqui.
lib : arquivos de biblioteca que podem ser usados por vários componentes, por exemplo, seus
conftest
em
conftest
,
pageobjects
, etc.
pageobjects : O
PageObjects
arquitetura
PageObjects pode ser usado para criar classes para várias páginas da GUI. Usamos o
Webium , que é uma biblioteca de implementações de modelos de objeto de página para Python.
suites : você pode escrever seus próprios conjuntos de verificações pylint para obter códigos, eles ajudarão você a ganhar mais confiança na qualidade do seu código.
testes : você pode catalogar testes com base em suas preferências. Isso facilitará o gerenciamento e a revisão de seus testes.
Trouxe-o apenas para referência, a estrutura do repositório e as dependências podem ser organizadas de acordo com suas necessidades pessoais.
Eu tenho muitos casos de teste e quero que eles sejam executados em paralelo
Você pode ter muitos casos de teste em seu conjunto, e acontece que é necessário executá-los em paralelo e reduzir o tempo geral de execução do teste.
O Pytest oferece um incrível plugin de execução de teste paralelo chamado
pytest-xdist
, que adiciona vários modos de execução exclusivos ao pytest de base. Instale este plugin usando
pip
.
pip install pytest-xdist
Vamos ver como isso funciona com um exemplo.
Eu tenho um repositório de testes automatizados do CloudApp para meus testes da GUI do Selenium. Além disso, está em constante crescimento e atualização com novos testes e agora possui centenas de testes. O que eu quero fazer é executá-los em paralelo e reduzir o tempo geral de execução do teste.
No terminal, basta digitar
pytest
na pasta raiz do projeto / pasta de teste. Isso permitirá que você execute todos os testes.
pytest -s -v -n=2

pytest-xdist
irá executar todos os testes em paralelo!
Dessa forma, você também pode executar vários navegadores em paralelo.
Relatórios
O Pytest vem com suporte interno para a criação de arquivos de resultados de teste que podem ser abertos usando Jenkins, Bamboo ou outros servidores de integração contínua. Use o seguinte:
pytest test/file/path — junitxml=path
Isso ajudará a gerar um ótimo arquivo XML que pode ser aberto com muitos analisadores.
Conclusão
A popularidade do Pytest está crescendo a cada ano. Além disso, possui um poderoso suporte da comunidade, que permite acessar muitas extensões, como
pytest-django , que o ajudará a escrever testes para aplicativos da web no Django. Lembre-se de que o pytest suporta casos de teste mais unittest; portanto, se você usar o
unittest
, o pytest deve ser considerado com mais detalhes.
Fontes
Só isso. Vejo você no
curso !