2013-09-29 18 views
12

bu kadar sık ​​birim testleri ise sqlalchemy içinde STDOUT izleme etkinleştirildiğinde Django yılında

from django import db 
from django.conf import settings 
settings.DEBUG=True 

class SendData(TestCase): 
    def test_send(self): 
     db.connection.queries = [] 
     event = Events.objects.all()[1:] 
     s = str(event) # QuerySet is lazy, force retrieval 
     self.assertEquals(len(db.connection.queries), 2) 

yeni N + 1 sorgu sorunları

yakalamak böylece yapılmalıdır sorgu sayısını iddia testleri motoru

engine.echo=True 

sqlalchemy tarafından yapılan sorgu sayısını saymak testleri yazmak için en iyi yolu nedir üzerine echo bayrağı ayarlayarak? idam/iz sorguları günlüğe

class SendData(TestCase): 
    def test_send(self): 
     event = session.query(Events).first() 
     s = str(event) 
     self.assertEquals(... , 2) 

cevap

6

Kullanım SQLAlchemy Core Events (bunlar gerçek uygulamaya performansınızı etkilemez böylece birim testlerinden de takabilirsiniz:

event.listen(engine, "before_cursor_execute", catch_queries) 

Şimdi işlev yazmak . yönlü test bağlıdır catch_queries Örneğin, test açıklamada bu işlevi tanımlayabilirsiniz:

def test_something(self): 
    stmts = [] 
    def catch_queries(conn, cursor, statement, ...): 
     stmts.append(statement) 
    # Now attach it as a listener and work with the collected events after running your test 

abov e yöntem sadece bir ilham kaynağıdır. Genişletilmiş durumlarda, muhtemelen her testten sonra boşaltacağınız global bir önbellek olmasını istersiniz. Bunun nedeni, 0.9'dan önce (mevcut dev) olay dinleyicilerini kaldırmak için bir API olmamasıdır. Böylece küresel bir listeye erişen bir küresel dinleyici yapın.

Ben bu amaçla bir bağlam yöneticisi sınıfı oluşturduk
5

:

class DBStatementCounter(object): 
    """ 
    Use as a context manager to count the number of execute()'s performed 
    against the given sqlalchemy connection. 

    Usage: 
     with DBStatementCounter(conn) as ctr: 
      conn.execute("SELECT 1") 
      conn.execute("SELECT 1") 
     assert ctr.get_count() == 2 
    """ 
    def __init__(self, conn): 
     self.conn = conn 
     self.count = 0 
     # Will have to rely on this since sqlalchemy 0.8 does not support 
     # removing event listeners 
     self.do_count = False 
     sqlalchemy.event.listen(conn, 'after_execute', self.callback) 

    def __enter__(self): 
     self.do_count = True 
     return self 

    def __exit__(self, *_): 
     self.do_count = False 

    def get_count(self): 
     return self.count 

    def callback(self, *_): 
     if self.do_count: 
      self.count += 1