记一次flask单元测试的编写

记录一些自己写单元测试时的点

关键代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
from datetime import datetime, timedelta
import pytest
from app import create_app, db
from app.models import User, Post
from config import Config

# 继承自生产Config, 用测试参数覆盖掉其中一部分参数
class TestConfig(Config):
TESTING = True
# IMPORTANT! 一定要用新的测试库,不要用生产库
SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://'

class TestUserModel():
def set_up(self):
self.app = create_app(TestConfig)
self.app_context = self.app.app_context()
self.app_context.push()
db.create_all()

def tear_down(self):
db.session.remove()
db.drop_all()
self.app_context.pop()

@pytest.fixture(scope='function')
def env(self):
# yield 以及yield之前会执行set_up
yield self.set_up()
# yield 这里会中断,跳回到调用方执行,待调用方执行完后,则回到yield所在的函数继续执行。
# 所以yield之后执行的相当于teardown.
self.tear_down()

def test_password_hashing(self, env): # 注意这里要传入fixtures
u = User(username='xiaoming')
u.set_password('xiao')

assert u.check_password('xiao')
assert not u.check_password('da')

收获的教训

  • 在新建的测试库上进行测试,不要用生产库

    因为测试时一般会按照你的Models新建库中所有的表,然后测试完后drop所有的表。

    真的误删了生产库的表可以在flask shell 里调用sqlalchemy 对象的create_all()方法新建所有的表。当然,数据还是没了…想要恢复数据的话,建议平时开着binlog。

    1
    2
    3
    4
    $ flask shell

    >>> from app import db
    >>> db.create_all()
  • 每个测试方法记得传入fixtures