2012-03-18 26 views
5

Có vấn đề lạ với Python không liên quan và PyMongo. Thử nghiệm thành công một cách ngẫu nhiên hay thất bại:Thử nghiệm không mong muốn của Python MongoDB ngẫu nhiên bị lỗi

import unittest 
from pymongo import Connection 

from tractor import Tractor 




class TestTractor(unittest.TestCase): 
    def setUp(self): 
     self.tractor = Tractor(1) 

     self.mongo = Connection() 
     self.db = self.mongo.tractor 

     self.db.classes.remove({'name': {'$regex':'^test_'}}) 

     self.action_class_id = self.db.classes.insert({'name': 'test_action', 
                 'metaclass': 'action'}) 
     self.object_class_id = self.db.classes.insert({'name': 'test_object', 
                 'metaclass': 'object'}) 


    def tearDown(self): 
     self.tractor = None 



    def test_create_class(self): 
     cid1 = self.tractor.create_action_class('test_create_action_class') 
     cid2 = self.tractor.create_object_class('test_create_object_class') 

     self.assertNotEqual(cid1, None) 
     self.assertNotEqual(cid2, None) 

     action_obj = self.db.classes.find_one({'_id': cid1}) 
     object_obj = self.db.classes.find_one({'_id': cid2}) 

     self.assertNotEqual(cid1, cid2) 
     self.assertEqual(action_obj['_id'], cid1) 
     self.assertEqual(object_obj['_id'], cid2) 

     self.assertEqual(action_obj['name'], 'test_create_action_class') 
     self.assertEqual(object_obj['name'], 'test_create_object_class') 

Lớp đang được thử nghiệm:

from pymongo import Connection 
from pymongo.objectid import ObjectId 



class Tractor(object): 
    def __init__(self, uid): 
     self.uid = uid 
     self.mongo = Connection() 
     self.db = self.mongo.tractor 


    # Classes 

    def create_action_class(self, name): 
     return self.db.classes.insert({'name': name, 
             'attributes': [], 
             'metaclass': 'action'}) 

    def create_object_class(self, name): 
     return self.db.classes.insert({'name': name, 
             'attributes': [], 
             'metaclass': 'object'}) 

hành vi ngẫu nhiên:

[email protected]30-lnx ~/projects/traction/tractor $ python -m unittest discover 
......ssEssssssssss 
====================================================================== 
ERROR: test_create_class (tests.test_tractor.TestTractor) 
---------------------------------------------------------------------- 
Traceback (most recent call last): 
    File "/home/silver/projects/traction/tractor/tests/test_tractor.py", line 64, in test_create_class 
    self.assertEqual(action_obj['_id'], cid1) 
TypeError: 'NoneType' object is not subscriptable 

---------------------------------------------------------------------- 
Ran 19 tests in 0.023s 

FAILED (errors=1, skipped=12) 

...

[email protected] ~/projects/traction/tractor $ python -m unittest discover 
......ss.ssssssssss 
---------------------------------------------------------------------- 
Ran 19 tests in 0.015s 

OK (skipped=12) 

Hai kết quả xảy ra một cách ngẫu nhiên cho cùng một thử nghiệm khi tôi chạy lại t est mà không thay đổi bất cứ thứ gì trong lớp hoặc trong bài kiểm tra.

Tất cả điều này chạy trên máy của tôi và tôi biết chắc chắn rằng trong khi chạy thử nghiệm, không ai khác tinker không với MongoDB cũng không phải với mã.

Điều gì mang lại?

+0

Có thể bạn có điều kiện chủng tộc. Nếu bạn nhận được 'Không có gì' để tra cứu của bạn, sẽ là khôn ngoan để ném thử nghiệm đơn vị này vào trình gỡ rối và tìm ra chính xác điều gì đã khiến nó bị tấn công. – MrGomez

+0

@MrGomez, bạn nghĩ insert() trả về trước khi mục được chèn vào thực tế và tìm kiếm nhanh() không tìm thấy nó vào thời điểm đó? Nhưng sau đó chèn() sẽ không trở lại, không? – sssilver

+0

Đó là ít nhất là lý thuyết của tôi. Tốt nhất của may mắn trong gỡ lỗi của bạn. – MrGomez

Trả lời

4

Tôi thật sự nghi ngờ vấn đề ở đây là bạn không sử dụng chế độ "an toàn" cho bài viết của mình.

Theo mặc định, MongoDB sử dụng chế độ "lửa và quên". Điều này có nghĩa rằng lệnh chèn được gửi đến máy chủ, nhưng trình điều khiển không kiểm tra bất kỳ phản hồi của máy chủ nào.

Khi bạn chuyển sang chế độ "an toàn", trình điều khiển sẽ gửi lệnh chèn và sau đó nó sẽ gửi lệnh thứ hai getLastError. Lệnh thứ hai này sẽ trở lại khi máy chủ thực sự đã cam kết ghi.

Một lần nữa, theo mặc định bạn đang chạy ở chế độ "lửa và quên", do đó, thực sự có một điều kiện chạy tiềm năng tại đây. Đối với các bài kiểm tra đơn vị, bạn sẽ cần phải chạy với chế độ "an toàn".

Chữ ký chức năng cho chèn được xác định here. Tuy nhiên, bạn cũng có thể thực hiện thay đổi ở mức Kết nối để mỗi kết nối với DB sử dụng chế độ "an toàn" theo mặc định.

+0

Hoàn toàn !! Điều đó cố định mọi thứ và giải quyết mọi vấn đề. Điều này đã cho tôi một lần gỡ lỗi khó khăn như vậy. – sssilver

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