我通过模仿The Flask Mega-Tutorial来撰写网络应用。
因为我试图在我的代码中添加一些单元测试用例。我发现教程中的测试用例有很多重复的代码。
以下是代码段:
def test_avatar(self):
u = User(nickname='john', email='john@example.com')
avatar = u.avatar(128)
expected = 'http://www.gravatar.com/avatar/d4c74594d841139328695756648b6bd6'
...
def test_make_unique_nickname(self):
u = User(nickname='john', email='john@example.com')
db.session.add(u)
db.session.commit()
...
问题在于每次我想测试一个新案例时我都要重复这个过程:
u = User(nickname='john', email='john@example.com')
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='john@example.com') # 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='john@example.com')
移到_init_database()
:
def _init_database():
u = User(nickname='john', email='john@example.com')
db.session.add(u)
db.session.commit(u)
现在一切都很好。
我真的不知道为什么!你能帮帮我吗?
答案 0 :(得分:0)
User
实例是由ORM控制的对象,因此将其作为全局变量不是一个好主意。该对象不仅包含您的数据,还包括数据库信息。通过使其成为全局,您首先在数据库中使用它进行第一次测试,然后在数据库上进行第二次测试。
更好的方法是为每个测试创建一个新的User
实例,并使用setUp()
方法返回它:
def _init_database():
u = User(nickname='john', email='john@example.com')
db.session.add(u)
db.session.commit()
return u
然后,您可以将此用户附加到测试用例并从测试中访问它。