1、知识点
- 多线程
- 一个电脑有几核的cpu,就只能同时运行几个任务
- 上下文切换
- python里面的多线程利用不了多核cpu
- GLI 全局解释器锁:保证线程在同一个cpu上运行
- 多线程,线程之间数据是共享的:每个线程都可以操作这个数据
- 多进程:可以利用多核cpu
- 进程包含线程的
- CPU密集型任务,用多进程:消耗CPU多
- IO密集型任务,用多线程:消耗IO比较多
- 磁盘IO
- 网络IO
- 多进程,每个进程之间数据是独立的(所以进程里的锁没啥意义)
- 协程:一个线程,异常IO
- nginx
2、进程实例
1 import multiprocessing 2 import time 3 import threading 4 5 lock = multiprocessing.Lock() 6 7 a = 1 8 9 def mytest2(): 10 print("线程") 11 12 def mytest(): 13 # for i in range(20): 14 # t = threading.Thread(target=mytest2) 15 # t.start() 16 time.sleep(3) 17 global a 18 with lock: 19 a += 1 20 print('子进程:',a) #为2;每个进程资源独享 21 22 # 快捷输入:输入main 23 if __name__ == '__main__': 24 # mytest() 25 26 for i in range(5): 27 p = multiprocessing.Process(target=mytest) 28 p.start() 29 # print(p.pid) #打印进程id 30 print('abc') 31 32 while len(multiprocessing.active_children()) != 0: 33 # print(multiprocessing.active_children()) 34 # print("请稍后,正在处理中.....") 35 pass 36 37 print('主进程:',a) #还是1 38 print('over!!!')
3、unittest单位测试框架
- 知识点
- 在TestCase里面,如果是一个测试用例,函数名必须以test开头
- 执行顺序按函数名先后顺序执行
- 查找测试用例:查找某个目录的测试用例
- 产生测试报告
- HTMLTestRunner
- pip install nnreport
-
- 参数化:pip install parameterized
- 代码驱动
- 数据驱动
- 关键字驱动:ui自动化
- 参数化:pip install parameterized
-
-
- 流程用例:登录-创建优惠券-查询优惠券
-
- 实例1
import unittest def add(a,b): return a+b class AddTest(unittest.TestCase): # 每个用例执行之前执行 def setUp(self): print('初始化') # 每个用例执行之后执行 def tearDown(self): print('清理现场') # 所有用例执行之前执行 # 场景:bak_db() 备份数据 @classmethod def setUpClass(cls): print('setUpClass') # 所有用例执行之后执行 # 场景:db()清理数据 @classmethod def tearDownClass(cls): print('tearDownClass') def test_add_normal(self): result = add(1,1) # self.assertEquals(2) #self.assertEqual(2,result) print('add_norma') def test_add_error(self): result = add(1,1) print('add_error') #self.assertEqual(1,result,'add测试结果不通过,预期结果1,实际结果%s'%result) def test_b(self): result = add(0,1) #self.assertEqual(1,result) print('b') def test_a(self): result = add(0,0) #self.assertEqual(0,result) print('a') # 运行当前文件里的所有用例 unittest.main()
- 产生测试报告:HTMLTestRunner模块
1 import unittest 2 import HTMLTestRunner # 放入环境变量 3 4 5 class TestLogin(unittest.TestCase): 6 def test_login_normal(self): 7 '''正常登录''' 8 self.assertEqual(1,1) 9 10 def test_login_black_list(self): 11 '''黑名单登录''' 12 self.assertTrue(False,'黑名单登录失败') 13 14 def test_login_exit(self): 15 '''注销用户登录''' 16 self.assertNotIn(1,[1,2,3],'not in') 17 18 def test_login_max_count(self): 19 '''登录最大次数''' 20 self.assertNotEquals(1,2,'不相等') 21 22 23 #产生测试报告时,需注释 24 #unittest.main() 25 26 # 方法一 27 # suite = unittest.TestSuite()#测试集合 28 29 # # 手动一个个的把用例加入到测试集合中 30 # suite.addTest(TestLogin('test_login_normal')) 31 # suite.addTest(TestLogin('test_login_black_list')) 32 33 # 方法二:推荐 34 # 把一个类里面的所有测试用例,放大一个测试集合 35 suite = unittest.makeSuite(TestLogin) 36 37 38 # 产生测试报告 39 f = open('测试报告.html','wb') 40 runner = HTMLTestRunner.HTMLTestRunner(f, 41 title='登录接口测试报告', 42 description='登录接口测试报告') 43 runner.run(suite) 44 f.close()
- 产生测试报告:nnreport模块
1 import unittest 2 import nnreport 3 4 class TestLogin(unittest.TestCase): 5 def test_login_normal(self): 6 '''正常登录''' 7 self.assertEqual(1,1) 8 9 def test_login_black_list(self): 10 '''黑名单登录''' 11 self.assertTrue(False,'黑名单登录失败') 12 13 def test_login_exit(self): 14 '''注销用户登录''' 15 self.assertNotIn(1,[1,2,3],'not in') 16 17 def test_login_max_count(self): 18 '''登录最大次数''' 19 self.assertNotEquals(1,2,'不相等') 20 21 22 #产生报告时,需注释 23 #unittest.main() 24 25 26 27 # 把一个类里面的所有测试用例,放大一个测试集合 28 suite = unittest.makeSuite(TestLogin) 29 30 31 #产生测试报告 32 runner = nnreport.BeautifulReport(suite) 33 runner.report(description='登录接口测试报告', 34 filename='login_report.html', 35 log_path='/Users/snail/PycharmProjects/python自动化/day9')
- 查找测试用例:测试用例并不是写在一个文件里,所以需要找出所有测试用例并执行
- 用例目录
- 执行用例文件:同cases在同一个目录下
1 import unittest 2 import nnreport 3 4 # 传入路径 5 # 匹配规则的文件才会被执行 6 # 查找用例 7 suite = unittest.defaultTestLoader.discover('cases','test*.py') 8 9 report = nnreport.BeautifulReport(suite) 10 report.report('查找测试用例')
- 运行结果:login.py文件不会被执行
- 参数化:parameterized模块
1 import unittest 2 import requests 3 import parameterized 4 import os 5 6 class GetData: 7 # 读取参数化文件 8 @staticmethod 9 def read_data(filename): 10 data = [] 11 if os.path.exists(filename): 12 with open(filename,'r',encoding='utf-8') as f: 13 for line in f: 14 param = line.strip().split(',') 15 data.append(param) 16 else: 17 raise FileNotFoundError('参数化文件找不到') 18 return data 19 20 @staticmethod 21 def read_data_from_excel(filename): 22 pass 23 24 @staticmethod 25 def read_data_from_redis(key): 26 pass 27 28 @staticmethod 29 def read_data_from_mysql(sql): 30 pass 31 32 33 class TestStuInfo(unittest.TestCase): 34 url = 'http://api.xxxx.cn/api/user/stu_info' 35 36 # #参数化:有几条数据就运行几次 37 # @parameterized.parameterized.expand( 38 # [ 39 # ['lzh'], 40 # ['zsb'], 41 # ] 42 # 43 # ) 44 # def test_single(self,name): 45 # print(name) 46 # data = {'stu_name':name} 47 # r = requests.get(self.url,data) 48 # print(r.json()) 49 50 @parameterized.parameterized.expand(GetData.read_data('stu_info.txt')) 51 def test_single(self,name,age): 52 print(name) 53 data = {'stu_name':name,'age':age} 54 r = requests.get(self.url,data) 55 print(r.json()) 56 57 unittest.main()
- 运行结果:
- 场景用例??