python 多进程&unittest单元测试框架&HTMLTestRunner模块&nnreport模块&parameterized模块

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自动化
      •   流程用例:登录-创建优惠券-查询优惠券
  • 实例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()
    • 运行结果:

  • 场景用例??

猜你喜欢

转载自www.cnblogs.com/tour8/p/13170573.html