py文件名不要用大写英文字母开头,因为在Linux系统中是区分大小写的,而在Windows系统是不区分大小写的,为了代码也能在Linux系统顺利运行,所以一般不使用大写字母开头命名py文件和包
1、在当前脚本调试代码__name__
在脚本下方使用if __name__ == '__main__'
语句可以运行当前脚本代码。
-
__name__
是模块的特殊变量 - 当直接执行当前模块的时候
__name__
就等于'__main__'
所以,if __name__ == '__main__'
这个语句成立,可以执行这个条件下的语句 - 当被其他模块导入的时候
__name__ = 模块名
所以,if __name__ == '__main__'
这个语句不成立,不会执行这个条件下的语句
def login_check(username, password):
"""
登录校验的函数
:param username: 账号
:param password: 密码
:return:
"""
if 6 <= len(password) <= 18:
if username == 'python34' and password == 'lemonban':
return {"code": 0, "msg": "登录成功"}
else:
return {"code": 1, "msg": "账号或密码不正确"}
else:
return {"code": 1, "msg": "密码长度在6-18位之间"}
print(__name__) # 输出__main__
if __name__ == '__main__':
# 这个里面的代码只有直接执行当前脚本的时候才会运行,
# 别的代码导入当前脚本,不执行
print('我执行了')
2、unittest模块
2.1使用步骤
先看下面代码,再逐步分析
import unittest
from login import login_check
class TestLogin(unittest.TestCase):
"""
测试登录功能
"""
def test_login_ok(self, username, password):
"""
账号和密码都正确
:return:
"""
# 1、测试数据
test_data = {"username": "tony", "password": "aabbcc123"}
# 2、期望数据
expect_data = {"code": 1, "msg": "账号或密码不正确"}
# 3、执行函数
res = login_check(**test_data)
# 4、断言
self.assertEqual(expect_data, res)
if __name__ == '__main__':
# 5. 调用unittest.main()来执行测试用例
unittest.main()
- 1、导入unitest模块和待测试函数
import unittest
from login import login_check
- 2、创建测试类,并继承unittest.TestCase
class TestLogin(unittest.TestCase):
"""
测试登录功能
"""
- 3、创建测试函数
def test_login_ok(self, username, password):
"""
账号和密码都正确
:return:
"""
3.1 创建测试数据
test_data = {"username": "tony", "password": "aabbcc123"}
3.2 创建期望数据
expect_data = {"code": 1, "msg": "账号或密码不正确"}
3.3 执行函数
res = login_check(**test_data)
3.4 断言
self.assertEqual(expect_data, res)
- 调用unittest.main()来执行测试用例
if __name__ == '__main__':
# 调用unittest.main()来执行测试用例
unittest.main()
2.2 利用main模块来执行测试用例
2.2.1收集测试套件(两个方法:手动收集和自动收集)
方法一:手动收集(不常用)
第一步:实例化测试套件
ts = unittest.TestSuite()
第二步:收集测试套件
- 手动收集测试套件(addTest与addTests)
- addTest一个个添加测试套件 语法:测试套件addTest(测试用例类名('单元测试方法名'))
ts.addTest(TestStrUpper('test_str_upper'))
#TestStrUpper 测试用例类名
#'test_str_upper' 是 '单元测试方法名'
- addTest一次添加多个测试套件 语法:以列表的形式输入 -->测试用例类名('单元测试方法名')
ts.addTests([TestLogin('test_login_ok'), TestLogin('test_login_password_err')])
看下代码汇总效果:
ts = unittest.TestSuite()
# 一个个收集测试套件
# 单元测试的语法: 测试用例类名('单元测试方法名')
ts.addTest(TestStrUpper('test_str_upper'))
ts.addTests([TestLogin('test_login_ok'), TestLogin('test_login_password_err')])
print(ts)
输入结果如下:
<unittest.suite.TestSuite tests=[<test_demo.TestStrUpper testMethod=test_str_upper>,
<test_case.TestLogin testMethod=test_login_ok>, <test_case.TestLogin testMethod=test_login_password_err>]>
addTest收集了一个测试套件,addTests收集了两个测试套件,所以print(ts)的输出结果中看到一共收集了三个测试套件。
但是此方法太麻烦,每个测试用例都要收到添加,不科学,所以此方法不常用;常用自动收集测试套件方法,就是下面介绍的第二个方法
方法二:自动收集(常用)
自动收集又分为两种情况,第一种是通过收集器TestLoader对象,通过模块、测试用例类、测试方法名来收集测试用例,这样也是需要导入模块、测试用例类或者测试方法名
情况1(不常用):通过模块、测试用例类、测试方法名来收集测试用例
- 第一步:实例化收集器TestLoader
- 第二步:通过TestLoader收集测试用例
import unittest
import test_case
# TestLoader对象,收集器
td = unittest.TestLoader() # 第一步:实例化收集器TestLoader
ts = td.loadTestsFromModule(test_case)#第二步:通过TestLoader收集测试用例
print(ts)
情况2(常用):通过目录自动收集测试用例
TestLoader有个discover方法:
- start_dir 开始查找的目录 递归的去所有目录下查找,开始目录下的所有文件夹中的文件(目录下一定要有__init__.py
)
- pattern 查找模块名的规则 test*.py 以test开头的模块,收集里面的测试用例
- top_level_dir 项目的顶层目录
一般只传开始目录一个参数 start_dir
代码如下:
td = unittest.TestLoader()
ts = td.discover('.') # .表示当前目录
print(ts, type(ts))
测试用例收集顺序(也是测试用例执行顺序)规则:
- 按照ascii码的顺序:先按照模块名进行收集,再按照在模块中类里的测试函数名
可以在test后面添加数字来指定哪个模块、函数来收集、执行测试用例:
模块:test01.py -- test02.py -- test03*.py,可以按照这个方式来指定顺序来收集测试用例
模块中类的测试函数名:test01_login_password_less5(self) -- test02_login_username_err(self) -- test03_login_password_err(self):
python3中文件夹中没有__int__.py
文件也认为此文件夹也是一个包,但是unitest例外,如果文件夹中没有__int__.py
文件,就不认为它是一个包,所以使用discover方法查找测试用例时,如果开始目录下的文件夹没有__int__.py
文件就不会查找此文件夹。
2.2.2执行测试
- 实例化运行器
- 传入测试套件
1、文本测试运行器执行测试用例(不常用)
#用文本测试运行器实例化运行器
runner = unittest.TextTestRunner()
# 传入测试套件
runner.run(ts)
总结一下main模块中的代码
import unittest #导入unittest模块
if __name__ == '__main__':
td = unittest.TestLoader() #实例化测试套件
ts = td.discover('.') #通过测试套件,用目录查找的方式收集测试用例
runner = unittest.TextTestRunner() #实例化运行器
runner.run(ts) #传入测试套件运行
2、HTMLTestRunnner运行器执行测试用例
需要HTMLTestRunnerNew模块
import unittest
from HTMLTestRunnerNew import HTMLTestRunner
if __name__ == '__main__':
td = unittest.TestLoader()
ts = td.discover('.')
with open(r'D:\Pycharm_workspace\day15u\report.html', 'wb') as f:
runner = HTMLTestRunner(stream=f, title='第一份测试报告', description='测试登录功能', tester='Leo')
runner.run(ts)
3、BeautifulReport运行器执行测试用例(常用)
import unittest
from BeautifulReport import BeautifulReport
if __name__ == '__main__':
td = unittest.TestLoader()
ts = td.discover('.')
# 实例化,并传入测试套件
br = BeautifulReport(ts)
br.report(filename='bf_测试报告.html', description='测试登录功能', report_dir=r'D:\Pycharm_workspace\day15u')
3、测试脚手架
unittest中的TestCase提供的一系列方法,它会在测试用例测试前,测试后执行
3.1在每个测试用例前都执行
- setUP 在每个单元测试函数开始前执行
- tearDown 在每个测试函数结束后执行
3.2在整个测试用例类开始执行前执行
是类方法,需要装饰器
class TestLogin(unittest.TestCase):
"""
测试登录功能
"""
def setUp(self) -> None:
"""
测试函数前置
:return:
"""
print("每个函数执行前都执行")
def tearDown(self) -> None:
"""
测试函数后置
:return:
"""
print("每个函数执行后都执行")
@classmethod
def setUpClass(cls) -> None:
"""
测试类前置
:return:
"""
print('在整个测试用例类开始测试前执行')
@classmethod
def tearDownClass(cls) -> None:
"""
测试类后置
:return:
"""
print('在整个测试用例类结束测试后执行')
def test_login_ok(self):
"""
账号和密码都正确
:return:
"""
网友评论