在这里会给大家介绍两种方式,分别为:
-
Allure服务器管理方案
-
Jenkins-Allure插件方案
本文中,以Allure服务器管理方案来给大家解决上述问题,若有需求去看Jenkins-Allure插件方案,可自行去本人其他文章中翻,感谢~
01背景
抛出问题:
-
跑完自动化生成的Allure测试报告是如何管理的?
-
我的Allure测试报告怎么只能本地展示啊?
-
别人怎么访问我的Allure测试报告链接?
-
我的测试用例中有截屏怎么在Allure报告展示?
02 环境要求
-
JDK11+
-
Python
03 方案说明
本次采用的方案为:pytest+allure+allure-server
-
pytest「不做过多解释」
-
allure「不做过多解释」
-
allure-server「一个大佬用写的allure服务管理的服务器,非常好用」
着重感谢一下allure-server,然后再贴出他的地址:github.com/kochetkov-m…
简单说就是,这个allure报告管理服务,可以给你提供一系列的API,让你使用API上传allure报告的压缩包之后,提供一个同一局域网可以访问的测试报告的链接,进而可以使所有人都可以查看报告,那它具体解决了什么问题呢?
-
跑完自动化生成的Allure测试报告统一在allure-server这个开源项目中管理
-
设置启动端口后,每次都会给你提供一个同一局域网的测试报告链接,所有人可访问
-
可解决截屏在allure中展示的问题
实例
04 使用
下载jar包
按照上面给你们的github项目可以进去找他的jar包,也可以点这个链接直接访问:github.com/kochetkov-m…
启动服务
此命令指定端口运行allure-server服务,防止端口冲突等问题。且环境要求JDK11及以上,否则会出现报错,若报错是JDK环境问题,请自行解决~
java -jar allure-server.jar --server.port=8898
访问服务
启动成功之后,访问链接:
http://{你的IP}/ui
allure-server接口文档
简单概述:提供了一些,上传报告,查看报告,删除报告的API
05 代码「敲黑板,开始讲重点了」
代码及解释
在这个位置,我写了一个allure_init的主函数来生成测试报告并将allure-server给的报告访问链接返回回来
def allure_init(results_dir, api_base_url, branch, build_name):
"""初始化Allure报告生成过程"""
try:
zip_path = zip_directory(results_dir)
logger.info(zip_path)
results_uuid = upload_results(f"{api_base_url}/result", zip_path)
report_data = generate_report(f"{api_base_url}/report", results_uuid, branch, build_name)
ip = get_host_ip()
url = report_data['url']
delete_file(zip_path)
return url.replace('localhost', str(ip))
except Exception as e:
return str(e)
代码解释:
-
zip_directory函数压缩指定目录,因为这里allure-server的API写明,只接受zip包上传
-
upload_results函数将压缩后的压缩包使用allure-server的API上传上去
-
generate_report函数来使用results_uuid唯一id来获得刚才上传上去的测试包的响应参数
-
get_host_ip函数来获取真实ip
-
最后做一些处理情况,比如获得相应参数中的url,并且清掉我们生成的压缩包
def zip_directory(source_dir):
"""将指定目录下的所有文件和子目录压缩成一个zip文件"""
if not os.path.exists(source_dir):
logger.error(f"The source directory {source_dir} does not exist.")
raise FileNotFoundError(f"The source directory {source_dir} does not exist.")
try:
output_zip = f'{config.BASE_DIR}/report/zip/{str(uuid.uuid1())}.zip'
output_dir = os.path.dirname(output_zip)
if not os.path.exists(output_dir):
os.makedirs(output_dir)
logger.info(f"Created directory {output_dir}")
with zipfile.ZipFile(output_zip, 'w', zipfile.ZIP_DEFLATED) as zipf:
for root, dirs, files in os.walk(source_dir):
for file in files:
file_path = os.path.join(root, file)
relative_path = os.path.relpath(file_path, start=source_dir)
zipf.write(file_path, relative_path)
logger.info(f"ZIP file created successfully at {source_dir}/allure_report.zip'")
return output_zip
except Exception as e:
# 异常处理,例如压缩失败
logger.error(f"Failed to create zip file due to: {e}")
raise Exception(f"Failed to create zip file due to: {e}")
def upload_results(api_url, file_path):
"""上传测试结果的zip文件到Allure服务器"""
try:
with open(file_path, 'rb') as file:
files = {'allureResults': (os.path.basename(file_path), file, 'application/zip')}
response = requests.post(api_url, files=files)
response.raise_for_status()
return response.json()['uuid']
except requests.exceptions.HTTPError as e:
logger.error(f"HTTP error occurred: {e}")
raise Exception(f"HTTP error occurred: {e}")
except requests.exceptions.RequestException as e:
logger.error(f"Error uploading file: {e}")
raise Exception(f"Error uploading file: {e}")
except Exception as e:
logger.error(f"Unknown error occurred: {e}")
raise Exception(f"Unknown error occurred: {e}")
def generate_report(api_url, results_uuid, path, build_name):
"""请求Allure服务器生成测试报告"""
data = {
"reportSpec": {
"path": path,
"executorInfo": {
"buildName": build_name
}
},
"results": [results_uuid],
"deleteResults": False
}
headers = {'Content-Type': 'application/json'}
try:
response = requests.post(api_url, headers=headers, json=data)
response.raise_for_status()
return response.json()
except requests.exceptions.HTTPError as e:
logger.error(f"HTTP error occurred while generating report: {e}")
raise Exception(f"HTTP error occurred while generating report: {e}")
except requests.exceptions.RequestException as e:
logger.error(f"Error generating report: {e}")
raise Exception(f"Error generating report: {e}")
except Exception as e:
logger.info(f"Unknown error occurred: {e}")
raise Exception(f"Unknown error occurred: {e}")
def get_host_ip():
"""获取本机 IP 地址"""
try:
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 使用 Google 公共 DNS 地址来确定自己的 IP 地址
s.connect(('8.8.8.8', 80))
ip = s.getsockname()[0]
finally:
s.close()
return ip
06 写在后面
更多的allure-server服务提供的API,请自行查看人家提供的API文档,目前看来是可以满足日常使用的。这套方案适合轻量化使用,在下一篇文章中我会给大家带来jenkins插件的方式来更简单的实现目前逻辑,敬请期待~
最后: 下方这份完整的软件测试视频教程已经整理上传完成,需要的朋友们可以自行领取【保证100%免费】