│ .coverage
│ config.py
│ manage.py
│ README.md
│ requirements.txt
│ setup.cfg
│ tree.txt
├─instance
├─migrations
├─mytools
│ │ extensions.py
│ │ logger.py
│ │ models.py
│ │ __init__.py
│ │
│ ├─logs
│ │ assistant.log
├─tests
│ │ conftest.py
│ │ test_db.py
│ │ test_scope.py
│ │
│ ├─data
│ │ setup.sql
│ │ teardown.sql
借助功能齐全的pytest测试框架,编写了一套mysql数据表的测试框架,实现了数据与用例分离,数据批量初始化、销毁,简单易用。
conftest.py
#!/usr/bin/env python
# encoding: utf-8
"""
@author: wanwei
@license: (C) Copyright 2013-2017, Node Supply Chain Manager Corporation Limited.
@contact: [email protected]
@software: pycharm
@file: conftest.py
@time: 2019/9/24 11:02
@desc:
"""
import pytest
import os
import sys
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../')))
from mytools import create_app
from mytools.extensions import db
# 加载数据初始化SQL语句文件
with open(os.path.join(os.path.dirname(__file__), './data/setup.sql'), 'rb') as f:
_setup_sql = f.readlines()
# 销毁数据SQL语句文件
with open(os.path.join(os.path.dirname(__file__), './data/teardown.sql'), 'rb') as f:
_teardown_sql = f.readlines()
@pytest.fixture(scope='session')
def setup(request):
def teardown():
print("用例执行结束..................................")
request.addfinalizer(teardown)
print("用例执行开始..................................")
@pytest.fixture(scope="module")
def setup_database(request):
print("setup tb_user开始执行...............")
# ----------FLASK-SQLALCHEMY数据库配置---------#
USERNAME = 'root'
PASSWORD = '123456'
HOST = '127.0.0.1'
DB = 'mockservertest'
SQLALCHEMY_DATABASE_URI = 'mysql+mysqlconnector://%s:%s@%s/%s' % (USERNAME, PASSWORD, HOST, DB)
# 创建应用实例
app = create_app({
'TESTING': True,
# 数据库文件存放路径
'SQLALCHEMY_DATABASE_URI': SQLALCHEMY_DATABASE_URI,
'SQLALCHEMY_TRACK_MODIFICATIONS': False,
'SQLALCHEMY_ECHO': False
})
def teardown_database():
print("teardown tb_user开始执行...............")
with app.app_context():
#初始化数据库模型
db.create_all()
for sql in _teardown_sql:
if sql:
db.engine.execute(sql.decode('utf-8'))
request.addfinalizer(teardown_database)
with app.app_context():
for sql in _setup_sql:
if sql:
db.engine.execute(sql.decode('utf-8'))
@pytest.fixture(scope='function')
def setup_function(request):
def teardown_function():
print("teardown_function called...")
request.addfinalizer(teardown_function) # 内嵌函数做teardown操作
print("setup_function called...")
@pytest.fixture(scope='module')
def setup_test(request):
def teardown_test():
print("teardown_module called...")
request.addfinalizer(teardown_test)
print("setup_module called...")
从上面的代码来看,fixture具备以下优势:
conftest.py配置需要注意以下点:
│ ├─data
│ │ setup.sql
│ │ teardown.sql
借助conftest.py可轻松实现数据与用例分离
setup.sql
INSERT INTO `tb_user`(password_hash,username,lastseen) VALUES ('pbkdf2:sha256:150000$3mEwvVlo$8f98a0ba2576529e7cd379eaea723bd2195ad1882d480150ff4736a5ed05a260', 'wanwei', '2019-9-18 14:59:43');
INSERT INTO `tb_user`(password_hash,username,lastseen) VALUES ('pbkdf2:sha256:150000$P2sZt9ih$d4ef4d800c4ae7a139fae3a389bbddab6789e7524bd976ab5914945bc52d0f59', 'wanwei2', '2019-9-23 20:08:49');
teardown.sql
DELETE FROM `tb_user` WHERE username='wanwei';
DELETE FROM `tb_user` WHERE username='wanwei2';
测试用例具备以下特点:
#!/usr/bin/env python
# encoding: utf-8
"""
@author: wanwei
@license: (C) Copyright 2013-2017, Node Supply Chain Manager Corporation Limited.
@contact: [email protected]
@software: pycharm
@file: test_db.py
@time: 2019/9/24 13:46
@desc:
"""
from mytools.models import User
from mytools.extensions import db
from mytools import app
def test_password_hash(setup):
"""测试密码加密"""
u = User(username="wanwei3")
u.set_password("Huawei1234")
assert u.check_password("Huawei1234") is True
assert u.check_password("huwe") is False
def test_follow(setup_database):
"""测试关注函数"""
with app.app_context():
user1 = User.query.filter_by(username='wanwei').first()
user2 = User.query.filter_by(username='wanwei2').first()
assert user1.username == 'wanwei','user1 username不正确'
assert user2.username == 'wanwei2','user2 username不正确'
test_scope.py
#!/usr/bin/env python
# encoding: utf-8
"""
@author: wanwei
@license: (C) Copyright 2013-2017, Node Supply Chain Manager Corporation Limited.
@contact: [email protected]
@software: pycharm
@file: pytest1.py
@time: 2019/9/29 15:29
@desc:
"""
import pytest
@pytest.mark.recommend
def test_1(setup_function):
print("test_1 called...")
def test_2(setup_test):
# assert 1 != 1
print("test_2 called...")
def test_3(setup_test):
print("test_3 called...")
[tool:pytest]
filterwarnings =
error
ignore::DeprecationWarning
testpaths = tests
[coverage:run]
branch = True
source = mytools
(mockenv) E:\技术资料\接口框架\datatestdemo>pytest ./tests/test_scope.py::test_2
============================================================================================ test session starts ============================================================================================
platform win32 -- Python 3.5.2, pytest-3.9.2, py-1.7.0, pluggy-0.8.0
rootdir: E:\技术资料\接口框架\datatestdemo, inifile: setup.cfg
plugins: metadata-1.7.0, html-1.19.0, cov-2.7.1, allure-adaptor-1.7.10
collected 1 item
tests\test_scope.py . [100%]
========================================================================================= 1 passed in 0.07 seconds ==========================================================================================
(mockenv) E:\技术资料\接口框架\datatestdemo>
(mockenv) E:\技术资料\接口框架\datatestdemo>
(mockenv) E:\技术资料\接口框架\datatestdemo>coverage run -m pytest
============================================================================================ test session starts ============================================================================================
platform win32 -- Python 3.5.2, pytest-3.9.2, py-1.7.0, pluggy-0.8.0
rootdir: E:\技术资料\接口框架\datatestdemo, inifile: setup.cfg
plugins: metadata-1.7.0, html-1.19.0, cov-2.7.1, allure-adaptor-1.7.10
collected 5 items
tests\test_db.py .. [ 40%]
tests\test_scope.py ... [100%]
========================================================================================= 5 passed in 0.65 seconds ==========================================================================================
(mockenv) E:\技术资料\接口框架\datatestdemo>coverage report
Name Stmts Miss Branch BrPart Cover
---------------------------------------------------------
mytools\__init__.py 19 0 4 0 100%
mytools\extensions.py 7 0 0 0 100%
mytools\logger.py 13 1 2 1 87%
mytools\models.py 29 5 0 0 83%
---------------------------------------------------------
TOTAL 68 6 6 1 91%
生成html报告
coverage html
在htmlcov目录中生成HTML报告,直接打开htmlcov/index.html 即可查看用例覆盖情况:
项目地址:
https://github.com/wanwei890116/Apitest
参考:
pytest文档5-fixture之conftest.py
https://www.cnblogs.com/yoyoketang/p/9390073.html