优化自动化测试流程,使用 flask 开发一个 toy jenkins工具 (2)

你基本上已经实现了功能,现在功能测试人员可以通过你搭建的简易平台执行自动化命令。但是这个平台还存在一些问题:第一、没有收集到构建信息,无法查看测试之后的结果;第二、用户必须等待自行测试脚本执行完成,才能返回前端具体的结果,如果自动化测试的执行时间很长,用户会一直停在这个页面,无法做其他事情。

 

你想到了并发编程,创建一个子进程单独去运行自动化测试脚本,因为子进程可以和主进程独立,所以不需要等待子进程执行完成,主进程就可以立即给前端返回结果。于是你重新编写了 build 函数:

 

@app.route("/build") def build(): id = uuid.uuid4().hex project_name = request.args.get('project') with open(id, mode='w', encoding='utf-8') as f: subprocess.Popen( ['pytest', f'workspace/{project_name}'], stdout=f ) return redirect(f'/build-history/{id}')

 

1、首先,通过 uuid 生成一个 id 号来表示这一次构建任务,之后可以通过这个 id 号查看此次构建的记录;

2、通过 subprocess 创建子进程运行自动化任务,把输出结果保存到文件当中,文件名就是生成的 id 号,之后想查看构建的结果时,只需要读取这个文件当中的内容;

3、只要子进程创建成功,马上通过 redirect 重定向到查看结果的 url, 此时并不需要等到子进程执行完就可以查看构建结果。

 

查看构建结果只需要通过 id 读取文件中的内容返回。

@app.route("/build-history/<id>") def build_history(id): with open(id, encoding='utf-8') as f: data = f.read() return data

 

 

4、生成器

上面读取文件的代码有点问题。当构建重定向到 /build-histrory 后,此时自动化测试脚本才刚刚执行,读取文件中的内容是空的。只有当测试脚本运行,产生越来越多的运行记录,文件中才会出现更多的内容,你必须手动刷新页面才能获取这些新内容。 当自动化任务执行时间很长的时候,你需要不停的刷新 /build-history 页面才能获取最新的构建信息。直到子进程结束,不再有新的内容被写入文件。

优化自动化测试流程,使用 flask 开发一个 toy jenkins工具

 

为了动态获取文件数据,你使用了生成器惰性获取数据,在 /build-history 的页面加载过程中,只要运行自动化任务的子进程还在运行,就不停的读取文件内容,将它们动态的返回给前端页面。

 

为了判断子进程的状态,在 /build 的时候,把子进程的 pid 传给 /build-history。

@app.route("/build", methods=['get', 'post']) def build(): id = uuid.uuid4().hex project_name = request.args.get('project') with open(id, mode='w', encoding='utf-8') as f: proc = subprocess.Popen( ['pytest', f'workspace/{project_name}'], stdout=f ) return redirect(f'/build-history/{id}?pid={proc.pid}')

 

在查看结果时,先编写一个生成器 stream, 每次读取文件中 100 长度的数据,直到进程运行结束。除了通过构建后的重定向,你也可以手动输入 id,查看历史构建记录。此时只需传 id, 不需要传进程名,直接读取文件中的数据。就算文件特别大,也可以通过批量加载,不至于因为同时读取大量数据给服务器造成压力。

import psutil @app.route("/build-history/<id>") def build_history(id): pid = request.args.get('pid', None) def stream(): f = open(id, encoding='utf-8') if not pid: while True: data = f.read(100) if not data: break yield data else: try: proc = psutil.Process(pid=int(pid)) except: return 'no such pid' else: while proc.is_running(): data = f.read(100) yield data return Response(stream())

 

最后效果:

优化自动化测试流程,使用 flask 开发一个 toy jenkins工具

 

5、总结

 

一般来说,做自动化测试只需要做到第一步,有脚本可以执行,就可以代替重复劳动。做测试平台只是让脚本变得更加好用。

 

但是有很多的测试平台让自动化运行起来更加复杂,要配置很多很多参数才能跑一个完整的测试用例,这似乎有点折本求末,也是很多人都在做的事情。

 

本文通过 flask 程序实现了一个最简单的 toy jenkins,辅助理解像 jenkins 这样的工具如何执行任务。其实像简单的构建任务,做起来也有很多问题需要解决,这些只有在遇到具体业务的时候我们才会去思考。

 

希望我们做的工具都是实用的,好用的。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpydgs.html