2014-10-04 9 views
1

The Flask Mega-Tutorial을 모방하여 웹 응용 프로그램을 쓰고 있습니다.Flask-SQLALchemy 단위 테스트 문제

내가 단위 테스트 케이스를 코드에 추가하려고했기 때문에. 튜토리얼의 테스트 케이스에 많은 중복 코드가 있다는 것을 알게되었습니다. 여기

는 코드 세그먼트이다 : 그래서

u = User(nickname='john', email='[email protected]') 
db.session.add(u) 
db.session.commit() 

, 나는이 과정을 이동 :

문제는 내가 새로운 케이스를 테스트 할 때마다 나는이 과정을 반복해야한다는 것입니다

def test_avatar(self): 
    u = User(nickname='john', email='[email protected]') 
    avatar = u.avatar(128) 
    expected = 'http://www.gravatar.com/avatar/d4c74594d841139328695756648b6bd6' 
    ... 

def test_make_unique_nickname(self): 
    u = User(nickname='john', email='[email protected]') 
    db.session.add(u) 
    db.session.commit() 
    ... 

다음과 같이 만들었습니다.

import unittest 

from config import basedir 
from app import app, db 
from app.models import User 

u = User(nickname='john', email='[email protected]') # I put this out because some cases may want to use this stuff. 

def _init_database(): 
    db.session.add(u) 
    db.session.commit(u) 

class TestCase(unittest.TestCase): 
    def setUp(self): 
     app.config['TESTING'] = True 
     app.config['WTF_CSRF_ENABLED'] = False 
     app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///:memory:') 
     self.app = app.test_client() 
     db.create_all() 
     _init_database() # init database every time 

    def tearDown(self): 
     db.session.remove() 
     db.drop_all() 

    def test_case_1(self): 
     self.assertTrue(User.query.count() == 1) # case 1 

    def test_case_2(self): 
     self.assertTrue(User.query.count() == 1) # case 1 

if __name__ == '__main__': 
    unittest.main() 

두 가지 테스트 케이스가 같습니다. 그러나 한 케이스 만 통과 할 수 있습니다. 다른 하나는 실패합니다.

하지만 u = User(nickname='john', email='[email protected]')_init_database()로 이동하는 경우 : 모든 것은 지금은 괜찮

def _init_database(): 
    u = User(nickname='john', email='[email protected]') 
    db.session.add(u) 
    db.session.commit(u) 

.

나는 정말로 이유를 모른다. 당신이 나를 도울 수?

답변

0

User 인스턴스는 ORM에 의해 제어되는 개체이므로 전역 변수로 설정하는 것은 좋지 않습니다. 이 개체는 데이터를 포함 할뿐만 아니라 데이터베이스 정보도 포함합니다. 글로벌하게 만들면 첫 번째 테스트에서는 데이터베이스에서 사용하고, 두 번째 테스트에서는 데이터베이스에서 사용합니다.

def _init_database(): 
    u = User(nickname='john', email='[email protected]') 
    db.session.add(u) 
    db.session.commit() 
    return u 

그런 다음 당신이 당신의 테스트 케이스와 테스트에서 액세스를이 사용자를 첨부 할 수 있습니다

더 좋은 방법은 각 시험에 대한 새로운 User 인스턴스를 생성하고 setUp() 방법을 반환하는 것입니다.

+0

전역 변수를 사용하면 안됩니다. 그러나 둘 이상의 사용자를 사용하려면 어떻게해야합니까? 그렇다면, 나는이'return (u1, u2, u3)'처럼 돌아와야 만합니까? 나는 그것을 해결할 수있는 유일한 방법을 생각할 수 있습니다. 이 모든 사용자 객체 변수를 만드십시오. 그러나, 사용자를 사용하고 싶을 때마다 나는이 'self.u1'과 같이 사용해야합니다. 이것은 약간 추한 것입니다. –

+1

나는 나쁜 글로벌 변수가 얼마나 유감 스럽 냐를 당신에게 설득하려하지 않았다. 전역 변수는 때로는 유용하지만이 경우 SQLAlchemy에서 제어하는 ​​데이터베이스 메타 데이터를 저장하기 때문에 사용자 모델이 다소 마법적이기 때문에 문제가됩니다. '_init_database()'함수를'TestCase' 클래스의 메소드로 만들 것이고 모든 사용자를 객체 변수로 저장할 것입니다. 그런 다음 세 명의 사용자를 반환하고 테스트 시작시'u1, u2, u3 = self._get_users()'로 호출하는'_get_users()'메소드를 작성하면'self를 사용할 필요가 없습니다. u1'. – Miguel