第6.3节 iOS Agent开发<一>

iOS由于其系统的特殊性,很多操作需要在Mac电脑上完成,所以也就无法部署到容器上。于是将iOS Agent开发成单独的服务,由Django开发,对外提供http请求接口,部署到Mac机器上以响应精准测试平台的请求。

6.3.1 Agent整体架构介绍

1,Agent功能架构图

2,功能模块介绍

(1)OC项目模块
针对 Object-C项目的生成覆盖率相关的操作,包括Clone项目,构建项目(需要构建后的Class文件),上传覆盖率文件(此文件为打包后的zip文件),XcodeCoverage生成覆盖率报告,以及解析覆盖率报告数据(取行覆盖率相关数据),下载覆盖率报告,以便精准测试平台展示。

  • 构建项目生成报告类iOSCovOperations:
python 复制代码
# coding=utf-8
import os,shutil
import zipfile

from iOSOCAndSwiftAgent.UtilsOperation.const import DEBUG_SERVICE


class iOSCovOperations(object):
    """
    iOS覆盖率相关操作
    """
    def getGcnoFilePath(self,propath):
        """获取项目构建后的gcno文件路径"""
        envfilepath=propath+"Pods/XcodeCoverage/env.sh";
        gcnopath=""
        rfile=open(envfilepath)
        line=rfile.readline()
        while line:
            if line.find("OBJECT_FILE_DIR_normal")>-1:
                gcnopath=line[line.index("=")+2:line.rindex("\"")]
                break
            line=rfile.readline()
        gcnopath=gcnopath+"/arm64"
        return gcnopath

    def copygcnofile(self,propath):
        """
        拷贝构建后的文件
        :param propath:
        :return:
        """
        # 4,拷贝构建后的代码到指定路径
        gcnopath=propath+"Pods/XcodeCoverage/gcnofolder"
        if os.path.exists(gcnopath):
            shutil.rmtree(gcnopath)
        shutil.copytree(self.getGcnoFilePath(propath),gcnopath)


    def buildPorject(self,propath):
        """构建iOS项目"""
        curpath = os.getcwd();
        scriptpath=""
        print("当前目录是:"+curpath)
        if DEBUG_SERVICE.find("Agent")>-1:
            #写死Agent上的路径
            scriptpath="/Users/****/ScriptFiles/"
        else:
            #本机debug
            scriptpath="/Users/*****/ScriptFiles/"
        os.chdir(propath)
        # 1,pod安装
        os.system("pod install")
        # 2,拷贝构建脚本
        os.system("cp "+scriptpath+"EnterpriseExportOptionsPlist.plist "+propath+"EnterpriseExportOptionsPlist.plist")
        os.system("cp "+scriptpath+"xcodebuild.sh "+propath+"xcodebuild.sh")
        os.system("chmod 777 "+propath+"xcodebuild.sh")
        # 获取项目名称
        proname=""
        for f in os.listdir(propath):
            print("file name:"+f)
            if f.find("xcworkspace")>-1:
                proname=f[0:f.index(".")]
                break
        #3,构建项目
        if len(proname)>0:
            os.system(propath+"xcodebuild.sh "+proname+" &")
        else:
            print("项目中没有项目文件,请检测项目内容是否有遗漏!")

        # # 4,拷贝构建后的代码到指定路径
        # gcnopath=propath+"Pods/XcodeCoverage/gcnofolder"
        # if os.path.exists(gcnopath):
        #     shutil.rmtree(gcnopath)
        # shutil.copytree(self.getGcnoFilePath(propath),gcnopath)
        #5,切换回当前目录
        os.chdir(curpath)
        return True

    def createiOSCovReport(self,propath,covdatapath):
        """根据覆盖率数据文件,生成覆盖率执行"""
        #1,拼出gcno文件路径
        gcnopath=propath+"Pods/XcodeCoverage/gcnofolder"
        #2,拷贝构建后的文件到覆盖率文件中
        for fileName in os.listdir(gcnopath):
            srcFile = os.path.join(gcnopath,fileName)
            tarFile = os.path.join(covdatapath,fileName)
            shutil.copyfile(srcFile,tarFile)

        #3,覆盖率报告路径
        covreppath=propath+"Pods/XcodeCoverage/tempreports/"+covdatapath[covdatapath.rindex("/")+1:len(covdatapath)]
        if not os.path.exists(covreppath):
            os.makedirs(covreppath)

        #4,重写env.sh文件内容
        envfile=propath+"Pods/XcodeCoverage/env.sh"
        os.remove(envfile)
        wrfile=open(envfile,"w+")
        #写入BUILT_PRODUCTS_DIR
        wrfile.write("export BUILT_PRODUCTS_DIR=\""+covreppath+"\"\t\n");
        #写入export CURRENT_ARCH=""
        wrfile.write("export CURRENT_ARCH=\"\"\t\n");
        #写入OBJECT_FILE_DIR_normal
        wrfile.write("export OBJECT_FILE_DIR_normal=\""+covdatapath+"\"\t\n");
        #写入OBJROOT
        wrfile.write("export OBJROOT=\"\"\t\n");
        #写入SRCROOT
        wrfile.write("export SRCROOT=\""+propath+"\"\t\n");
        wrfile.close()
        #5,执行生成报告命令
        getcovcmd=propath+"Pods/XcodeCoverage/getcov"
        os.system(getcovcmd)

        return covreppath


    def createXcodeCoverageReport(self,propath,covdatapath):
        """根据覆盖率数据,合并报告生成最终的报告"""
        gedatapath = propath + "Pods/XcodeCoverage/coverage"
        if not os.path.exists(gedatapath):
            os.makedirs(gedatapath)
        xcreppath = propath + "Pods/XcodeCoverage/report"
        if not os.path.exists(xcreppath):
            os.makedirs(xcreppath)
        #遍历覆盖率数据文件夹,分别生成报告
        count=0
        for file in os.listdir(covdatapath):
            if file.find("arm")>-1:
                tempcovpath=covdatapath+"/"+file
                print("数据文件:"+tempcovpath)
                temprep=self.createiOSCovReport(propath,tempcovpath)
                #拷贝生成的Coverage.info文件
                os.system("cp "+temprep+"/lcov/Coverage.info "+gedatapath+"/Coverage"+str(count)+".info")
                count=count+1
        # 生成整体覆盖率的报告
        mercmd=propath+"Pods/XcodeCoverage/mergecov"
        curpath = os.getcwd();
        if DEBUG_SERVICE.find("Agent")>-1:
            #写死Agent上的路径
            scriptpath="/Users/****/ScriptFiles/"
        else:
            #本机debug
            scriptpath="/Users/*****/ScriptFiles/"
        os.system("cp "+scriptpath+"mergecov "+mercmd)
        os.system("chmod 777 "+mercmd)
        os.system(mercmd)
        # 将生成的测试报告打包
        output_filename=propath+"report.zip"
        zipf = zipfile.ZipFile(output_filename, 'w')
        pre_len = len(os.path.dirname(xcreppath))
        for parent, dirnames, filenames in os.walk(xcreppath):
            for filename in filenames:
                pathfile = os.path.join(parent, filename)
                arcname = pathfile[pre_len:].strip(os.path.sep)
                zipf.write(pathfile, arcname)
        zipf.close()
        return xcreppath


    def getCovData(self,reppath):
        """
        获取覆盖率报告中的数据
        :param reppath:
        :return:
        """
        file=open(reppath,"r")
        line=file.readline()
        covlines=""
        totallines=""
        covlinerate=""
        covfuns=""
        totalfuns=""
        covfunrate=""
        while line:
            line=file.readline()
            if line.find("headerCovTableEntry")>-1:
                if len(covlines)==0:
                    covlines=line[line.index(">")+1:line.rindex("<")]
                    continue
                if len(covlines)>0 and len(totallines)==0:
                    totallines=line[line.index(">")+1:line.rindex("<")]
                    continue
                if line.find("%")>-1 and len(covlinerate)==0:
                    covlinerate=line[line.index(">")+1:line.rindex("<")]
                    continue
                if len(covfuns)==0:
                    covfuns=line[line.index(">")+1:line.rindex("<")]
                    continue
                if len(covfuns)>0 and len(totalfuns)==0:
                    totalfuns=line[line.index(">")+1:line.rindex("<")]
                    continue
                if line.find("%")>-1 and len(covfunrate)==0:
                    covfunrate=line[line.index(">")+1:line.rindex("<")]
                    break
        repdata={"totalines":totallines,"covlines":covlines,"covlinerate":covlinerate,"totalfuns":totalfuns,"covfuns":covfuns,"covfunrate":covfunrate}
        return repdata

if __name__ == '__main__':
    iosopr=iOSCovOperations()
    propath="/Users/****/ghdropmenudemo/"
covdatapath="/Users/****/ghdropmenudemo/Pods/XcodeCoverage/tempcovdata"
  
    iosopr.getCovData(propath+"Pods/XcodeCoverage/report/index.html")

此方案主要在构建项目上比较耗时,可以采取在公司打包平台打包后上传构建文件,以节省时间;同时上传的覆盖率数据文件也较大,由于公司的项目是Swift的,这个模块也没有再继续优化,使用测试Demo验证,相关功能没有问题

相关推荐
巴博尔11 小时前
uniapp的IOS中首次进入,无网络问题
前端·javascript·ios·uni-app
Digitally12 小时前
如何从 iPhone 中导出视频
ios·iphone
_阿南_18 小时前
flutter在Xcode26打包的iOS26上全屏支持右滑的问题
flutter·ios·xcode
2501_9160074719 小时前
iOS 26 软件性能测试 新版系统下评估全流程 + 多工具辅助方案
android·macos·ios·小程序·uni-app·cocoa·iphone
00后程序员张19 小时前
Swoole HTTPS 实战,在生产环境部署、性能权衡与排查流程
后端·ios·小程序·https·uni-app·iphone·swoole
2501_915909061 天前
iOS App 上架全流程详解:证书配置、打包上传、审核技巧与跨平台上架工具 开心上架 实践
android·ios·小程序·https·uni-app·iphone·webview
2501_915106321 天前
iOS 26 系统流畅度测试实战分享,多工具组合辅助策略
android·macos·ios·小程序·uni-app·cocoa·iphone
2501_915918411 天前
开发 iOS 应用全流程指南,环境搭建、证书配置与跨平台使用 开心上架 上架AppStore
android·ios·小程序·https·uni-app·iphone·webview
方君宇1 天前
iOS App小组件(Widget)显示LottieFiles动画和GIF图片
ios
Digitally1 天前
如何将 iPhone 联系人同步到 Mac
macos·ios·iphone