什么是单元测试?
程序开发过程中,写代码是为了实现需求。当我们的代码通过了编译,只是说明它的语法正确,功能能否实现则不能保证。 因此,当我们的某些功能代码完成后,为了检验其是否满足程序的需求。可以通过编写测试代码,模拟程序运行的过程,检验功能代码是否符合预期。
单元测试就是开发者编写一小段代码,检验目标代码的功能是否符合预期。通常情况下,单元测试主要面向一些功能单一的模块进行。
在Web开发过程中,单元测试实际上就是一些“断言”(assert)代码。
断言就是判断一个函数或对象的一个方法所产生的结果是否符合你期望的那个结果。 python中assert断言是声明布尔值为真的判定,如果表达式为假会发生异常。单元测试中,一般使用assert来断言结果。
常用的断言方法:
断言 | 作用 |
---|---|
assertEqual | 如果两个值相等,则pass |
assertNotEqual | 如果两个值不相等,则pass |
assertTrue | 判断bool值为True,则pass |
assertFalse | 判断bool值为False,则pass |
assertIsNone | 不存在,则pass |
assertIsNotNone | 存在,则pass |
示例:
import unittest
#flask提供的测试对象,继承使用
class TestClass(unittest.TestCase):
#该方法会首先执行,相当于做测试前的准备工作
#一般初始化数据使用
def setUp(self):
pass
#该方法会在测试代码执行完后执行,相当于做测试后的扫尾工作
def tearDown(self):
pass
#测试代码,最前面一定是test开头,才能找到函数
def test_run(self):
pass
完整的接口测试demo
# coding:utf-8
import unittest
from login import app
import json
class TestLogin(unittest.TestCase):
def setUp(self):
"""在执行具体的测试方法前,先被调用"""
# 可以使用python的http标准客户端进行测试
#常规的测试方法用postman测试接口,或者用http请求第三方库进行接口调用如下:
# urllib urllib2 requests
# 使用flask提供的测试客户端进行测试,flask自带测试客户端,直接模拟终端请求
self.client = app.test_client()
def test_empty_name_password(self):
"""测试模拟场景,用户名或密码不完整"""
# 使用客户端向后端发送post请求, data指明发送的数据,会返回一个响应对象
response = self.client.post("/login", data={})
# respoonse.data是响应体数据
resp_json = response.data
# 按照json解析
resp_dict = json.loads(resp_json)
# 使用断言进行验证(断言是否满足预期结果)
self.assertIn("code", resp_dict)
code = resp_dict.get("code")
self.assertEqual(code, 1)
# 测试只传name
response = self.client.post("/login", data={"name": "admin"})
# respoonse.data是响应体数据
resp_json = response.data
# 按照json解析
resp_dict = json.loads(resp_json)
# 使用断言进行验证
self.assertIn("code", resp_dict)
code = resp_dict.get("code")
self.assertEqual(code, 1)
def test_wrong_name_password(self):
"""测试用户名或密码错误"""
# 使用客户端向后端发送post请求, data指明发送的数据,会返回一个响应对象
response = self.client.post("/login", data={"name": "admin", "password": "itcast"})
# respoonse.data是响应体数据
resp_json = response.data
# 按照json解析
resp_dict = json.loads(resp_json)
# 使用断言进行验证
self.assertIn("code", resp_dict)
code = resp_dict.get("code")
self.assertEqual(code, 2)
if __name__ == '__main__':
unittest.main()
数据库单元测试demo
# coding:utf-8
import unittest
from author_book import Author, db, app
class TestDatabase(unittest.TestCase):
"""测试数据库的案例"""
def setUp(self):
#开启测试模式
app.debug = True
#对应修改成自己测试数据库
app.config["SQLALCHEMY_DATABASE_URI"] = "mysql://root:mysql@127.0.0.1:3306/test"
db.drop_all()
//第一次生成表
db.create_all()
def test_author(self):
"""测试添加作者的案例"""
author = Author(name="cloudwalk", email="cloudwalk@cn")
db.session.add(author)
db.session.commit()
ret_author = Author.query.filter_by(name="cloudwalk").first()
self.assertIsNotNone(ret_author)
self.assertEqual(ret_author.name, "itcast")
def tearDown(self):
"""在所有测试方法执行后,被调用"""
# 清除记录的测试任务
db.session.remove()
# 清除数据库数据
db.drop_all()
if __name__ == '__main__':
unittest.main()
发送邮件测试
#coding=utf-8
import unittest
from Flask_day04 import app
class TestCase(unittest.TestCase):
# 创建测试环境,在测试代码执行前执行
def setUp(self):
self.app = app
# 激活测试标志
app.config['TESTING'] = True
self.client = self.app.test_client()
# 在测试代码执行完成后执行
def tearDown(self):
pass
# 测试代码
def test_email(self):
resp = self.client.get('/')
print resp.data
self.assertEqual(resp.data,'ok')