ใช้กรณีทดสอบเฉพาะใน Django เมื่อแอปของคุณมีไดเรกทอรีทดสอบ


165

เอกสาร Django ( http://docs.djangoproject.com/en/1.3/topics/testing/#running-tests ) บอกว่าคุณสามารถเรียกใช้กรณีทดสอบเฉพาะบุคคลได้โดยระบุ:

$ ./manage.py test animals.AnimalTestCase

นี่ถือว่าคุณมีการทดสอบในไฟล์ tests.py ในแอปพลิเคชัน Django ของคุณ หากสิ่งนี้เป็นจริงคำสั่งนี้จะทำงานเหมือนที่คาดไว้

ฉันมีแบบทดสอบสำหรับแอปพลิเคชัน Django ในไดเรกทอรีการทดสอบ:

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

tests/__init__.pyไฟล์มีห้องสวีท () ฟังก์ชัน:

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)

เพื่อรันการทดสอบที่ฉันทำ:

$ ./manage.py test my_app

การพยายามระบุกรณีทดสอบรายบุคคลทำให้เกิดข้อยกเว้น:

$ ./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

ฉันพยายามทำสิ่งที่ข้อความข้อยกเว้นกล่าวว่า:

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

ฉันจะระบุกรณีทดสอบเฉพาะบุคคลได้อย่างไรเมื่อการทดสอบของฉันมีหลายไฟล์?

คำตอบ:


156

กร้าDjango จมูก อนุญาตให้คุณระบุการทดสอบเพื่อให้ทำงานเช่น:

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

หรือตามที่ระบุไว้ในความคิดเห็นใช้ไวยากรณ์:

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

ขอบคุณ @ sdolan พบปัญหาเดียวกันกับ hekevintran เปลี่ยนเป็น django-nose และแก้ไขปัญหาดังกล่าวแล้วยังทำงานได้ดีกว่านักวิ่งทดสอบ Django ที่เป็นค่าเริ่มต้น
LeeMobile

สิ่งนี้จะทำการทดสอบ แต่จะเรียกใช้ TestCase ทั้งหมดได้อย่างไร
jMyles

5
@jMyles:another.test:TestCase
Sam Dolan

4
คนที่สนใจเช่นฉันที่สุ่มสี่สุ่มห้าวางจาก Stackoverflow: ข้อผิดพลาดนี้จะไม่มีปลั๊กอินที่กล่าวถึงให้ใช้ไวยากรณ์ที่อธิบายไว้ในคำตอบอื่น ๆ (. แทน :) ซึ่งใช้งานได้ใน Django 1.6+
Andy Smith

1
ฉันลงคะแนนคำตอบนี้เพราะจริง ๆ แล้วไม่ได้ตอบคำถามของ OP ซึ่งเป็นวิธีการทำเช่นนี้ใน Django ค่อนข้างเป็นการแนะนำให้เปลี่ยนไปใช้ Nosetest
Josh Brown เมื่อ

175

ตั้งแต่ Django 1.6 คุณสามารถเรียกใช้กรณีทดสอบที่สมบูรณ์หรือการทดสอบเดี่ยวโดยใช้เครื่องหมายจุดที่สมบูรณ์สำหรับองค์ประกอบที่คุณต้องการเรียกใช้

ตอนนี้การค้นหาทดสอบอัตโนมัติจะค้นหาการทดสอบในไฟล์ใด ๆ ที่ขึ้นต้นด้วยการทดสอบภายใต้ไดเรกทอรีทำงานดังนั้นการระบุคำถามที่คุณต้องเปลี่ยนชื่อไฟล์ของคุณ แต่ตอนนี้คุณสามารถเก็บไว้ในไดเรกทอรีที่คุณต้องการ หากคุณต้องการที่จะใช้ชื่อไฟล์ที่กำหนดเองคุณสามารถระบุรูปแบบ (เริ่มต้น Django วิ่งทดสอบ) --pattern="my_pattern_*.py"ที่มีธงตัวเลือก

ดังนั้นหากคุณอยู่ในmanage.pyไดเรกทอรีของคุณและต้องการเรียกใช้การทดสอบtest_aภายในTestCaseคลาสย่อยAภายในไฟล์tests.pyภายใต้แอพ / โมดูลexampleคุณจะทำ:

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

หากคุณไม่ต้องการรวมการพึ่งพาและอยู่ใน Django 1.6 หรือใหม่กว่านั้นเป็นวิธีที่คุณทำ

ดูเอกสารประกอบของ Django สำหรับข้อมูลเพิ่มเติม


ดีใจที่ได้เห็นฟีเจอร์นี้สร้างขึ้นใน Django
hekevintran

ฉันไม่สามารถทำงานนี้ได้เลย: error: option --pattern not recognizedและinvalid command name
geoidesic

ใช้งานได้ดีใน Django v3!
Kirk

11

ฉันมีปัญหานี้ด้วยตนเองและพบคำถามนี้ในกรณีที่มีคนอื่นมานี่คือสิ่งที่ฉันขุดขึ้นมา DjangoTestSuiteRuner ใช้วิธีการที่เรียกว่า build_test (ฉลาก) ซึ่งระบุว่ากรณีทดสอบใดบ้างที่จะเรียกใช้ตามฉลาก เมื่อมองไปที่วิธีการนี้แล้วปรากฎว่าพวกเขากำลังทำ getattr () บนทั้งโมดูล "รุ่น" หรือ "ทดสอบ" ซึ่งหมายความว่าหากคุณส่งคืนชุดทดสอบที่ไม่ได้มองหากรณีทดสอบของคุณในชุดนั้นมันจะมองเฉพาะในหนึ่งในโมดูลเหล่านั้น

วิธีแก้ปัญหาอย่างรวดเร็วคือใช้__init__.pyเพื่อนำเข้าการทดสอบของคุณโดยตรงแทนที่จะกำหนดชุด ทำให้พวกมันเป็นส่วนหนึ่งของโมดูล "test" และ build_test (label) สามารถค้นหาได้

สำหรับตัวอย่างของคุณด้านบนtests/__init__.pyควรมี:

from field_tests import *
from storage_tests import *

นี่ไม่ใช่สิ่งที่สวยงามมากและแน่นอนว่าถ้าคุณกำลังพยายามทำสิ่งที่ซับซ้อนกว่าในห้องสวีทของคุณสิ่งนี้จะไม่ทำงาน แต่สำหรับกรณีนี้



4

ฉันยังวิ่งเข้าไปในปัญหานี้และแทนการใช้ Django จมูกผมทำตามลิงค์นี้ที่นี่: http://www.pioverpi.net/2010/03/10/organizing-django-tests-into-folders/ คุณต้องเปิดคุณ. initและนำเข้าการทดสอบของคุณ

Ex ในinit .py:from unique_test_file import *


3

ใส่รหัสนี้ใน __init__.py ของคุณแล้วมันจะนำเข้าคลาสการทดสอบทั้งหมดในแพ็คเกจและแพ็คเกจย่อย วิธีนี้จะช่วยให้คุณเรียกใช้การทดสอบเฉพาะโดยไม่ต้องนำเข้าไฟล์ทุกไฟล์

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__)

ในทำนองเดียวกันสำหรับชุดทดสอบคุณสามารถใช้:

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

ตอนนี้สิ่งที่คุณต้องทำสำหรับการทดสอบใหม่คือเขียนและตรวจสอบให้แน่ใจว่าพวกเขาอยู่ในโฟลเดอร์การทดสอบ ไม่มีการนำเข้าบำรุงรักษาที่น่าเบื่ออีกต่อไป!

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.