จะรันการทดสอบหน่วย django บนฐานข้อมูลการผลิตได้อย่างไร

ฉันกำลังเริ่มต้นทัศนคติในการพัฒนา TDD และกำลังเขียนการทดสอบหน่วยสำหรับแอปพลิเคชัน django ของฉัน ฉันตระหนักถึงฟิกซ์เจอร์และรู้ว่านั่นคือวิธีดำเนินการทดสอบ แต่สำหรับการทดสอบที่กำหนด ฉันจำเป็นต้องดำเนินการกับฐานข้อมูลทั้งหมด และฟิกซ์เจอร์ json สำหรับฐานข้อมูลมากกว่า 10 ล้านแถวไม่ใช่สิ่งที่ฉันต้องการจัดการ ยิ่งไปกว่านั้น การทดสอบนี้เป็นแบบ "อ่านอย่างเดียว"

คำถามคือคุณจะตั้งค่าชุดการทดสอบให้ทำงานบนฐานข้อมูลที่ใช้งานจริงได้อย่างไร ฉันคิดว่ามันอาจจะง่ายพอ ๆ กับการเพิ่มการตั้งค่า DATABASE_NAME ในวิธีการตั้งค่าของการทดสอบบางอย่าง แต่การตั้งค่า DATABASE_NAME="prod_db" ส่งผลให้เกิด "NameError: ไม่ได้กำหนดชื่อสากล 'การตั้งค่า'" ในขณะที่รันการทดสอบ นอกจากนี้ ยังมีความเสี่ยงที่อธิบายไว้ใน http://code.djangoproject.com/ticket/11987 ที่คุณสามารถลบฐานข้อมูลการผลิตโดยไม่ตั้งใจได้

ดังนั้น เป็นไปได้อย่างไร หรือดีไปกว่านั้น คือแนวทางปฏิบัติที่ดีที่สุดในการรันการทดสอบชุดทดสอบเดี่ยวบนฐานข้อมูลที่ใช้งานจริงแทนที่จะเป็นการทดสอบชั่วคราว

ไชโยล่วงหน้าสำหรับความคิดเห็นใด ๆ !


person James    schedule 29.10.2009    source แหล่งที่มา


คำตอบ (5)


ประการแรก หากคุณใช้งานบนฐานข้อมูลที่ใช้งานจริง ก็จะไม่ใช่การทดสอบแบบ "หน่วย" มากนัก

เป็นงานแบตช์ชั้นหนึ่งและจำเป็นต้องได้รับการปฏิบัติเหมือนงานแบตช์การผลิตชั้นหนึ่ง

คุณไม่สามารถใช้คำสั่ง Django test เพื่อดูข้อมูลการผลิตได้ มันจะสร้างฐานข้อมูลว่างซึ่งบรรจุจากฟิกซ์เจอร์ใน TestCase เสมอ

คุณสามารถทำให้ฐานข้อมูลการผลิตของคุณประมวลผล คำสั่งการจัดการ นี่เป็นสภาพแวดล้อมที่ได้รับการกำหนดค่าอย่างเหมาะสมเพื่อให้คำสั่งของคุณสามารถใช้ Django ORM เพื่อประมวลผลข้อมูลของคุณได้

ทางเลือกอื่นคือต้องแน่ใจว่าคุณได้กำหนด การตั้งค่า ของคุณ ใช้ตัวแปรสภาพแวดล้อม DJANGO_SETTINGS_MODULE หรือใช้ฟังก์ชัน settings.configure() เพื่อสร้างสภาพแวดล้อม

จากนั้นคุณสามารถนำเข้าแบบจำลองและดำเนินการตามที่คุณต้องการกับฐานข้อมูลที่ใช้งานจริงได้

คุณสามารถเรียกมันว่า "ทดสอบ" ได้ถ้าคุณต้องการ แต่คุณกำลังดูข้อมูลการผลิต ดังนั้นจึงต้องได้รับการปฏิบัติเหมือนเป็นแอปพลิเคชันที่ใช้งานจริงที่เกี่ยวข้องกับการรับไฟล์การตั้งค่าและการใช้การกำหนดค่า ORM ที่เหมาะสม

person S.Lott    schedule 29.10.2009
comment
ขอบคุณสำหรับคำตอบที่ดี! ฉันยอมรับว่านั่นไม่ใช่แนวทางปฏิบัติที่ดีที่สุดเลยที่ฉันพยายามทำให้สำเร็จ การเขียนคำสั่งการจัดการที่เหมาะสมดูเหมือนจะเป็นวิธีที่ถูกต้องในการจัดการกับสถานการณ์เช่นนี้ ขอบคุณสำหรับทิศทาง! ฉันเดาว่าฉันจะทำแบบนั้น แต่เพื่อที่จะพบว่าสิ่งนั้น เป็นไปได้ เป็นไปได้ คุณช่วยระบุวิธีใช้ settings.configure() ในกรณีของฉันอย่างถูกต้องได้ไหม วางจากการตั้งค่าการนำเข้า django.conf และ settings.configure(DATABASE_NAME=prod_db) ในผลการทดสอบหน่วยในการตั้งค่าข้อผิดพลาดรันไทม์ที่กำหนดค่าไว้แล้ว (และนั่นคือสิ่งที่เอกสารพูด) - person James; 30.10.2009
comment
แม้ว่าเอกสารจะบอกว่าไม่ควรทำการแก้ไขการตั้งค่าขณะรันไทม์ แต่นั่นเป็นวิธีที่ฉันจินตนาการถึงปัญหานี้สามารถแก้ไขได้ BTW, Steven ฉันได้ตรวจสอบเว็บไซต์ของคุณแล้ว และทั้ง Python สำหรับโปรแกรมเมอร์และการออกแบบเชิงวัตถุสำหรับโปรแกรมเมอร์ก็กลายเป็นหนังสือยอดนิยมในรายการ tor-ead-next ของฉัน ขอบคุณมากสำหรับการเขียนและแบ่งปัน! - person James; 30.10.2009
comment
คุณไม่สามารถเปลี่ยนการตั้งค่า Django ขณะรันไทม์ได้ คุณสามารถระบุการตั้งค่าผ่านไฟล์หรือผ่านวิธี .configure() เลือกหนึ่ง. ไม่มีการตั้งค่าแบบไดนามิก - person S.Lott; 30.10.2009
comment
ฉันไม่เข้าใจว่าทำไมคุณถึงลองทั้ง DJANGO_SETTINGS_MODULE และ settings.confgure() เพียงแค่เลือกหนึ่ง คุณสามารถมีไฟล์การตั้งค่าได้หลายไฟล์ (มีชื่อต่างกัน) คุณสามารถใช้ไฟล์ settings หนึ่งไฟล์สำหรับการทดสอบหน่วยและการสแกนฐานข้อมูลที่ใช้งานจริงเหล่านี้ - person S.Lott; 30.10.2009
comment
หากสิ่งที่ @James อธิบายคือการทดสอบ BDD หรือที่เรียกว่า การทดสอบฟังก์ชัน หรือ การทดสอบการรวมระบบ ซึ่งอาจทำได้ดีที่สุดด้วยเครื่องมือเช่น ประพฤติตัว ดังนั้น จึงอาจสมเหตุสมผลอย่างยิ่งที่จะเรียกใช้งานกับฐานข้อมูลที่ใช้งานจริง (สำเนาของ) เพียงสองเซ็นต์ของฉันในการสนทนา ... - person Peterino; 27.05.2015
comment
@Peterino ฉันรู้ว่าเมื่อฉันเริ่มการทดสอบซึ่งทำให้ฉันมาถึงคำถามนี้ว่าเป็นการทดสอบบูรณาการ แต่ฉันไม่รู้ behave ขอบคุณสำหรับเครื่องมือใหม่ที่จะเรียนรู้ (ฉันชอบที่จะใช้การทดสอบของฉันโดยใช้พฤติกรรมตอนนี้ แต่เนื่องจากข้อจำกัดด้านเวลา พวกเขาจะต้องคงคำสั่งการจัดการ django ไว้ในตอนนี้) - person hlongmore; 21.02.2018
comment
@hlongmore ขณะที่คุณกำลังใช้ Django คุณอาจต้องการดูที่ behave-django, github.com/behave/ ประพฤติ-django. มีการสนับสนุนในตัวสำหรับการทดสอบกับ (สำเนา) ของฐานข้อมูลที่มีอยู่ - person Peterino; 21.02.2018

ในกรณีที่มีคนค้นหาวิธีแก้ไขปัญหาใน Google ที่นี่ นี่คือโครงกระดูกเกี่ยวกับวิธีการทดสอบหน่วยในฐานข้อมูลการผลิต django ตรวจสอบส่วนเอกสาร django ที่นี่ สำหรับโครงสร้างไฟล์/ไดเร็กทอรี และคำแนะนำเกี่ยวกับตำแหน่งที่จะวางโค้ดที่กำหนด ควรอยู่ใน yourapp/management/commands/newcommandname.py และทั้งโฟลเดอร์การจัดการและคำสั่งควรมีไฟล์ __init__.py เปล่า ซึ่งทำให้หลามถือว่าไฟล์เหล่านี้เป็นโมดูลที่ถูกต้อง

ชุดทดสอบสามารถรันเป็น:

$python Manage.py ชื่อคำสั่งใหม่

และนี่คือโค้ดที่คุณควรใส่ใน yourapp/management/commands/newcommandname.py:

from django.core.management.base import BaseCommand
import unittest

class Command(BaseCommand):
    help = """
    If you need Arguments, please check other modules in 
    django/core/management/commands.
    """

    def handle(self, **options):
        suite = unittest.TestLoader().loadTestsFromTestCase(TestChronology)
        unittest.TextTestRunner().run(suite)


class TestChronology(unittest.TestCase):
    def setUp(self):
        print "Write your pre-test prerequisites here"

    def test_equality(self):
        """
        Tests that 1 + 1 always equals 2.
        """
        from core.models import Yourmodel
        self.failUnlessEqual(1 + 1, 2)
person James    schedule 30.10.2009
comment
ขอบคุณ! คำตอบนี้เป็นของด้านบน :) - person Danilo Bargen; 29.04.2011
comment
+1 สำหรับการตอบคำถามและการแสดงวิธีการทำโดยการสร้างคำสั่งการจัดการใหม่ - person MrOodles; 21.08.2012
comment
NoArgsCommand เลิกใช้แล้วและจะถูกลบออกใน Django 1.10 - ตอนนี้แนวทางปฏิบัติที่ดีที่สุดคือการใช้ BaseCommand ซึ่งค่าเริ่มต้นคือไม่มี args สิ่งที่คุณต้องเปลี่ยนจากคำตอบข้างต้นคือ: from django.core.management.base import BaseCommand ... class Command(BaseCommand) ... def handle(self, **options) - person Chris; 28.12.2015

TEST_RUNNER นี้ใช้ได้กับ Django 1.3

from django.test.simple import DjangoTestSuiteRunner as TestRunner

class DjangoTestSuiteRunner(TestRunner):
    def setup_databases(self, **kwargs):
        pass

    def teardown_databases(self, old_config, **kwargs):
        pass
person Noel Pure    schedule 06.06.2014
comment
สำหรับ Django 1.8 ให้ซับคลาส DiscoverRunner คลาส (from django.test.runner import DiscoverRunner) - person dhobbs; 18.11.2015

Unittest มีวัตถุประสงค์เพื่อทดสอบโดยไม่มีผลข้างเคียงใดๆ แม้ว่าการทดสอบของคุณจะไม่มีอะไรที่เรียกว่า unittest หากคุณต้องการดำเนินการต่อไป คุณสามารถใช้ตัวทดสอบแบบกำหนดเองที่กำลังตั้งค่าฐานข้อมูล (หรือในกรณีของคุณโดยใช้ db ที่มีอยู่)

คุณสามารถตั้งค่า TEST_RUNNER ได้ในไฟล์ settings.py ของคุณ ค่าเริ่มต้นคือค้นหาใน django.test.simple.run_tests คุณสามารถดูแหล่งที่มาได้ที่นี่: http://code.djangoproject.com/browser/django/trunk/django/test/simple.py

คัดลอกและวางโค้ดในไฟล์ใหม่ และลบบรรทัดต่อไปนี้ออกจากโค้ด:

connection.creation.create_test_db(verbosity, autoclobber=not interactive)
...
connection.creation.destroy_test_db(old_name, verbosity)

วิธีนี้จะป้องกันไม่ให้ django สร้างฐานข้อมูลทดสอบและรีเซ็ตการกำหนดค่าฐานข้อมูลของไฟล์การตั้งค่าของคุณ

person Gregor Müllegger    schedule 30.10.2009
comment
ดูเหมือนว่าจะใช้งานไม่ได้: การทดสอบ Djanfo ไม่พบฐานข้อมูลการผลิต :-( - person luc; 20.11.2009

ไม่ใช่ความคิดที่ดี แต่ถ้าคุณรู้ว่าคุณกำลังทำอะไรอยู่ (โดยทั่วไปคือการทำลายการผลิตของคุณ) คุณสามารถตรวจสอบการตั้งค่านี้ได้:

https://docs.djangoproject.com/en/2.2/ref/settings/#test

DATABASES = {
  'default': {
     ...
     'TEST': {
        'NAME': 'your prod db'
     }
}
person Michel Samia    schedule 13.08.2019