筑建网站,上海已经开始二次感染了,网站建设与管理 规划书,如何通过网站后台修改网站案情描述
收到这么一个需求#xff1a;存在一个数据库查询功能接口#xff0c;需要完成1000个条件语句的查询#xff0c;并将查询结果与原始数据库#xff08;如es#xff09;的查询结果对比#xff0c;从而判定该功能接口是否正常#xff0c;且正确可用。
第一次测试…案情描述收到这么一个需求存在一个数据库查询功能接口需要完成1000个条件语句的查询并将查询结果与原始数据库如es的查询结果对比从而判定该功能接口是否正常且正确可用。第一次测试设计读取文件中的1000个查询条件顺序执行。但由于查询数据量较大单线程顺序完成1000次查询耗时较长效率太低——抛弃第二次测试设计使用并发查询多线程并发提高工作效率节省了大大的时间。但将输出的1000个查询结果与原始数据库查询结果对比时发现某些语句差异较大为什么抽丝剥茧为何功能接口查询结果与原始数据查询结果差异性大经过排查问题出在查询语句对比时匹配错位——使用简单并发查询输出并不严格按照读入顺序。换句话说读入1、2、3、4、5个顺序查询条件并发查询输出顺序可能时2、1、3、4、5也可能时4、5、2、1、3。那么如何在编写测试脚本时让并发输出严格按照读入顺序输出呢亡羊补牢从Python3.2开始标准库为我们提供了concurrent.futures模块它提供了ThreadPoolExecutor和ProcessPoolExecutor两个类可以帮助我们更好地完成并发设计。本文我们不过深地讲述如何使用这些Python类只简单讲述如何解答我们的核心问题——“如何在并发时让结果严格按照输入顺序输出”。线程池ThreadPoolExecutor……如下所示为ThreadPoolExecutor的基本使用方法打印输入的list列表中的数字。ThreadPoolExecutor()初始化创建线程池最多2个线程并发运行通过submit调用子函数打印输入数字最终通过as_completed等待所有任务完成后通过result收集返回结果。# -*-coding:utf-8 -*-from concurrent.futures import ThreadPoolExecutor,as_completed# 子函数打印输入数字def print_num(num):return numlist [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]##############使用ThreadPoolExecutor##################################并发执行非顺序返回################# 创建线程池子# 设置最多2个线程运行其他等待executor ThreadPoolExecutor(max_workers2)all_task [executor.submit(print_num, (num)) for num in list]result2_list []for future in as_completed(all_task):data future.result()result2_list.append(data)print(并发执行非顺序返回 str(result2_list))##############################################如下图所示为上述使用ThreadPoolExecutor并发运行的结果由结果打印可知输出并非严格按照列表输入值顺序输出。由此可以预见当我们简单使用并发时我们的结果可能并不是我们认为的与“顺序”输出。那么如何改造呢请关注map方法。使用map方法无需提前使用submit方法map方法与python标准库中的map含义相同都是将序列中的每个元素都执行同一个函数。###############并发执行顺序返回################# 创建线程池子# 设置最多2个线程运行其他等待executor ThreadPoolExecutor(max_workers2)result1_list []for result in executor.map(print_num, list):result1_list.append(result)print(并发执行顺序返回 str(result1_list))##############################################上面的代码就是对list的每个元素都执行print_num子函数并分配各线程池。由此可以看到执行结果与上面的as_completed方法的结果不同输出顺序和list列表的顺序相同。进程池ProcessPoolExecutor……使用进程池ProcessPoolExecutor处理并发输入按序输出问题同ThreadPoolExecutor一样使用map方法即可解决。但是值得注意的是注意在使用多进程时必须把 多进程代码写在?if __name__ __main__ 下面否则异常甚至报错“concurrent.futures.process.BrokenProcessPool: A process in the process pool was terminated abruptly while the future was running or pending.”#########################使用ProcessPoolExecutor####################################并发执行顺序返回################# 创建进程池子# 设置最多2个进程运行其他等待if __name__ __main__:executor ProcessPoolExecutor(max_workers2)result2_list []for result in executor.map(print_num, list):result2_list.append(result)print(ProcessPoolExecutor并发执行顺序返回 str(result2_list))###################################################################################################################还存在一点“笨”方法……除了上述所说的ThreadPoolExecutor和ProcessPoolExecutor使用map方法让结果顺序输出外我们还可以使用一些笨方法。例如使用并发运行程序并发方法不仅限于ThreadPoolExecutor和ProcessPoolExecutor还可以使用threading等等sort方法对输出结果排序。就上述案例而言不使用map可以如下改造###############并发执行非顺序返回################# 创建线程池子# 设置最多2个线程运行其他等待executor ThreadPoolExecutor(max_workers2)all_task [executor.submit(print_num, (num)) for num in list]result2_list []for future in as_completed(all_task):data future.result()result2_list.append(data)result2_list.sort()print(ThreadPoolExecutor并发执行非顺序返回 str(result2_list))##############################################最终输出结果符合我们的要求。结案陈词ThreadPoolExecutor 多线程并行执行任务可以共享当前进程变量但缺点也很致命但其实仍然最多只能占用 CPU 一个核。如果指定的任务和线程数不恰当(比如一个任务很短线程数量很多导致线程频繁调用回收)那么效率还不如单线程。ProcessPoolExecutor可以使用多核进行计算但缺点就是进程之间共享数据就比较麻烦,消耗更多的内存。本文的主要目的是帮助大家认识并发好用但使用需谨慎。谨防一不小心落入并发的坑使用map方法可以帮助大家快速地完成测试结果地有序输出。感谢每一个认真阅读我文章的人礼尚往来总是要有的虽然不是什么很值钱的东西如果你用得到的话可以直接拿走这些资料对于【软件测试】的朋友来说应该是最全面最完整的备战仓库这个仓库也陪伴上万个测试工程师们走过最艰难的路程希望也能帮助到你!有需要的小伙伴可以点击下方小卡片领取