游戏测试 【测试工具】配置表 svn 比对工具

特尔斯特 · 2022年03月09日 · 最后由 lazydao 回复于 2022年04月10日 · 7559 次阅读

场景:最近一个游戏版本发布后玩家发现游戏中的某个英雄在佩戴一把特殊 n 星武器后射程发生了异常,从远程变成了近战。一查是因为策划改动这个武器的技能配置,可是 QA 并不知道,因为没有口头告知或者有需求单,理论上所有的配置表变动都应该有对应的需求单,并且需求单要转到对应的 QA 进行测试,实际上大部分公司由于策划的个人素质或者管理方面的原因并不能做到这一点,结果是出了问题又来反问 “为什么没有测到?"或者默认把锅盖到 QA 头上,升职加薪年终奖都会受到影响,说多了容易 emo ~

解决方案:把游戏上次上线的节点到当前节点的配置表 SVN 变更输出到一个文件夹中用来在上线前做最后的检查和确认,有疑议再找策划确认,一定程度上能降低上述问题再发生。

分析:
1.配置表文件夹可能是多层级的,所以这里不能只按只有一层的文件夹来处理
2.配置表有可能是当前版本周期 (当前版本周期指上次发布到线上的最终 svn 版本号~这次版本最后发布的 svn 版本号) 创建的,diff 一个比它小的 svn 版本号会什么都没有
3.在处理了 2 的前提下,配置表可能是当前版本周期创建的同时没有任何变更,这种情况下我希望能把这个新增的且没有任何变更的配置文件复制到输出文件夹中和其他 log 文件一同检查避免某种风险。

算法:
取某个文件的最初的 svn 版本号和最后的 svn 版本号和要比对的版本号(comp_version) 对比,
if ( 最后的 svn 版本号< = comp_version):
    说明这个文件在当前版本周期根本没变过就不用检查了
else (最后的 svn 版本号 > comp_version):
     if ( 最初的 svn 版本号== 最后的 svn 版本号):
       说明这个文件是” 新增的 “同时” 没有任何变更 “的文件,把它复制出去
    else ( 最初的 svn 版本号!= 最后的 svn 版本号):
       说明这个文件在 comp_version 后是有变更的,读 diff log 并保存

最终效果:
配置表目录:

输出的报告目录:

完整代码:

#coding=utf-8
import os
import datetime
import re


config_path=r"E:\Trunk2ForTest\Client\TEST\Assets\Editor\QA\JsonFile\\"  #配置表路径
out_put_path ="E:\svncheck\\"#报告存放路径
comp_version="1000" #需要比对的版本号

#得到当前目录下所有json的文件名
def get_jsons():
    jsons =[]
    for root,dirs,files, in  os.walk(config_path):
        for file in files:
            if file.split('.')[-1]=="json":#筛选出json格式的文件,因为是Unity项目还会有很多.meta文件
                jsons.append(os.path.join(root, file))
    return jsons


#创建一个标记时间和comp_versoin的文件夹,用来保存报告
def make_report_path():
    current_date = datetime.datetime.now().strftime('%Y%m%d%H%M%S')
    print(current_date)
    report_path =out_put_path+"%s\\"%(current_date+"_"+comp_version)
    if not os.path.exists(report_path):
        os.makedirs(report_path)
    print("报告文件路径:"+report_path)
    return report_path

#检查svn变更输出日志
def check_json_svn_change(jsons,report_path):

    for json in jsons:
        def create_level_path(json):
            dir_and_json_name = json.split(config_path)[-1]
            json_name = dir_and_json_name.split('\\')[-1]
            dir = dir_and_json_name.rstrip(json_name)
            deep_report_path = report_path + "\\" + dir
            if (dir and not os.path.exists(deep_report_path)):
                os.makedirs(deep_report_path)
            return deep_report_path,dir_and_json_name

        init_version,last_versoin = get_init_version_and_last_version(json)
        #print(init_version,last_versoin)
        svn_comp_version = comp_version
        #如果最后的版本号不大于比对的版本号(comp_version),说明当前版本区间这个文件根本没有任何变化,可以跳过不做任何处理
        if last_versoin<svn_comp_version or last_versoin==svn_comp_version:
            continue
        elif last_versoin==init_version:#如果最后的版本号和最初的版本号相等,说明这个文件创建后没有做任何变更,如果这个版本号比comp_version大按照需求把它复制出来检查
            #考虑到有多级目录的情况,需要创建对应的目录
            temp_path= create_level_path(json)[0]
            cmd ="copy %s %s"%(json,temp_path)
            print(cmd)
            os.system(cmd)
        else:
            dir_and_json_name = create_level_path(json)[1]
            dir_and_json_name = dir_and_json_name.replace(".json",".log")
            svn_comp_version = svn_comp_version if comp_version> init_version else init_version
            svn_cmd = "svn diff -r %s %s > %s"%(svn_comp_version,json,report_path+dir_and_json_name)
            print(svn_cmd)
            os.system(svn_cmd)



#得到某个文件的最初svn版本号和最终svn版本号
def get_init_version_and_last_version(file):
    svn_log = os.popen('svn log %s'%file)
    svn_log = svn_log.read()
    pattern = "r(\d+) \|"
    res = re.findall(pattern,svn_log)
    return res[-1],res[0]



if __name__ == "__main__":
    report_path = make_report_path()
    jsons = get_jsons()
    print(jsons)
    check_json_svn_change(jsons,report_path)
    os.system("explorer %s"%out_put_path)#直接打开输出的文件夹,方便查看

测试用例执行结果:

**** 最开始想要用 pysvn 来实现,可惜在网上找了几个版本都有各种问题不好解决,所以直接用 os.system 来操作 svn 指令。

共收到 9 条回复 时间 点赞

不太清楚为啥你找的 pysvn 有各种问题不好解决。https://pysvn.sourceforge.io/downloads.html 我在这里下的,好像也没遇到什么问题,用的还算顺手。

开发工具是好,但遇到这种事情,天塌下来也不能接锅

最佩服你的不是解决问题的思路,而是发现能用技术手段去解决的问题。

陈随想 回复

pysvn.client.diff() 总是提示路径或是什么 “语法卷错误”,请大佬指点

特尔斯特 回复

这个我也不知道哦,https://tools.ietf.org/doc/python-svn/pysvn_prog_ref.html#pysvn_client_diff 你看看官方的这个,参数都写的很清楚,可能对你有帮助。

陈随想 回复

好的,谢谢

做事前要先思考,解决这个问题用管理手段和技术手段,哪样更好?

Thirty-Thirty 回复

能这么问说明你在一个开明的团队

其实这个有现成的工具能做到更好,比如 Beyond Compare 能直接比较文件夹差异,并且输出 HTML 格式的 diff 结果。
我们这就做了个类似的工具,只需要写点胶水脚本执行 svn 更新至指定版本然后调用 Beyond Compare 的命令就得了。如果明天在公司我还记得这事,就补个截图🤣

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册