django单元测试
django 单元测试小结
django 测试
从前很少写单元测试了,特别是web应用。最近不知不觉喜欢起来这个事情了,发现单元测试对于软件的模块,正交性有很大促进作用,因为函数,模块写的不合理,单元测试写起来就麻烦的多呀。公司的项目一直都是用Django,所以写点django单元测试的小总结,记录为主,备查。
测试的场景
框架Django1.8 测试工具 unittest, 要记得给test设置一个独特的settings。
测试请求 也就是测试整个view部分 官方案例 其中可能会遇到登录,或者时session怎么模拟的问题
测试带有orm的模块
- 需要mock的测试,比较多的情况是有第三方API调用, 发邮件,发短信这种
unittest提供的断言种类挺多,但是经常用的也就几个 self.assertContains, self.assertEqual, self.assertTrue
顺便提下有用的选项(我这里是单独给测试写了一个settings), 为了提高测试速度,可以把用不到的中间件,installed_apps之类的多余配置给去掉。
测试全部用例python manage.py test --setting settings_test测试某个APPpython manage.py test appname --setting settings_test测试某个app下的TeseCase类python manage.py test alarm.tests.ModelTestCase--setting settings_test-v {1,2,3}数字越大,显示的输出越详细,测试的日志信息python manage.py test --setting settings_test -v3其他的选项请查看--helppython manage.py test --help
用请求测试 views函数
DJANGO中提供了Client类来模拟http请求,可以模拟不同的method,然后就是请求参数的模拟,用起来很方面。
#coding:utf-8from django.test importTestCase,Clientfrom sendviews import*from core.tests import create_userclassSendviewsTestCase(TestCase):def setUp(self):self.user = create_user()self.device =Device(hostname="CN-BJ-0000-00",mac="ff:ff:ff:ff:ff:ff", user=self.user).save()def test_creat_sms(self):c =Client()rep = c.post("/acquireportal/createsms",{"phone":"13988902345","ssid":"erya","dmac":"ff:ff:ff:ff:ff:ff"})# 测试http请求的返回码是否正确self.assertEqual(rep.status_code,200)# 测试response的内容是否包含字符串self.assertContains(rep,"OK")# 测试response的内容是否包含字符串 方法二self.assertTrue('OK'in rep.content)
- 操作 session,例如用户登录,特殊的session值
from django.test importClientdef init_client(user):client =Client()client.login(username=user.username, password="lzz")s = client.sessions['cur_user_id']= user.ids.save()return client
- 增加header
from django.test.utils import setup_test_environmentsetup_test_environment()from django.test.client importClientc =Client()# get 请求,带参数,并增加headerc.get('/some/path/',{'qs_param':'foo'},**{'HTTP_USER_AGENT':'silly-human','REMOTE_ADDR':'127.0.0.1'})#get 请求,没有带参数,自定义headersc.get('/some/path/',**{'HTTP_USER_AGENT':'silly-human','REMOTE_ADDR':'127.0.0.1'})
- 使用 RequestFactory 对象来进行测试,不是从 http client来发起,某些情况会用到
from django.test importTestCase,RequestFactoryfrom django.http importHttpResponsefrom util.sign import generate_sign, validate_signfrom util.decorators import apiauth_required, SIGN_KEY@apiauth_required()def simpleapi(request):returnHttpResponse('ok')classDecoratorsTestCase(TestCase):def setUp(self):self.factory =RequestFactory()def test_apiauth(self):# create request objectkey = SIGN_KEYquery_string ={u"name": u"lzz", u"age": u"20", u"data": u"[python, java, golang, lua]"}token = generate_sign(query_string, key)query_string.update({u"sign": token})req =self.factory.post("/api/test", data=query_string)response = simpleapi(req)self.assertEqual(response.status_code,200)
- HTML 文本测试,使用 constants 来判断并不是个好的选择,可以用render之后的字符串对比。
对于需要登陆的view,有client也比较容易操作,还有一些特殊的session的检测等, 我这里做了一个简单的封装
from django.test importClientdef init_client(user):client =Client()client.login(username=user.username, password="lzz")s = client.sessions['cur_user_id']= user.ids.save()return client
带有mock的测试
对模块中的方法mock或者是对一个对象中的方法进行mock。真对测试函数中一些无法直接测试的函数设置默认的返回值, py3标准库中已经有了mock模块,py2需要自己安装, 推荐教程 使用Pyhton Mock进行单元测试1。 下面是个实际的代码片段。
import mockfrom django.test importTestCasefrom core.models importTenantfrom alarm.models import*from.controler importTenantAlarmclassModelTestCase(TestCase):def setUp(self):self.tenant =Tenant.objects.create(domainname="erya", comname=u"尔雅")@mock.patch.object(TenantAlarm,"sendAlarm")def test_record_alarm(self, mock_method):# record_alarm 这个中会调用sendAlarm方法mock_method.return_value =Nonecontent ="ccccc"atype =0rec_uid =0Alarm().record_alarm(content=content, atype=0,rec_tid=self.tenant.id)classTenantAlarmTestCase(TestCase):def setUp(self):self.tenant =Tenant.objects.create(domainname="erya", comname=u"尔雅")@mock.patch.object(TenantAlarm,"sendSMS", return_value=None)@mock.patch.object(TenantAlarm,"sendEmail", return_value=None)def test_send_alarm(self, method1, method2):content = u"报警了"ta =TenantAlarm(self.tenant.id, content,{u'SMS':0, u'EMAIL':0})ta.sendAlarm()@mock.patch('util.sendsms_com.send', return_value=1)def test_sendsms(self, send):ta =TenantAlarm(self.tenant.id,self.content,{u'SMS':0, u'EMAIL':0})ta.sendSMS()self.assertEqual(0,Account.objects.get(tenant=self.tenant).sms_num)self.account.sms_num =100self.account.save()ta.sendSMS()self.assertEqual(99,Account.objects.get(tenant=self.tenant).sms_num)
coverage
coverage是一个检查单元测试覆盖率的工具,django的文档中也有简要的说明coverage的集成 文档地址
#测试并收集测试信息coverage run --source='.' manage.py test --setting mandela.settings_test#查看测试结果coverage report -mNameStmtsMissCoverMissing----------------------------------------------------------------------------------------acquireportal/__init__.py 00100%acquireportal/controler.py 654728%22-56,60-71,76-79acquireportal/migrations/0001_initial.py 60100%acquireportal/migrations/0002_auto_20160622_1059.py 60100%acquireportal/migrations/0003_auto_20160622_1100.py 50100%....----------------------------------------------------------------------------------------TOTAL 8013585827%
覆盖率挺低的
django单元测试的更多相关文章
- [Django] 单元测试小记
从前很少写单元测试了,特别是web应用.最近不知不觉喜欢起来这个事情了,发现单元测试对于软件的模块,正交性有很大促进作用,因为函数,模块写的不合理,单元测试写起来就麻烦的多呀.公司的项目一直都是用Dj ...
- 如何进行Django单元测试
如何进行Django单元测试 Django的单元测试使用python的unittest模块,这个模块使用基于类的方法来定义测试.类名为django.test.TestCase,继承于python的un ...
- Django 单元测试
mock 测试 mock 是辅助单元测试的模块,用于测试不方便调用的别人的接口.举个简单的例子,比如说,我们测试django 写的微信登录接口,正常流程下,我们需要前端拉起授权窗口,获取jscode或 ...
- Django单元测试 相关知识
前言 本文,旨在说明python Django如何编写单元测试,从“背景”,“测试要求”,“代码编写”,“如何运行”,“检验测试覆盖度” 这几个方面来说明附上django的官方文档单元测试章节=> ...
- Django 单元测试笔记
引言 关于单元测试的基本知识这里不再讲述,简单一句话:单元测试是用一段代码去测试另一段代码.最常用的框架是unittest,这是python的单元测试框架,而django单元测试框架test.Test ...
- Django单元测试(一)
Django测试框架非常简单,首选方法是使用python标准库中的unittest模块. Writing tests Django的单元测试使用python的unittest模块,这个模块使用基于类的 ...
- django 单元测试错误总结
TestCase django自带有一个TestCase模块来进行测试,我们可以参考官网 来写单元测试的代码.我这里主要是总结一些错误. 用户无法登陆 我们有些api登录后才可以进行测试,所以我们可以 ...
- django 单元测试小结
测试的场景 框架Django1.8 测试工具 unittest, 要记得给test设置一个独特的settings. 测试请求 也就是测试整个view部分 官方案例 其中可能会遇到登录,或者时sessi ...
- Django单元测试中Fixtures用法
在使用单元测试时,有时候需要测试数据库中有数据,这时我们可以使用Django的Fixtures来生成测试数据. 基础配置 在settings.py 中配置如下内容: FIXTURE_DIRS = (' ...
随机推荐
- Javascirpt中创建对象的几种方式
js是一种动态语言,即js的对象创建好之后可以随意修改,因此JS对象的面向对象编程部分更可以说是通过JS的怪异特性来模拟Java这类的面向对象编程的.下面首先讨论几种创建对象的方式: 1. 工厂模式创 ...
- 【整理】C#文件操作大全(SamWang)<转>
文件与文件夹操作主要用到以下几个类: 1.File类: 提供用于创建.复制.删除.移动和打开文件的静态方法,并协助创建 FileStream 对象. msdn:http://msdn.microsof ...
- STL set使用例子
#include<iostream>#include<set>using namespace std; #include<stdlib.h> #define ran ...
- 如何使用THashedStringList
1.添加 uses system.IniFiles 2.实例代码: unit Unit1; interface uses Winapi.Windows, Winapi.Messages, System ...
- Markdown写博客
一级目录 我接下来是不是该写二级目录了 二级目录 如果我用桌面端的Markdown会不会好很多,这个我看不到效果 听说插入表格很麻烦? 列表是这样的? 我还看不出样子 *这个是什么样子啊 引用是这样用 ...
- docker help
localhost == 127.0.0.1 == 本机ip ifconfig 或者 ip addr 查看本地宿主机的ip地址 $ docker help Usage: docker [OPTIONS ...
- FusionCharts中仪表盘相关属性
上上周用FusionCharts做了几个报表,里面有个仪表盘,当时查属性查疯了,现在把相关的一些属性记下来,方便以后查找. -------------------------仪表盘重要属性解析---- ...
- Python自动化 【第十六篇】:JavaScript作用域和Dom收尾
本节内容: javascript作用域 DOM收尾 JavaScript作用域 JavaScript的作用域一直以来是前端开发中比较难以理解的知识点,对于JavaScript的作用域主要记住几句话,走 ...
- disconf系列【1】——百度disconf在ubuntu14.04环境下的安装
disconf官网给出的安装文档默认读者已经非常熟练本文1.2章节给出的依赖软件的原理及使用方法,且官网默认安装环境为linux(windows安装方法只字未提).同时,官网对很多重要的细节语焉不详, ...
- Spring-Batch CSV文件读取时的注意点
按照Spring Batch 之 Sample(CSV文件操作)(四) 的方式配置好csvItemReader, 发现读入的数据很是奇怪,通过修改配置文件发现, commit-interval=&qu ...