Abstract

  • Background: Functional correctness很重要,但难测,传统人测,工具只测crash bugs
  • 目的: 利用independent view properties,从种子测试中生成大量property-preserving tests,用来确保具体的app view properties不因为无关操作而改变
  • 成果: 工具GENIE
    - 能无需人工提供测试或者oracles,自动发现functional bugs
    - Q: the detected functional bugs are diverse, thus general and not limited to specific functional properties
  • 实验
    - 数据: 12个Apps
    - 结果:
    - 检测到33个新functional bugs,都经过开发者确认,其中21个被修复
    - 检测到26个crash bugs,其中24个被确认,14个fixed

Intro

背景:

  1. GUI测试工具,例如Monkey, Sapienz, Stoat: 仅能测crash bugs
  2. off-the-shell test automation framework, 如Expresso, Robotium, Appium, 能够自动运行测试,但是需要人为设计验证方式
  3. 静态分析工具,如Lint, Find Bugs, Infer等,能找到广义上的编码bug,但是找不到functional error

本文认为,编码的主要困难是缺失test oracles, 进而缺乏编码者的详细功能描述。

已有解决方法:

  1. 使用已有的单元测试中的codified oracles
  2. 为特定app功能手动定义oracle

本文提出了independent view fuzzing的概念,面向off-the-shell Android Apps, 不需要人为提供任何额外的testing 或者oracles,也不限于测试具体的功能

挑战:

  1. 系统生成属性不变性测试变体 the system generation of app property preserving mutants
    • 分析在种子测试执行期间的GUI pages和layouts来推测independent views
    • 使用一个GUI transitional model来系统性地生成独立事件
  2. 识别属性被错误地改变了 the precise identification of property violations
    • 将每个mutant test与对应的种子测试的GUI效果进行对比
    • 本文认为,由于插入的事件是相互独立的,对应的种子测试的GUI效果应该在任何mutant test执行中保持不变
    • the inserted events should add, but not remove GUI effects from the execution

具体实现:

  1. GUI transitional model
  2. infers independent views from random seed tests
  3. 1+2 generate property-preserving mutants and executes them
  4. 将变体与seed test做对比,报告潜在functional bugs

Illustrative Example

一般分析测试一个App需要四步:

  1. mining a GUI transitional model from this APP
  2. 生成一系列随机种子测试+执行每个种子测试来确认independent views
    • 种子测试也能来自人工或者已经存在的其他工具
  3. 生成mutant test+执行
  4. 对比每个种子测试和其mutants来确认property violation,报告潜在bugs

Proj THUDBFuzz Paper Reading: Automated Functional Fuzzing of Android Apps_字符串

Step 1:
由GUI transitonal model(GUI转移模型)可以画一个状态图,图中节点是一个GUI state,是根据结构相似性划分的。边则是标识一种用于转移的行为。
Q: 如果layout相同那么就算是同样的状态??不去管例如字体大小被异常更改,按钮被错误disable之类的错误?
Q2: 在后面这些状态有什么用?这些边又是怎么用的,用来推测如何回到当前状态?可是只有layout-或者说GUI tree是一致的?

Step 2:
生成一系列随机种子测试,在执行种子测试的时候,检查GUI layout,主要着重检查Group view(比如ListView或者RecyclerView)中的independent view(似乎就是inactive child view)。也因此一个尤其重要的信息是active view。

Q: 种子测试到底是如何生成的?例如启动之后看到一个界面这样?还是从A界面点击弹出图片这样?
Q2: 那种点击一个按钮后,其它按钮暂时不能点击直到完成编辑那种都测不了?也就是,只要对其他的siblings有任何微小扰动就测不了了?
Q3: 只是检测种子测试中的inactive view?种子测试本身不是还不完备么?

Step 3:
从seed test中挑一个pivot layout,一个inactive view,然后对这个inactive view操作,操作之后再使用transitional model将状态还原回原始状态。

Q: 令人懵逼,Expected和actual如何体现bug了?倒不如说作为用户看起来actual更好吧。

Step 4:
要求seed test中的元素要在mutant test中出现

Q: 如果我触发了删除功能??
Proj THUDBFuzz Paper Reading: Automated Functional Fuzzing of Android Apps_子节点_02

符号定义

Proj THUDBFuzz Paper Reading: Automated Functional Fuzzing of Android Apps_oracle_03

这里,经过一定程度的简化,两个layout相等被定义为集合中的view的类型和层级一致。

State coverage-optimized model mining

GENIE有两个选择事件e的策略:

  1. 依据评分:
    Proj THUDBFuzz Paper Reading: Automated Functional Fuzzing of Android Apps_子节点_04
    该评分希望选择执行频率较少或者能够转移到具有较多new events的layout的事件e

  2. 为每种e.type分配一个先验概率,然后按此概率随机选择

这两种策略是先依据评分,等到saturation,也即达到瓶颈之后,再用随机选择策略

Inferring Independent Views from Seed Tests

首先定义Independent from,若Group(wi)代表wi所对应的Group view,那么,若以下条件之一成立:

  1. Group(w1)≠Group(w2)
  2. Group(w1)=Group(w2)但w1和w2是sibling views而且w1.type = w2.type
    就认为w1 independent from w2
    Q: 如果是linearlayout,不能保证同类型兄弟无关?

接着定义active view:
如果事件e满足e.r(l) = wi且e被才执行了,那么wi就是Active状态,且\(h_l[Group(w_i)]=w_i\)。当然,当新的e.r(l)=wj在这一group view发生之后,wi就inactive且被替代了
Q: 整个group view也可以被inactive吧?

由于这样的定义,不属于任何group view的view就是永远inactive的。
此外,GENIE还会做execution traces上active关系的传递,具体方法是对于任意两个无关但都能执行事件e的layout l和l',若w1是l中e的recevier view,w2是l'中e的接收view,那么就认为w1与w2相似,把active关系过继

实际上这一策略执行时还要考虑更多:

  1. 程序试着把所有view都化成字符串,如果w1的字符串恰好匹配l'中的其他view w2,就认为w2是w1的similiar view
    • Q: 图片的?
  2. 如果没能在1匹配上,那么就把w1和子节点的type info拿来找string edit distance最小的w2.
    • Q: 没有限制允许的最大距离?分词么??为啥扁平化
      Proj THUDBFuzz Paper Reading: Automated Functional Fuzzing of Android Apps_sed_05

Proj THUDBFuzz Paper Reading: Automated Functional Fuzzing of Android Apps_sed_06

Mutant Test Generation and Execution

  1. 定义independent event trace
    • 新的trace是在inactive view上工作
    • Q: 难道不会访问本来是active,但是由于操作变为inactive?
    • Q: 测试范围变小?
  2. 定义connect with, E1 can connect with E2 iff
    • 存在E2中的第一个事件e2的receiver view,与E1的last layout中的receiver view相似

具体寻mutant算法
Proj THUDBFuzz Paper Reading: Automated Functional Fuzzing of Android Apps_字符串_07
Proj THUDBFuzz Paper Reading: Automated Functional Fuzzing of Android Apps_oracle_08

GUI-based Oracle Checking

Proj THUDBFuzz Paper Reading: Automated Functional Fuzzing of Android Apps_oracle_09
Proj THUDBFuzz Paper Reading: Automated Functional Fuzzing of Android Apps_sed_10
Proj THUDBFuzz Paper Reading: Automated Functional Fuzzing of Android Apps_sed_11

Implementation

Seed Test Generation

  1. 利用events权重,做state coverage optimized mining
  2. 利用motif events-比如打开摄像之后,一般人们更多尝试摄像而不是点击cancel
    Q: 其实我更多点cancel,因为摄像很容易误触发。。。

Mutant Generation and Execution

  1. breath-first random search
  2. 为了避免太多路径,最多2 self loop + 最多3 independent views
  3. 删除了transition model中的redundant events
    • 一对状态中只保留一个event 通路?

Bug report reduction and Visualization

  1. bug report reduction
    • 删除冗余的
      - 是通过string比较
    • 只保留出现一次的error
      - 认为suspicious errors with less occurrences are more likely to be true errors
      - bugs as deviant behaviour
  2. web-based bug report visualization tool

Evaluation

集中在回答以下四个问题:

  1. 能否找到真实的functional bugs?
  2. 能增加code coverage吗?
  3. bug精确度
  4. 找到的functional bugs的类型?