Django: هل هناك طريقة لحساب استعلامات SQL من اختبار الوحدة؟

StackOverflow https://stackoverflow.com/questions/1254170

سؤال

أحاول معرفة عدد الاستعلامات التي تنفذها وظيفة فائدة. لقد كتبت اختبار وحدة لهذه الوظيفة، تعمل الوظيفة بشكل جيد. ما أود القيام به هو تتبع عدد استعلامات SQL التي تنفذها الوظيفة حتى أتمكن من معرفة ما إذا كان هناك أي تحسن بعد إعادة الإنفاق.

def do_something_in_the_database():
    # Does something in the database
    # return result

class DoSomethingTests(django.test.TestCase):
    def test_function_returns_correct_values(self):
        self.assertEqual(n, <number of SQL queries executed>)

تحرير: اكتشفت أن هناك django معلقة طلب المواصفات لهذا. ومع ذلك لا تزال تذكرة مفتوحة. في هذه الأثناء هل هناك طريقة أخرى للذهاب حول هذا الموضوع؟

هل كانت مفيدة؟

المحلول

منذ django 1.3 هناك assertnumqueries. متاح بالضبط لهذا الغرض.

نصائح أخرى

استجابة Vinay صحيحة، مع إضافة طفيفة واحدة.

يقوم إطار اختبار وحدة DJANGO في الواقع بتعيين تصحيح الأخطاء إلى FALSE عند تشغيله، لذلك بغض النظر عما لديك settings.py, ، لن يكون لديك أي شيء يسكن في connection.queries في اختبار الوحدة الخاصة بك ما لم تقم بإعادة تمكين وضع التصحيح. تفسر مستندات django الأساس المنطقي لهذا كما:

بغض النظر عن قيمة إعداد التصحيح في ملف التكوين الخاص بك، تعمل جميع اختبارات DJango مع Debug = False. هذا هو التأكد من أن الإخراج الملحوظ من التعليمات البرمجية يطابق ما الذي سينظر إليه في إعداد الإنتاج.

إذا كنت متأكدا من أن تصحيح تمكين لن يؤثر على اختباراتك (مثل اختبار الزيارات DB على وجه التحديد، لأنك يبدو مثلك)، فإن الحل هو إعادة تمكين مؤقتا في اختبار الوحدة الخاص بك، ثم قم بتعيينه العودة بعد ذلك:

def test_myself(self):
    from django.conf import settings
    from django.db import connection

    settings.DEBUG = True
    connection.queries = []

    # Test code as normal
    self.assert_(connection.queries)

    settings.DEBUG = False

إذا كنت تستخدم pytest, pytest-django لديها django_assert_num_num_queries. تركيبات لهذا الغرض:

def test_queries(django_assert_num_queries):
    with django_assert_num_queries(3):
        Item.objects.create('foo')
        Item.objects.create('bar')
        Item.objects.create('baz')

اذا كنت تمتلك DEBUG تعيين إلى True في الخاص بك settings.py (يفترض ذلك في بيئة الاختبار الخاصة بك) ثم يمكنك حساب الاستعلامات المنفذة في الاختبار الخاص بك كما يلي:

from django.db import connection

class DoSomethingTests(django.test.TestCase):
    def test_something_or_other(self):
        num_queries_old = len(connection.queries)
        do_something_in_the_database()
        num_queries_new = len(connection.queries)
        self.assertEqual(n, num_queries_new - num_queries_old)

في django الحديثة (> = 1.8) موثقة جيدا (يتم توثيقها أيضا لمدة 1.7) هنا, ، لديك الطريقة إعادة تعيين بدلا من تعيين اتصال = [ مما يزيد بالفعل خطأ، شيء من هذا القبيل يعمل على Django> = 1.8:

class QueriesTests(django.test.TestCase):
    def test_queries(self):
        from django.conf import settings
        from django.db import connection, reset_queries

        try:
            settings.DEBUG = True
            # [... your ORM code ...]
            self.assertEquals(len(connection.queries), num_of_expected_queries)
        finally:
            settings.DEBUG = False
            reset_queries()

قد تفكر أيضا في إعادة تعيين الاستعلامات على الإعداد / الدموع لضمان إعادة تعيين الاستعلامات لكل اختبار بدلا من القيام بذلك في جملة أخيرا، ولكن بهذه الطريقة أكثر صراحة (على الرغم من أن المزيد من السفلات)، أو يمكنك استخدامها إعادة تعيين في جملة المحيط عدة مرات كما تحتاج إلى تقييم الاستفسارات عد من 0.

إذا كنت لا تريد استخدام اختبار (مع assertnumqueries.) أو تغيير الإعدادات لتصحيح = صحيح، يمكنك استخدام capturequeries manager capturequentext (نفسه assertnumqueries. استخدام).

from django.db import ConnectionHandler
from django.test.utils import CaptureQueriesContext

DB_NAME = "default"  # name of db configured in settings you want to use - "default" is standard
connection = ConnectionHandler()[DB_NAME]
with CaptureQueriesContext(connection) as context:
    ... # do your thing
num_queries = context.initial_queries - context.final_queries
assert num_queries == expected_num_queries

إعدادات DB.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top