51Testing软件测试论坛

 找回密码
 (注-册)加入51Testing

QQ登录

只需一步,快速开始

微信登录,快人一步

查看: 608|回复: 1
打印 上一主题 下一主题

[原创] 大神带你如何获得代码覆盖率(下)

[复制链接]
  • TA的每日心情
    无聊
    2 小时前
  • 签到天数: 933 天

    连续签到: 5 天

    [LV.10]测试总司令

    跳转到指定楼层
    1#
    发表于 2023-1-31 10:24:15 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
    一些bug
      jacoco.exec
    W/System.err: java.io.FileNotFoundException: /jacoco.exec (Read-only file system)



    这应该是JaCoCo库包的一些问题,由于Android平台的特殊性导致的,JaCoCo的开发者也没提出明确的解决方案。但是,不影响我们这里要求的功能。
      切页面闪退
      网上一些例子中会出现切换Activity,应用闪退的问题。我一开始也是照着这个例子来的,也出现了这个问题,分析是代码思路有问题,一是只有由Instrument开启的Activity才设置了listener,二是,切换Activity会调用finish方法,直接就结束了应用。反正我一通删删删之后,可以正常运行了。
      Instrument命令无反应
      可能是targetPackage配置的问题,有些时候AndroidManifest.xml里设置的package不一定是实际安装时应用的package名。
    1. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    2.     package="org.glucosio.android">
    3. ······
    4.     <instrumentation
    5.         android:name="test.JacocoInstrumentation"
    6.         android:handleProfiling="true"
    7.         android:label="CoverageInstrumentation"
    8.         android:targetPackage="org.glucosio.android.daily" />//实际安装的包名变化了
    9. </manifest>
    复制代码


    比如这个例子,在构建文件build.gradle里面对debug和release版本的包名做了修改,所以,实际安装的时候,应用对应的包名并不是AndroidManifest.xml里配置的那样。
      解决方案就是编译完知道真实的包名后再配置,还有,在AS里面,targetPackage属性无论配置正确与否都会飘红报错,但是,这并不影响编译运行。
      启动应用闪退
      在设置了假入口类,并通过Instrument启动的时候,可能会遇到应用启动闪退的情况,这是因为很多应用会改写Theme,然后Fake入口类继承的真实入口类需要对应的Theme配置,这里出现了配置,或者资源不兼容的情况,造成了闪退。
    1. <activity
    2.     android:name=".activity.SplashActivity"
    3.     android:label="@string/app_name"
    4.     android:theme="@style/SplashTheme">
    5.     <intent-filter>
    6.         <action android:name="android.intent.action.MAIN" />

    7.         <category android:name="android.intent.category.LAUNCHER" />
    8.     </intent-filter>
    9.     <meta-data
    10.         android:name="android.app.shortcuts"
    11.         android:resource="@xml/shortcuts" />
    12. </activity>

    13. <activity
    14.     android:name="test.InstrumentedActivity"
    15.     android:label="@string/app_name"
    16.     android:theme="@style/SplashTheme">
    17.     <meta-data
    18.         android:name="android.app.shortcuts"
    19.         android:resource="@xml/shortcuts" />
    20. </activity>
    复制代码


    上面例子里的InstrumentedActivity就是继承了真实入口类SplashActivity的Fake入口类。
      解决方案,继承一切真实入口类可以被继承的属性,比如theme什么的,这样在FakeActivity实例化加载资源的时候,可以避免出现资源申请失败的问题,防止出现应用启动闪退的现象。
      进阶
      本方法的主要功能就是generateCoverageReport,所以,何时调用,是最主要的问题。
      最理想的状态,在测试退出的时候调用,写入一次,节省时间,性能也高。但是大多数场景下,这种情况是行不通的。以下我整理几个场景,以及解决方案,提供参考:
      入口类是一次性的,比如加载页面、广告页面等等;
      入口类显性调用,指定了Activity跳转的目标类名,无法重回我们重写的Fake入口类。
      以下可以提供一些解决方案:
      Application的onTerminate()方法重写,在这里打桩调用记录函数,但是Application的生命周期监听在不同设备上有区别,貌似只在模拟器上有用;
      BaseActivity的onDestroy()方法重写,一般大型的Android项目都会有一个自定义的顶级Activity,重写销毁监听函数,在这里打桩,这样每次Activity退出都会记录一次数据,当然,这也是在其子类重写但没有覆盖父类这个操作的情况下;
      MainActivity的onDestroy()方法重写,这种方法是最保险的方法,这里的MainActivity指代应用首页对应的Activity。虽然,很多时候这个MainActivity不一定是入口类,但是只要在测试的时候能够最终回到MainActivity所在的页面,然后通过Android的回退键退出,调用onDestrooy()记录数据。
      总结
      通过JaCoCo记录覆盖率的核心是调用记录函数,重点是保证记录函数能被成功调用。所以,Instrument也好,Service也好,直接写在原来的Activity里也好,目的都是成功记录数据。没有通用的万能方法,还是得因地制宜。在复杂的项目环境下,还是需要对原生代码进行适当的打桩修改的。




    分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
    收藏收藏
    回复

    使用道具 举报

  • TA的每日心情
    开心
    7 小时前
  • 签到天数: 443 天

    连续签到: 39 天

    [LV.9]测试副司令

    2#
    发表于 2023-2-28 10:17:47 | 只看该作者
    这里是有使用工具,还是直接通过源码
    回复 支持 反对

    使用道具 举报

    本版积分规则

    关闭

    站长推荐上一条 /1 下一条

    小黑屋|手机版|Archiver|51Testing软件测试网 ( 沪ICP备05003035号 关于我们

    GMT+8, 2024-4-19 12:10 , Processed in 0.066133 second(s), 22 queries .

    Powered by Discuz! X3.2

    © 2001-2024 Comsenz Inc.

    快速回复 返回顶部 返回列表