2019独角兽企业重金招聘Python工程师标准>>>
背景
使用django开发了个人博客,欲单元测试,后遍寻网络,然相关资料甚少,遂成此文,望对汝有所助
环境
- pytest
- pytest-django
- pytest-cov
- pytest-html
- django
- mixer
测试配置
项目根目录下新建pytest.ini和conftest.py
pytest.ini
[pytest]
DJANGO_SETTINGS_MODULE = carp.settingspython_files = tests.py test_*.py *_tests.py
addopts = --cov=blog/
carp是我的的项目名称
conftest.py
#使用测试的数据库
@pytest.fixture(scope='session')
def django_db_setup():settings.DATABASES['default'] = {'ENGINE': 'django.db.backends.sqlite3','NAME': os.path.join(BASE_DIR, 'test_db.sqlite3'),}
test_db.sqlite3为我的测试数据,这里的数据库用的是sqlite
脚本编写
model测试脚本
@pytest.mark.django_db
def test_models():# 插入10条模拟的分类记录mixer.cycle(10).blend('blog.Category')# 插入50条模拟的文章记录mixer.cycle(50).blend('blog.Article', is_md='0', presentation='test简介')mixer.blend('blog.BlogSettings')assert Category.objects.all().count() > 0assert Article.objects.all().count() > 0
这里的使用了第三方库mixer,实现了对数据模拟,在使用mixer对数据进行新增的时候,相关联表数据也会插入 @pytest.mark.django_db对数据进行装载和回滚
views测试脚本
@pytest.mark.django_db
def test_details(client):article = Article.objects.all().first()response = client.get('/article/2019/7/12/' + str(article.id) + '.html')assert response.status_code == 200
这里请求使用了client
执行测试
命令行输入
pytest
----------- coverage: platform win32, python 3.6.4-final-0 -----------
Name Stmts Miss Cover
----------------------------------------------------------------
blog\__init__.py 0 0 100%
blog\admin.py 58 14 76%
blog\apps.py 5 0 100%
blog\migrations\0001_initial.py 8 8 0%
blog\migrations\0002_auto_20190313_1308.py 4 4 0%
blog\migrations\0003_article_is_dirlist.py 4 4 0%
blog\migrations\__init__.py 0 0 100%
blog\models.py 150 12 92%
blog\search_indexes.py 8 1 88%
blog\signals.py 16 5 69%
blog\spider_notify.py 38 27 29%
blog\templatetags\__init__.py 0 0 100%
blog\templatetags\blog_tags.py 48 3 94%
blog\tests.py 27 0 100%
blog\urls.py 5 0 100%
blog\views.py 67 19 72%
blog\whoosh_cn_backend.py 506 384 24%
----------------------------------------------------------------
TOTAL 944 481 49%
从上述结果就可以直接看到各个文件的代码测试覆盖率是多少
.coveragerc 配置
从上面结果可以发现有的程序是不需要衡量代码测试覆盖率的,如__init__.py一般都是空的,我们可以使用.coveragerc配置将它排除
[run]
omit =*/__init__.py*/migrations/**/whoosh_cn_backend.py*/spider_notify.py
上述配置排除了项目下的所有 init.py 以及 migrations/ 文件夹底下的所有文件。
接着我们在执行一遍测试
pytest
就会看到配置的文件排除了
----------- coverage: platform win32, python 3.6.4-final-0 -----------
Name Stmts Miss Cover
----------------------------------------------------
blog\admin.py 58 14 76%
blog\apps.py 5 0 100%
blog\models.py 150 12 92%
blog\search_indexes.py 8 1 88%
blog\signals.py 16 5 69%
blog\templatetags\blog_tags.py 48 3 94%
blog\tests.py 27 0 100%
blog\urls.py 5 0 100%
blog\views.py 67 19 72%
----------------------------------------------------
TOTAL 384 54 86%
pytest.ini重新配置
- 为了让测试覆盖率的结果输出为html 格式,增加命令--cov-report html,这样结果就会存在 htmlcov 这个新增的文件夹下面
- 输出代码测试覆盖率的测试报告的同时,生成单元测试报告,这里使用了pytest的插件库pytest-html
重新配置一下pytest.ini
[pytest]
DJANGO_SETTINGS_MODULE = carp.settingspython_files = tests.py test_*.py *_tests.py
addopts = --cov-config=.coveragerc--cov-report html--cov=blog/--html=report.html
接着我们在执行一遍测试
pytest
打开htmlcov目录下的index.html
打开根目录下的report.html
以上就是本篇 pytest对django项目进行单元测试的内容
参考
pytest测试框架入门教程
pytest-cov’s documentation
pytest-django Documentation