Se você está escrevendo uma biblioteca ou um aplicativo, para onde vão os arquivos de teste de unidade?
É bom separar os arquivos de teste do código principal do aplicativo, mas é complicado colocá-los em um subdiretório "tests" dentro do diretório raiz do aplicativo, porque fica mais difícil importar os módulos que você testará.
Existe uma prática recomendada aqui?
python
unit-testing
code-organization
Somente leitura
fonte
fonte
Respostas:
Para um arquivo
module.py
, o teste de unidade deve normalmente ser chamadotest_module.py
, seguindo as convenções de nomenclatura Pythonic.Existem vários lugares comumente aceitos para colocar
test_module.py
:module.py
.../tests/test_module.py
(no mesmo nível que o diretório de código).tests/test_module.py
(um nível no diretório de código).Eu prefiro o número 1 por sua simplicidade de encontrar os testes e importá-los. Qualquer que seja o sistema de construção que você esteja usando, pode ser facilmente configurado para executar arquivos começando com
test_
. Na verdade, o padrãounittest
padrão usado para a descoberta de teste étest*.py
.fonte
Apenas 1 arquivo de teste
Se houver apenas 1 arquivo de teste, é recomendável colocá-lo em um diretório de nível superior:
Execute o teste na CLI
Muitos arquivos de teste
Se houver muitos arquivos de teste, coloque-o em uma
tests
pasta:Execute o teste na CLI
Usar
unittest discovery
unittest discovery
encontrará todos os testes na pasta do pacote.Crie uma pasta
__init__.py
natests/
Execute o teste na CLI
Referência
pytest
Boas práticas para o layout de testeunittest
Estrutura de teste de unidade
fonte
Uma prática comum é colocar o diretório de testes no mesmo diretório pai do seu módulo / pacote. Portanto, se seu módulo foi chamado foo.py, seu layout de diretório seria semelhante a:
Claro que não há uma maneira de fazê-lo. Você também pode criar um subdiretório de testes e importar o módulo usando a importação absoluta .
Onde quer que você faça seus testes, recomendo que você use o nariz para executá-los. O nariz pesquisa nos diretórios por testes. Dessa forma, você pode fazer testes sempre que eles fizerem mais sentido organizacional.
fonte
Tivemos a mesma pergunta ao escrever o Pythoscope ( https://pypi.org/project/pythoscope/ ), que gera testes de unidade para programas Python. Pesquisamos pessoas na lista de testes em python antes de escolhermos um diretório, havia muitas opiniões diferentes. No final, escolhemos colocar um diretório "tests" no mesmo diretório que o código-fonte. Nesse diretório, geramos um arquivo de teste para cada módulo no diretório pai.
fonte
Eu também tendem a colocar meus testes de unidade no próprio arquivo, como observa Jeremy Cantrell acima, embora eu não coloque a função de teste no corpo principal, mas coloque tudo em um
quadra. Isso acaba adicionando documentação ao arquivo como 'código de exemplo' de como usar o arquivo python que você está testando.
Devo acrescentar, tendo a escrever módulos / classes muito restritos. Se seus módulos exigirem um número muito grande de testes, você poderá colocá-los em outro, mas mesmo assim, eu ainda acrescentaria:
Isso permite que qualquer pessoa que esteja lendo seu código-fonte saiba onde procurar o código de teste.
fonte
De vez em quando eu me pego conferindo o tópico de colocação de teste, e toda vez a maioria recomenda uma estrutura de pastas separada ao lado do código da biblioteca, mas acho que toda vez que os argumentos são os mesmos e não são tão convincentes. Acabo colocando meus módulos de teste em algum lugar ao lado dos módulos principais.
A principal razão para fazer isso é: refatoração .
Quando movo as coisas, quero que os módulos de teste sejam movidos com o código; é fácil perder testes se eles estiverem em uma árvore separada. Sejamos honestos, mais cedo ou mais tarde você acaba com uma estrutura de pastas totalmente diferente, como django , balão e muitas outras. O que é bom se você não se importa.
A principal questão que você deve se perguntar é:
Estou escrevendo:
Se um:
Uma pasta separada e o esforço extra para manter sua estrutura podem ser mais adequados. Ninguém vai reclamar dos seus testes sendo implantados na produção .
Mas também é fácil excluir os testes da distribuição quando eles são misturados às pastas principais; coloque isso no setup.py :
Se b:
Você pode desejar - como todos nós - que esteja escrevendo bibliotecas reutilizáveis, mas na maioria das vezes a vida delas está ligada à vida do projeto. A capacidade de manter facilmente seu projeto deve ser uma prioridade.
Então, se você fez um bom trabalho e seu módulo é adequado para outro projeto, ele provavelmente será copiado - não bifurcado ou transformado em uma biblioteca separada - para esse novo projeto e movendo testes que ficam ao lado dele na mesma estrutura de pastas é fácil em comparação com a busca de testes em uma bagunça em que uma pasta de teste separada se tornou. (Você pode argumentar que não deve ser uma bagunça em primeiro lugar, mas vamos ser realistas aqui).
Portanto, a escolha ainda é sua, mas eu argumentaria que, com testes confusos, você realiza as mesmas coisas que em uma pasta separada, mas com menos esforço para manter as coisas organizadas.
fonte
Eu uso um
tests/
diretório e, em seguida, importo os principais módulos de aplicativos usando importações relativas. Portanto, em MyApp / tests / foo.py, pode haver:para importar o
MyApp.foo
módulo.fonte
Não acredito que exista uma "melhor prática" estabelecida.
Coloquei meus testes em outro diretório fora do código do aplicativo. Em seguida, adiciono o diretório principal do aplicativo ao sys.path (permitindo importar os módulos de qualquer lugar) no script do executor de teste (que faz outras coisas também) antes de executar todos os testes. Dessa forma, nunca preciso remover o diretório de testes do código principal ao liberá-lo, poupando tempo e esforço, se houver uma quantidade muito pequena.
fonte
os.sys.path.append(os.dirname('..'))
Da minha experiência no desenvolvimento de estruturas de teste em Python, sugiro colocar testes de unidade python em um diretório separado. Mantenha uma estrutura de diretório simétrica. Isso seria útil para empacotar apenas as bibliotecas principais e não empacotar os testes de unidade. Abaixo é implementado através de um diagrama esquemático.
Dessa maneira, quando você empacota essas bibliotecas usando um rpm, você pode apenas empacotar os módulos principais da biblioteca (apenas). Isso ajuda na manutenção, principalmente em ambientes ágeis.
fonte
Eu recomendo que você verifique alguns dos principais projetos Python no GitHub e tenha algumas idéias.
Quando seu código aumenta e você adiciona mais bibliotecas, é melhor criar uma pasta de teste no mesmo diretório que você configurou.py e espelhar sua estrutura de diretórios de projeto para cada tipo de teste (mais unittest, integração, ...)
Por exemplo, se você tiver uma estrutura de diretórios como:
Após adicionar a pasta de teste, você terá uma estrutura de diretórios como:
Muitos pacotes Python escritos corretamente usam a mesma estrutura. Um exemplo muito bom é o pacote Boto. Verifique https://github.com/boto/boto
fonte
matplotlib
, está emmatplotlib/lib/matplotlib/tests
( github.com/matplotlib/matplotlib/tree/… ),sklearn
emscikitelearn/sklearn/tests
( github.com/scikit-learn/scikit-learn/tree/master/sklearn/tests )Como eu faço isso...
Estrutura de pastas:
Setup.py aponta para src / como o local que contém meus módulos de projetos e, em seguida, corro:
O que adiciona meu projeto aos pacotes de sites, apontando para minha cópia de trabalho. Para executar meus testes eu uso:
Usando o corredor de teste que eu configurei.
fonte
code.py
. Seria mais sensato chamar o diretório de nível superior "projeto".Eu prefiro o diretório de testes de nível superior. Isso significa que as importações se tornam um pouco mais difíceis. Para isso eu tenho duas soluções:
test_suite='tests.runalltests.suite'
entrarsetup()
e executar os testes simplesmente:python setup.py test
PYTHONPATH=. python tests/runalltests.py
Veja como esse material é suportado pelo código no M2Crypto:
Se você preferir executar testes com testes nos, pode ser necessário fazer algo um pouco diferente.
fonte
Nós usamos
Em cada arquivo de teste nós inserimos
../src/
nosys.path
. Não é a melhor solução, mas funciona. Eu acho que seria ótimo se alguém aparecesse com algo como o maven em java que oferece convenções padrão que simplesmente funcionam, não importa em que projeto você trabalha.fonte
Se os testes forem simples, basta colocá-los na documentação - a maioria das estruturas de teste do Python poderá usar isso:
Para outros testes mais envolvidos, eu os colocaria dentro
../tests/test_module.py
ou dentrotests/test_module.py
.fonte
Em C #, geralmente separo os testes em um assembly separado.
No Python - até agora - eu costumava escrever testes de documentos, onde o teste está na cadeia de caracteres de uma função, ou colocá-los no
if __name__ == "__main__"
bloco na parte inferior do módulo.fonte
Ao escrever um pacote chamado "foo", colocarei testes de unidade em um pacote separado "foo_test". Módulos e subpacotes terão o mesmo nome que o módulo do pacote SUT. Por exemplo, testes para um módulo foo.xy são encontrados em foo_test.xy Os arquivos __init__.py de cada pacote de teste contêm um conjunto AllTests que inclui todos os conjuntos de testes do pacote. O setuptools fornece uma maneira conveniente de especificar o pacote de teste principal, para que, após "python setup.py develop", você possa usar "python setup.py test" ou "python setup.py test" ou "python setup.py test -s foo_test.x.SomeTestSuite" para o diretório apenas uma suíte específica.
fonte
Coloquei meus testes no mesmo diretório que o código em teste (CUT); para
foo.py
os testes serãofoo_ut.py
iguais ou semelhantes. (Eu ajusto o processo de descoberta de teste para encontrá-los.)Isso coloca os testes ao lado do código em uma lista de diretórios, tornando óbvio que os testes existem e facilita a abertura dos testes quando possível em um arquivo separado. (Para editores de linha de comando
vim foo*
e ao usar um navegador gráfico de sistema de arquivos, basta clicar no arquivo CUT e, em seguida, no arquivo de teste imediatamente adjacente.)Como outros já apontaram , isso também facilita refatorar e extrair o código para uso em outro lugar, caso isso seja necessário.
Eu realmente não gosto da idéia de colocar testes em uma árvore de diretórios completamente diferente; por que dificultar o necessário para os desenvolvedores abrirem os testes quando estão abrindo o arquivo com o CUT? Não é como se a grande maioria dos desenvolvedores estivesse tão interessada em escrever ou ajustar os testes que eles ignorariam qualquer barreira para fazer isso, em vez de usá-la como desculpa. (Muito pelo contrário, na minha experiência; mesmo quando você torna o mais fácil possível, conheço muitos desenvolvedores que não podem se preocupar em escrever testes.)
fonte
Recentemente, comecei a programar em Python, então ainda não tive chance de descobrir as melhores práticas. Mas, eu escrevi um módulo que encontra e encontra todos os testes e os executa.
Então eu tenho:
Vou ter que ver como vai o andamento de projetos maiores.
fonte