赞
踩
单元测试是用来对一个模块、一个函数或者一个类来进行正确性检验的测试工作,是测试最小独立的单元模块
如果有需要,可以给项目进行单元测试,主要目的有消灭低级错误、减少和快速定位BUG、提高代码质量
我们在创建好一个APP的时候,它会在自动在APP目录创建一个tests.py文件,这个就是拿来做单元测试的
apps/users/tests.py
from django.test import TestCase class MyTestCase(TestCase): @classmethod def setUpClass(cls): print('setUpClass') @classmethod def tearDownClass(cls): print('tearDownClass') def setUp(self): print("setUp") def tearDown(self): print("tearDown") def test_2_func(self): print("test_2_func") def test_1_func(self): print("test_1_func")
终端命令,有多种执行方法 python3 manage.py test -t . # 执行所有测试 python manage.py test meiduo_mall.apps.users # 执行某个APP的所有test文件 python manage.py test meiduo_mall.apps.users.tests # 执行某个APP的某个tests文件 执行结果 Creating test database for alias 'default'... System check identified no issues (0 silenced). setUpClass setUp test_1_func tearDown .setUp test_2_func tearDown .tearDownClass ---------------------------------------------------------------------- Ran 2 tests in 0.004s OK Destroying test database for alias 'default'...
从执行过程打印的信息我们可以知道
(1).测试类要继承TestCase类
(2).执行前会自动创建一个mysql数据库,执行后自动销毁
(3).setUpClass和tearDownClass这两个静态方法分别会在测试所有用例执行前后各执行一次
(4).setUp和tearDown这两个方法会在每个测试用例前后都各执行一次
(5).setUp和tearDown、def setUpClass和tearDownClass成对出现
(6).用例方法必须以test开头,并非自身往下执行,而是按照方法名字符按照ASCII码排序,顺序是0-9、A-Z、a-z
(7).测试用例执行成功返回一个小数点,失败则返回F
另外,在执行过程可能会遇到django.db.utils.OperationalError: (1366, "Incorrect string value: '\\xE7\\x94\\xA8\\xE6\\x88\\xB7' for column 'name' at row 5") 的问题
这个时候,打开Django的配置文件,在DATABASES配置项里添加一个TEST指定单元测试的字符编码
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql', # 数据库引擎
...
"TEST":{
"CHARSET":"utf8",
"COLLATION":"utf8_general_ci"
},
},
}
根据以上信息,我们可以写一个登录、查询、登出的测试例子
from django.test import TestCase from requests import Session class MyTestCase(TestCase): session = None @classmethod def setUpClass(cls): info = { "username": "13978414080", "password": "123456789", "remembered": True } cls.session = Session() resp = cls.session.post("http://127.0.0.1:8000/login/", json=info) result = resp.json() if result["code"] == 0: print("登录成功") @classmethod def tearDownClass(cls): resp = cls.session.delete('http://127.0.0.1:8000/logout/') result = resp.json() if result["code"] == 0: print("已退出登录") def test_1_info(self): resp = self.session.get("http://127.0.0.1:8000/info/") print(resp.json()) def test_2_history(self): resp = self.session.get('http://127.0.0.1:8000/browse_histories/') print(resp.json()) def test_3_addresses(self): resp = self.session.get("http://127.0.0.1:8000/addresses/") print(resp.json())
我们在上面的模拟测试中使用了requests.Session()来状态保持,其实也可以使用Client类,它还是与Session有些区别的
(1).Client不需要启动服务器就能测试Django项目,也只能在Django中测试
(2).Client的请求url不需要带协议和域名端口,只需要路径部分
(1)get (path,data={},follow=False,**extra)
(2)post (path, data={}, content_type=MULTIPART_CONTENT, follow=False, **extra)
content_type:默认是multipart/form-data,可以指定为application/json
这次我们使用Client实现注册、登录、查询、登出,登出之后再查询一下信息
from django.test import TestCase from django_redis import get_redis_connection from requests import Session class MyTestCase(TestCase): def setUp(self): print("setUp") def tearDown(self): print("tearDown") def test_api(self): self.do_register() self.do_login() self.do_info() self.do_logout() self.do_info() def do_register(self): _uuid = '0fdb75a8-d60e-4598-86bc-c3e7991aadf9' self.client.get("/image_codes/%s/" % _uuid) conn = get_redis_connection('verify_code') ret = conn.get("img_%s" % _uuid) mobile = "13977778888" self.client.get("/sms_codes/%s/?image_code=%s&image_code_id=%s" % (mobile,ret.decode(),_uuid)) user_info = { "username": "13978414088", "password": "123456789", "password2": "123456789", "allow": True, "mobile": mobile, "sms_code": "123456", } resp = self.client.post('/register/', data=user_info, content_type='application/json') print(resp.json()) def do_login(self): user_info = { "username": "13978414088", "password": "123456789", "remembered": True, } resp = self.client.post('/login/', data=user_info, content_type='application/json') print(resp.json()) def do_info(self): resp = self.client.get('/info/') print(resp.json()) def do_logout(self): self.client.delete('/logout/')
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。