(2)Swift项目覆盖率

此模块为主要功能,包含下载项目源码,覆盖率数据profdata文件,下载测试包ipa解压取出可执行的二进制文件,使用xcrun命令行成覆盖率执行,通过git diff过滤生成增量报告,解析覆盖率报告数据,下载覆盖率报告功能。
  • Swift生成报告类swiftCovReportOperations
    # coding=utf-8
    import json
    import os,asyncio
    
    from iOSOCAndSwiftAgent.UtilsOperation.const import DEBUG_SERVICE
    from iOSOCAndSwiftAgent.UtilsOperation.iOS_Diff_Parser import iOSDiffParser
    
    
    class swiftCovReportOperations():
        """
        生成Swift报告相关的操作类
        """
        def __init__(self):
            if DEBUG_SERVICE.find("Agent")>-1:
                #写死Agent上的路径
                scriptpath="/Users/*****/ScriptFiles/"
            else:
                #本机debug
                scriptpath="/Users/*****/ScriptFiles/"
            self.genhtml=scriptpath+"lcov-1.14/bin/genhtml"
    
    
        def getBinDataFilePath(self,propath):
            """
            获取应用对应的可执行文件
            :return:
            """
            return propath+"Kima"
    
        def createXcodeCoverageReport(self,propath,curbranch,combranch):
            """
            生成XcodeCoverage格式的报告
            :param propath: 项目地址
            :return:
            """
            curpath = os.getcwd()
            profrawfold=propath+"profrawdata"
            #获取文件夹下的所有文件,并进行合并
            allprofraw=""
            frawlist=os.walk(profrawfold)
            for path,dir_list,file_list in frawlist:
                for file_name in file_list:
                    if file_name.find("profraw")>-1:
                        allprofraw=allprofraw+" "+file_name
            #合并覆盖率数据
            if len(allprofraw)>0:
                os.chdir(profrawfold)
                mergedcmd="xcrun llvm-profdata merge"+allprofraw+" -output ./coverage_merged.profraw"
                os.system(mergedcmd)
                #转换数据文件类型
                changecov="xcrun llvm-profdata merge -sparse ./coverage_merged.profraw -o ./coverage_merged.profdata"
                os.system(changecov)
                #生在info文件
                appbinpath=self.getBinDataFilePath(propath)
                infocmd="xcrun llvm-cov export "+appbinpath+" --instr-profile=./coverage_merged.profdata -use-color --format=lcov > ./allreport.info"
                os.system(infocmd)
                newpropath=propath+"packages"
                newpropath=newpropath.replace("/","\/")
                print("当前项目路径:"+newpropath)
                changecmd="sed -i '' 's/\/Users\/****/packages/"+newpropath+"/g' ./allreport.info"
                os.system(changecmd)
                print("替换allreport.info中的项目路径")
                #删除allreport.info中的Pods相关的文件信息
                self.removePodFileFromInfoFile(profrawfold+"/allreport.info")
                print("删除allreport.info文件中的Pods相关文件信息")
                #生成全量XcoverageReport
                reportcmd=self.genhtml+" -o "+propath+"/allreport "+profrawfold+"/allreport.info"
                os.system(reportcmd)
                os.chdir(curpath)
                #生成增量覆盖率报告
                self.createDiffReport(propath,curbranch,combranch,"normal")
    
            else:
                print("没有覆盖率数据,无需生成覆盖率报告")
    
        def getCurrentCommitOfPro(self,propath):
            """
            获取当前项目的最新版本
            :param propath:
            :return:
            """
            curpath=os.getcwd()
            os.chdir(propath)
            getcutcont=os.popen("git log").read()
            linescheck=getcutcont.split("\n")
            curcommitinfo=linescheck[0]
            curcommit=curcommitinfo[curcommitinfo.index(" ")+1:]
            os.chdir(curpath)
            return curcommit
    
    
        def createDiffReport(self,propath,curbranch,combranch,difftype):
            """
            生成增量XcodeCoverage报告
            :param propath: 项目地址
            :param target_branch: 目标分支
            :param source_branch: 源分支
            :param difftype 增量报告的类型,正常为normal,合并覆盖率的为merged
            :return:
            """
            if not propath.endswith("/"):
                propath=propath+"/"
            if len(propath)>0:
                #处理一下source_branch,去掉:remotes/origin/
                if combranch.find("/")>-1:
                    combranch=combranch[combranch.rindex("/")+1:]
                    print("要对比的路径是:"+combranch)
                else:
                    if curbranch.find("/")>-1:
                        curbranch=self.getCurrentCommitOfPro(propath)
                    print("对比的是版本,当前版本:"+curbranch+",对比版本:"+combranch)
                #生成增量的info文件
                iosdiffoper=iOSDiffParser()
                iosdiffoper.createDiffInfoFile(propath,combranch,curbranch,difftype)
                #生成增量覆盖率报告
                profrawfold=propath+"profrawdata"
                #如果diffreport.info为空
                if os.path.getsize(profrawfold+"/diffreport.info")>0:
                    reportcmd=self.genhtml+" -o "+propath+"/diffreport "+profrawfold+"/diffreport.info"
                    os.system(reportcmd)
                else:
                    #将diff文件详情记录下来
                    with open(propath+"difffilelist.json","w",encoding='utf-8') as fp:
                        json.dump(iosdiffoper.file_diff_line,fp,ensure_ascii=False)
                    print("diffreport.info为空,无需要生成增量报告!")
            else:
                print("项目地址为空,无法生成覆盖率报告")
    
        def createCommitsMergedReports(self,propath,srccommit,desccomit):
            """
            生成跨版本合并的覆盖率报告
            :param propath:
            :param srccommit:
            :param desccomit:
            :return:
            """
            #获取合并的最新版本号
            resultjson=propath+"/profrawdata/allcommits_infofile_detail.json"
            if os.path.exists(resultjson) and os.path.getsize(resultjson)>0:
                with open(resultjson, "r") as readjson:
                    json_data = json.load(readjson)
            for commits in json_data.keys():
                pass
            #切换到指定的版本
            os.system("git checkout "+commits)
    
            commits_merged_infofile=propath+"/profrawdata/all_commits_megedreport.info"
            #去掉Pod相关的文件信息
            self.removePodFileFromInfoFile(commits_merged_infofile)
            if os.path.getsize(commits_merged_infofile)>0:
                #生成合并后的全量报告
                reportcmd=self.genhtml+" -o "+propath+"/allreport "+commits_merged_infofile
                os.system(reportcmd)
                #生成增量覆盖率报告
                self.createDiffReport(propath,commits,desccomit,"merged")
            else:
                print("合并后的info数据为空,无需生成报告!")
            #切换相应的分支
            os.system("git checkout "+srccommit)
    
        def removePodFileFromInfoFile(self,infofilepath):
            """
            去掉info文件中,有关Pod路径下的项目
            :param infofilepath:
            :return:
            """
            cutcont="cat "+infofilepath+"|grep SF:"
            getcutcont=os.popen(cutcont).read()
            linescheck=getcutcont.split("\n")
            for i in range(len(linescheck)):
                covfile=linescheck[i]
                if len(covfile)>0 and covfile.find("Pods")>-1:
                    #获取指定行号之间的内容
                    fileloccmd="grep -n '"+covfile+"' "+infofilepath
                    fileloccont=os.popen(fileloccmd).read()
                    fileloc=fileloccont[0:fileloccont.index(":")]
                    endloccmd="grep -n '"+linescheck[i+1]+"' "+infofilepath
                    endloccont=os.popen(endloccmd).read()
                    endloc=int(endloccont[0:endloccont.index(":")])-1
                    if endloc==0:
                        #找出文件最后一行行号
                        lastloccont=os.popen("wc -l "+infofilepath).read()
                        lastloccont=lastloccont.strip()
                        lastloc=lastloccont[0:lastloccont.index("/")-1]
                        endloc=lastloc
                    #删除指定的行之间的内容
                    sedcmd="sed -i '' '"+fileloc+","+str(endloc)+"d' "+infofilepath
                    os.system(sedcmd)
    
    
    
    
    if __name__ == '__main__':
        covreport=CovReportOperations()
        

    Agent架构中其他功能,由于涉及到公司内部的资料,不方便公开,在此就不展开介绍了。

Logo

更多推荐