没有手机也没有模拟器:我在服务器上真跑安卓界面测试

教程 2026-09-29 20:04 · 61 次阅读 ·安卓,测试,踩坑,实测

服务器上跑安卓界面测试的实测数字:正常代码 6 个用例全过,注掉一行立刻红了 2 个

一句话结论:不用手机、也不用模拟器,服务器上就能把安卓界面真跑起来。我用一套叫 Robolectric 的工具(把安卓系统搬进电脑的 Java 环境里运行的东西),6 个用例 17.8 秒跑完。为了确认它不是摆设,我把代码注掉一行,6 个用例立刻红了 2 个。

背景

我改了几行安卓界面的代码,只想知道一件事:一打开会不会白屏。

服务器上装不了安卓模拟器。模拟器需要一块叫 KVM 的硬件加速能力,这台机器没有——ls /dev/kvm 回的是 No such file or directory。

老办法是编译出安装包、传到手机、手点一遍,一轮十几分钟。一天改十次,时间全耗在传包上。

Robolectric 走的是另一条路:把真实的安卓系统搬到电脑里跑,不需要虚拟硬件。界面代码照样执行,抛异常就原样打印出来。

做法

1. 让下载走国内镜像。 编译工具默认去国外取包,慢。加一个配置文件 ~/.m2/settings.xml:

<mirror>
  <id>aliyun-public</id>
  <mirrorOf>central</mirrorOf>
  <url>https://maven.aliyun.com/repository/public</url>
</mirror>

同一个包(27,018 字节),实测国外仓库 2.22 秒,国内镜像 0.058 秒,差 38 倍。

2. 真安卓框架只下一次。 Robolectric 会拉一个 150,646,262 字节(144 MB)的包,里面是安卓 14 的真实现。下好之后打开离线开关、指定放包的目录,以后每次跑都不联网。

3. 卡我最久的坑:编译工具不认安卓的包格式。 报错原文:

The following artifacts could not be resolved:
androidx.test:monitor:aar:1.6.1,
androidx.test.espresso:espresso-idling-resource:aar:3.5.1

安卓的库有两种包:jar 是普通 Java 包,aar 是安卓专用格式(里面还裹着一层 jar)。编译工具只认 jar,看到 :aar: 就停。这两个包在国内的公共镜像里也没有,我去取,返回 404。

两步解决。一是把下载源换成 Google 的安卓仓库(国内也有它的镜像:同一个包 0.054 秒,直连 Google 0.50 秒)。二是把 aar 里那层 jar 掏出来装到本地:我下载的那个 aar 是 100,803 字节,里面的 classes.jar 是 116,335 字节,装进去编译就过了。

4. 用例写什么。 不用一上来写几十个,先写最贵的几条。我写了 6 条:全新安装必须出登录页;老版本留下的登录状态必须作废;登录页单独构建时输入框和按钮都在;切到「登录已有账号」时验证码那一行要收起来;邮箱填错要给人话提示;密码太短要拦住。

每条用例里都有一句判断(叫断言):界面上必须出现某个控件,没有就算失败。判断不过时,我把界面上所有控件按层级打出来一起报错:

DecorView
  ActionBarOverlayLayout
    FrameLayout
      LinearLayout
        TextView「AI 记账」
        Button「登录 / 注册」
        TextView「本月支出」「0」

少了哪一层、哪个按钮没挂上,看这段就够了,不用猜。

5. 跑起来。 6 个用例 17.8 秒;整条命令(同步源码 + 编译 + 跑)25 到 29 秒。

实测:它真能抓出问题

我把挂载登录页的那一行注掉(rootFrame.addView(gateView, ...)),再跑一遍。

6 个用例红了 2 个,17.79 秒出结果。报错文字是「白屏了:界面里既没有登录页顶栏,也没有注册按钮」和「没回到登录页」,后面跟着整棵界面树。

这行的作用是把登录页盖在账本界面上。注掉以后,没登录的人直接进到账本界面,登录页等于不存在。手点的时候这种问题容易滑过去——点进去反正能看见东西;测试不放它过。

结论与踩坑

  1. 没有硬件加速就别碰模拟器。 ls /dev/kvm 回 No such file or directory,直接换成在电脑上跑的这条路。
  2. 144 MB 的框架包单独指一个目录、开离线开关,一次下好反复用,不用每次联网。
  3. 报错里带 :aar:,就去 Google 的仓库取,再掏里面的 classes.jar。
  4. 断言要带上界面树。 只判断「没崩」不够:白屏、按钮忘了挂上去,程序都不会报错,只有把这些控件写进判断里才拦得住。
  5. 它管不了真机。 拍照、推送、真实网速还得上手机;我验的是界面能不能正常建出来。同一份代码前后跑两遍对结果,是这次最有用的习惯。

继续看

全部 →