2013-04-13 23 views
8

Tôi đang cố gắng triển khai kịch bản nhiều-nhiều bằng cách sử dụng ORM pyewee python và tôi muốn một số kiểm tra đơn vị. Hướng dẫn Peewee là tuyệt vời nhưng nó giả định rằng cơ sở dữ liệu được định nghĩa ở cấp mô-đun sau đó tất cả các mô hình đang sử dụng nó. Tình hình của tôi khác: Tôi không có một tập tin mã nguồn (một mô-đun từ quan điểm của python) với các bài kiểm tra mà tôi chạy một cách rõ ràng, tôi đang sử dụng mũi thu thập các bài kiểm tra từ tập tin đó và chạy chúng.Cơ sở dữ liệu sqlite tùy chỉnh để kiểm tra đơn vị mã bằng cách sử dụng ORM

Làm cách nào để sử dụng cơ sở dữ liệu tùy chỉnh chỉ cho các mô hình được khởi tạo trong các thử nghiệm (đang được chạy bằng mũi)? Mục tiêu của tôi là sử dụng cơ sở dữ liệu trong bộ nhớ chỉ để kiểm tra, để tăng tốc quá trình thử nghiệm.

+0

Tôi cũng tò mò về điều này. [PyORMish] (http://pyormish.nullism.com) có thể xử lý điều này bằng cách thiết lập giá trị 'db_config' trên Model trước khi chạy thử nghiệm, và sau đó thiết lập nó trở lại trong phương thức teardown. Tôi hy vọng điều này sẽ làm việc với Peewee. –

Trả lời

11

Tôi vừa mới thực hiện một cam kết ngày hôm nay giúp việc này trở nên dễ dàng hơn.

Việc sửa chữa là dưới hình thức một người quản lý bối cảnh cho phép bạn ghi đè lên cơ sở dữ liệu của một mô hình:

from unittest import TestCase 
from playhouse.test_utils import test_database 
from peewee import * 

from my_app.models import User, Tweet 

test_db = SqliteDatabase(':memory:') 

class TestUsersTweets(TestCase): 
    def create_test_data(self): 
     # ... create a bunch of users and tweets 
     for i in range(10): 
      User.create(username='user-%d' % i) 

    def test_timeline(self): 
     with test_database(test_db, (User, Tweet)): 
      # This data will be created in `test_db` 
      self.create_test_data() 

      # Perform assertions on test data inside ctx manager. 
      self.assertEqual(Tweet.timeline('user-0') [...]) 

     # once we exit the context manager, we're back to using the normal database 

Xem documentation và có một cái nhìn vào ví dụ testcases:

+0

Một thử nghiệm tầm thường hoạt động tốt với peewee-2.1.1, cảm ơn bạn. – AnonymousLurker

+1

Đây có phải là cách để thực hiện khi thử nghiệm không? –

6

Để không bao gồm trình quản lý ngữ cảnh trong mọi trường hợp kiểm tra, hãy ghi đè phương thức run.

# imports and db declaration 

class TestUsersTweets(TestCase): 
    def run(self, result=None): 
     with test_database(test_db, (User, Tweet)): 
      super(TestUsersTweets, self).run(result) 

    def test_timeline(self): 
     self.create_test_data() 
     self.assertEqual(Tweet.timeline('user-0') [...]) 
5

tôi lấy câu trả lời lớn từ @coleifer và @avalanchy và đưa họ thêm một bước nữa.

Để tránh trọng phương pháp chạy trên tất cả các TestCase lớp con, bạn có thể sử dụng một lớp cơ sở ... và tôi cũng thích ý tưởng không cần phải viết xuống mỗi lớp mô hình tôi làm việc với, vì vậy tôi đã lên với điều này

import unittest 
import inspect 
import sys 
import peewee 
from abc import ABCMeta 
from playhouse.test_utils import test_database 
from business_logic.models import * 

test_db = peewee.SqliteDatabase(':memory:') 


class TestCaseWithPeewee(unittest.TestCase): 
    """ 
    This abstract class is used to "inject" the test database so that the tests don't use the real sqlite db 
    """ 

    __metaclass__ = ABCMeta 

    def run(self, result=None): 
     model_classes = [m[1] for m in inspect.getmembers(sys.modules['business_logic.models'], inspect.isclass) if 
         issubclass(m[1], peewee.Model) and m[1] != peewee.Model] 
     with test_database(test_db, model_classes): 
      super(TestCaseWithPeewee, self).run(result) 

như vậy, bây giờ tôi chỉ có thể kế thừa từ TestCaseWithPeewee và không phải lo lắng về bất cứ điều gì khác ngoài sự kiểm tra

0

Khi sử dụng test_database tôi gặp phải vấn đề với test_db không được khởi tạo:

nose.proxy.Exception: Error, database not properly initialized before opening connection -------------------- >> begin captured logging << -------------------- peewee: DEBUG: ('SELECT "t1"."id", "t1"."name", "t1"."count" FROM "counter" AS t1', []) --------------------- >> end captured logging << ---------------------

tôi cuối cùng cố định này bằng cách thông qua create_tables=True như vậy:

def test_timeline(self): with test_database(test_db, (User, Tweet), create_tables=True): # This data will be created in `test_db` self.create_test_data()

Theo the docscreate_tables nên mặc định True nhưng có vẻ như đó không phải là trường hợp trong bản phát hành mới nhất của peewee.

+0

Đã tạo vấn đề github https: // github.com/coleifer/peewee/issues/741 – coleifer

+0

Traceback chỉ ra rằng cơ sở dữ liệu thử nghiệm ở trạng thái "trì hoãn". Cơ sở dữ liệu thử nghiệm cần được khởi tạo với tên cơ sở dữ liệu. – coleifer

Các vấn đề liên quan