zoukankan      html  css  js  c++  java
  • app 测试要点

    APP功能测试#

    APP功能测试主要包含:

    • 业务逻辑测试:

      • 依据产品的设计文档,设计测试用例。
      • 再加上一些隐性的需求测试,比如产品文档中没有涉及到的。
    • 兼容性测试:

      • 系统版本:
        • Android:原生Android系统及定制版本。
        • ios:原生系统。
      • 分辨率:
        • 主要关注图片的分辨率,720 * 1280、1920 * 1080,一般公司会根据分辨处理图片。
      • 网络情况:2G、3G、4G、WiFi,比如在2G网络环境,应用会不会特别慢,或者卡死等。
    • 异常测试:

      • 热启动应用:应用前后台切换的过程。
      • 网络切换:WiFi --> 4G,应用应处于可用状态。
      • 中断恢复:WiFi --> 断网 --> 4G,处于下载中的应用,怎么处理?断点续传?还是等待WiFi下载?
      • 电话:比如正在看片片,突然来个电话,接完电话后,返回应用,此时的应用处于什么状态?
      • 信息:玩游戏中,弹出了一个消息提示,不应该影响游戏。或者查看消息后在回来,游戏处于什么状态。
    • 升级安装卸载测试:

      • 升级:临近版本升级(1.0 --> 1.1),跨版本升级。
      • 安装:
        • 首次安装。
        • 卸载安装。
        • 覆盖安装。
      • 卸载:正常卸载、下载一般终止下载,完事在下载。
    • 健壮性测试:

      • 手机资源消耗:CPU、RAM。
      • 流量消耗:数据流量、比如说图片加载消耗。可以进行压缩,图片压缩、数据压缩。
      • 崩溃恢复测试:APP闪退、系统结束执行时要做那些处理。

    app性能测试

    Android APP使用Python进行性能测试以及测试框架

    APP性能测试

    APP启动时间

    冷启动

    • 启动APP命令
    adb shell am start -W -n package/activity
    
    • 停止App命令
    adb shell am force-stop package
    
    • 获取某个APP的packageName和ActivityName的命令

      adb logcat | grep START
      

      然后打开你想获取packageName和ActivityName的应用即可。

    热启动

    • 启动APP命令和冷启动一样

    • 停止App命令

      # 模拟点击back键
      adb shell input keyevent 3
      

    自动化脚本的实现

    两种方案:

    • 获取命令执行时间,作为启动时间参考值

      class App(object):
          def __init__(self):
              self.content = ""
              self.startTime = 0
      
          # 启动APP
          def launch_app(self):
              cmd = 'adb shell am start -W -n org.chromium.webview_shell/.WebViewBrowserActivity'  # type: str
              self.content = os.popen(cmd)
      
          # 停止app
          @staticmethod
          def stop_app():
              # 冷启动停止的命令
              # cmd = 'adb shell am force-stop org.chromium.webview_shell'
              # 热启动停止的命令
              cmd = 'adb shell input keyevent 3'
              os.popen(cmd)
      
          # 获取启动时间
          def get_launched_time(self):
              for line in self.content.readlines():
                  if "ThisTime" in line:
                      self.startTime = line.split(":")[1]
                      break
              return self.startTime
          
      # 单次测试过程
          def test_process(self):   
              self.app.launch_app()
              time.sleep(5)
              elapsed_time = self.app.get_launched_time()
              self.app.stop_app()
              time.sleep(3)
              current_time = self.get_current_time()
              self.all_data.append((current_time, elapsed_time))
      
          # 多次执行测试过程
          def run(self):
              while self.counter > 0:
                  self.test_process()
                  self.counter = self.counter - 1
      
    • 在命令前后加上时间戳,以差值作为参考值

       # 单次测试过程
          def test_process(self):
              time_before_launch = int(time.time())
              self.app.launch_app()
              time_after_launch = int(time.time())
              time.sleep(5)
              # elapsed_time = self.app.get_launched_time()
              elapsed_time = time_after_launch - time_before_launch
              self.app.stop_app()
              time.sleep(3)
              current_time = self.get_current_time()
              self.all_data.append((current_time, str(elapsed_time)))
      
          # 多次执行测试过程
          def run(self):
              while self.counter > 0:
                  self.test_process()
                  self.counter = self.counter - 1
      

    可以多次计算启动时间值,并保存到本地csv文件,进行统计分析,求平均值等,第一次获得的值最好弃用。

    APP的CPU占用情况

    获取数据

    命令
    # windows系统的cmd中,用findstr来过滤字符,不能用grep。
    adb shell dumpsys cpuinfo | grep packagename
    
    脚本的代码实现
    # 单次测试过程
        def test_process(self):
            # window 下用findstr,Mac下用grep
            cmd = "adb shell dumpsys cpuinfo | findstr org.chromium.webview_shell"
            self.result = os.popen(cmd)
            cpu_value = 0
            for line in self.result.readlines():
                cpu_value = line.split("%")[0]
    
            current_time = self.get_current_time()
            self.all_data.append((current_time, cpu_value))
    

    流量

    命令
    • 获取进程ID指令

      # windows下用findstr代替grep,否则拿不到结果
      adb shell ps | grep packagename
      
    • 获取进程ID的流量指令

      # pid就是上面指令获取的进程ID
      adb shell cat /proc/pid/net/dev
      
    脚本实现
    # 单次测试过程
        def test_process(self):
            # 执行获取进程ID的指令 window 下用findstr,Mac下用grep
            cmd = "adb shell ps | findstr org.chromium.webview_shell"
            result = os.popen(cmd)
            # 获取进程ID
            pid = result.readlines()[0].split(" ")[5]
    
            # 获取进程ID使用的流量
            traffic = os.popen("adb shell cat /proc/" + pid + "/net/dev")
            for line in traffic:
                # 第一个网卡的数据
                if "eth0" in line:
                    # 将所有空行换成#
                    line = "#".join(line.split())
                    # 然后按#号进行拆分,获取到收到和发出的流量值
                    receive = line.split("#")[1]
                    transmit = line.split("#")[9]
                # 第二个网卡的数据
                elif "eth1" in line:
                    line2 = "#".join(line.split())
                    # 然后按#号进行拆分,获取到收到和发出的流量值
                    receive2 = line2.split("#")[1]
                    transmit2 = line2.split("#")[9]
    
            # 计算所有流量之和
            all_traffic = string.atoi(receive) + string.atoi(transmit) + string.atoi(receive2) + string.atoi(transmit2)
            # 按KB计算流量值
            all_traffic = all_traffic / 1024
            # 获取当前时间
            current_time = self.get_current_time()
            # 将获取到的数据存到数组中
            self.all_data.append((current_time, all_traffic))
    

    运行后的结果:

    timestamp,traffic
    2020-03-13 11:35:36,136535
    2020-03-13 11:35:41,136791
    2020-03-13 11:35:47,166458
    2020-03-13 11:35:52,264812
    2020-03-13 11:35:57,380940
    
    数据分析

    用最后一条流量值减去第一条流量值,得到本次测试运行时消耗掉的流量,然后和以往版本以及竞品进行对比,然后发现流量消耗的问题。

    电量

    获取电量
    adb shell dumpsys battery
    

    但是手机连接USB之后,会进入充电状态,测试电量需要在非充电的情况下,所以可以使用下面的命令切换充电状态

    # 切换到非充电状态,status = 2 代表充电,非2就是非充电
    adb shell dumpsys battery set status 1
    
    脚本实现
    # 单次测试过程
        def test_process(self):
            cmd = "adb shell dumpsys battery"
            result = os.popen(cmd)
    
            for line in result:
                if "level" in line:
                    power = line.split(":")[1]
    
            # 获取当前时间
            current_time = self.get_current_time()
            # 将获取到的数据存到数组中
            self.all_data.append((current_time, power))
    
        # 多次执行测试过程
        def run(self):
            cmd = "adb shell dumpsys battery set status 1"
            os.popen(cmd)
            while self.counter > 0:
                self.test_process()
                self.counter = self.counter - 1
                # 每5秒采集一次数据, 真实测试场景建议在0.5-1小时
                time.sleep(5)
    

    内存

    获取内存
    adb shell top
    # -d 刷新频率, 1 代表多久刷新一次,单位秒
    adb shell top -d 1
    # 输出到指定文件,测试完终止命令就可以分析指定文件
    adb shell top -d 1 > meminfo
    # 筛选指定包名,进行分析, windows上可以用type代替cat, findstr代替grep
    cat meminfo | grep packagename
    

    VSS - Virtual Set Size 虚拟消耗内存

    RSS - Resident Set Size 实际使用物理内存

    脚本实现

    脚本负责对命令行中测试后生成的meminfo文件进行分析,然后生成分析数据到csv文件,然后可以利用该csv文件进行图表绘制,内存数据获取时,建议测试时间长一点,方便分析使用过程中内存数据是否稳定,vss和rss分别分析。

    # 控制类
    class Controller(object):
        def __init__(self):
            # 定义收集数据的数组
            self.all_data = [("id", "vss", "rss")]
    
        # 分析数据
        def analyze_data(self):
            content = self.read_file()
            i = 0
            for line in content:
                if "org.chromium.webview_shell" in line:
                    print line
                    line = "#".join(line.split())
                    # 角标7和8不是固定的,要看你生成的meminfo文件里vss和rss出现的位置来确定
                    vss = line.split("#")[7].strip("K")
                    rss = line.split("#")[8].strip("K")
    
                    # 将获取到的数据存到数组中
                    self.all_data.append((i, vss, rss))
                    i = i + 1
    
        # 读取数据文件
        @staticmethod
        def read_file():
            mem_info = file("meminfo", "r")
            content = mem_info.readlines()
            mem_info.close()
            return content
    
        # 数据的存储
        def save_data_to_csv(self):
            csv_file = file('meminfo.csv', 'wb')
            writer = csv.writer(csv_file)
            writer.writerows(self.all_data)
            csv_file.close()
    
    
    if __name__ == '__main__':
        controller = Controller()
        controller.analyze_data()
        controller.save_data_to_csv()
    

    FPS&过度渲染

    FPS

    frames per second - 每秒的帧数

    Android中每一帧的绘制时间大于16秒,则可能会产生卡顿的现象,可以借助设置-开发者选项-GPU呈现模式分析,选择在屏幕上呈现为条形图,屏幕中横着的绿线就是16ms的基准线,高于绿线的条形图就是发生卡顿的帧

    过度渲染

    描述的是屏幕上的某个像素在同一帧的时间内被绘制了多次

    可以借助设置-开发者选项-调试GPU过度绘制-选择显示过度绘制区域,从最优到最差:蓝,绿,淡红,红。

  • 相关阅读:
    ADF中遍历VO中的行数据(Iterator)
    程序中实现两个DataTable的Left Join效果(修改了,网上第二个DataTable为空,所处的异常)
    ArcGIS api for javascript——鼠标悬停时显示信息窗口
    ArcGIS api for javascript——查询,然后单击显示信息窗口
    ArcGIS api for javascript——查询,立刻打开信息窗口
    ArcGIS api for javascript——显示多个查询结果
    ArcGIS api for javascript——用图表显示查询结果
    ArcGIS api for javascript——查询没有地图的数据
    ArcGIS api for javascript——用第二个服务的范围设置地图范围
    ArcGIS api for javascript——显示地图属性
  • 原文地址:https://www.cnblogs.com/hanfe1/p/14605074.html
Copyright © 2011-2022 走看看