Uygulamanızın test dizini olduğunda Django'da belirli bir test senaryosu çalıştırma


165

Django belgeleri ( http://docs.djangoproject.com/en/1.3/topics/testing/#running-tests ), test senaryolarını tek tek belirleyerek çalıştırabileceğinizi söylüyor:

$ ./manage.py test animals.AnimalTestCase

Bu, testlerinizi Django uygulamanızdaki bir tests.py dosyasında yaptığınızı varsayar. Bu doğruysa, bu komut beklendiği gibi çalışır.

Bir test dizininde bir Django uygulaması için benim testleri var:

my_project/apps/my_app/
├── __init__.py
├── tests
   ├── __init__.py
   ├── field_tests.py
   ├── storage_tests.py
├── urls.py
├── utils.py
└── views.py

tests/__init__.pyDosya bir paketi () işlevi vardır:

import unittest

from my_project.apps.my_app.tests import field_tests, storage_tests

def suite():
    tests_loader = unittest.TestLoader().loadTestsFromModule
    test_suites = []
    test_suites.append(tests_loader(field_tests))
    test_suites.append(tests_loader(storage_tests))
    return unittest.TestSuite(test_suites)

Testleri yapmak için:

$ ./manage.py test my_app

Tek bir test senaryosu belirtmeye çalışmak bir istisna oluşturur:

$ ./manage.py test my_app.tests.storage_tests.StorageTestCase
...
ValueError: Test label 'my_app.tests.storage_tests.StorageTestCase' should be of the form app.TestCase or app.TestCase.test_method

İstisna mesajının söylediklerini yapmaya çalıştım:

$ ./manage.py test my_app.StorageTestCase
...
ValueError: Test label 'my_app.StorageTestCase' does not refer to a test

Testlerim birden fazla dosyadayken ayrı bir test durumunu nasıl belirleyebilirim?

Yanıtlar:


156

Ödeme django-burun . Çalıştırılacak testleri belirtmenize izin verir:

python manage.py test another.test:TestCase.test_method

veya yorumlarda belirtildiği gibi sözdizimini kullanın:

python manage.py test another.test.TestCase.test_method

Teşekkürler @sdolan. Hekevintran ile aynı problemle karşılaştı. Django-burnuna geçti ve bu sorunu düzeltti, ayrıca varsayılan Django test koşucusundan çok daha iyi çalışıyor.
LeeMobile

Bu bir test çalıştırır, ancak tüm TestCase nasıl çalıştırılır?
jMyles

5
@JMyles:another.test:TestCase
Sam Dolan

4
Stackoverflow'dan körü körüne yapıştıran benim gibi insanların dikkatine: Bu, söz konusu eklenti olmadan hata verecektir, Django 1.6+ ile çalışan diğer cevapta (. Yerine :) sözdizimini kullanın.
Andy Smith

1
Bu cevabı reddettim, çünkü aslında OP'nin Django'da nasıl yapılacağı sorusunu cevaplamıyor. Aksine, Nosetest'e geçmenizi önerir
Josh Brown

175

Django 1.6'dan beri, çalıştırmak istediğiniz öğe için tam nokta gösterimini kullanarak tam bir test durumu veya tek bir test çalıştırabilirsiniz.

Otomatik sınama keşfi artık çalışma dizini altında sınama ile başlayan herhangi bir dosyada sınama bulur , bu nedenle dosyalarınızı yeniden adlandırmanız gerekeceği sorusunu ele alırsınız, ancak artık bunları istediğiniz dizinde tutabilirsiniz. Özel dosya adları kullanmak istiyorsanız, seçenek işaretli bir desen (varsayılan Django test çalıştırıcısı) belirleyebilirsiniz --pattern="my_pattern_*.py".

Eğer içindedir Yani eğer manage.pydizin ve testi yapmak istiyorsunuz test_aiçindeki TestCasealt sınıf Abir dosya içinde tests.pyuygulamanın altındaki / modülü exampleyapardın:

python manage.py test example.tests.A.test_a

Bir bağımlılık eklemek istemiyorsanız ve Django 1.6 veya sonraki bir sürümdeyseniz, bunu böyle yaparsınız.

Daha fazla bilgi için Django belgelerine bakın


Bu özelliği şimdi Django'da yerleşik olarak görmek güzel.
hekevintran

Bunu hiç çalışamıyorum: error: option --pattern not recognizedveinvalid command name
jeoidesic

Bu Django v3'te harika çalışıyor!
Kirk

11

Bu sorunu kendim yaşıyordum ve bu soruyu buldum, eğer başka biri gelirse, işte kazdım. DjangoTestSuiteRuner, etikete dayalı olarak hangi test senaryolarının çalıştırılacağını anlayan build_test (label) adlı bir yöntem kullanır. Bu yönteme bakıldığında, "modeller" veya "test" modülünde bir getattr () yaptıkları ortaya çıkıyor. Bu, test çalıştırıcısının bu paketteki test senaryolarınızı aramadığı bir paketi döndürürseniz, yalnızca bu modüllerden birine bakar.

Hızlı bir çözüm, __init__.pybir paketi tanımlamak yerine testlerinizi doğrudan içe aktarmak için kullanmaktır . Onları "test" modülünün bir parçası yapar ve böylece build_test (etiket) onları bulabilirsiniz.

Yukarıdaki örneğiniz için tests/__init__.pyşunları içermesi gerekir:

from field_tests import *
from storage_tests import *

Bu çok zarif değil ve elbette süitinizle daha karmaşık bir şey yapmaya çalışıyorsanız, bu işe yaramaz, ancak bu durumda olur.




3

Bu kodu __init__.py dosyanıza koyun, tüm test sınıflarını pakete ve alt paketlere aktarın. Bu, her dosyayı manuel olarak içe aktarmadan belirli testleri çalıştırmanızı sağlar.

import pkgutil
import unittest

for loader, module_name, is_pkg in pkgutil.walk_packages(__path__):
    module = loader.find_module(module_name).load_module(module_name)
    for name in dir(module):
        obj = getattr(module, name)
        if isinstance(obj, type) and issubclass(obj, unittest.case.TestCase):
            exec ('%s = obj' % obj.__name__)

Benzer şekilde, test paketiniz için şunları kullanabilirsiniz:

def suite():   
    return unittest.TestLoader().discover("appname.tests", pattern="*.py")

Şimdi yeni testler için yapmanız gereken tek şey onları yazmak ve testler klasöründe olduklarından emin olmaktır. İthalatın sıkıcı bakımı yok!

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.