Mutation testing needs source code.

Often, you get an APK.

Closed source, closed door.

Source isn’t always available — say, to an outsourced testing service. Source-level tools stall.

app/src/
No source tree
.apk
Just one file
Introducing
MutAPK
Mutants, straight from the APK

Built beside MDroid+ for source code — both from 38 operators grounded in 262 real fault types.

.apk
smali/com/fsck/k9/activity/Accounts.smali
invoke-virtual {p0}, Lcom/fsck/k9/…;->getIntent()
new-instance v1, Landroid/content/Intent;
const-class v3, Lcom/fsck/k9/activity/ImportActivity;const-class v3, Lcom/fsck/k9/activity/ExportActivity;
invoke-direct {v1, v2, v3}, …/Intent;-><init>
invoke-virtual {p0, v1}, …->startActivity
const-string v4, "account_uuid"
invoke-virtual {v1, v4, v5}, …->putExtra
AndroidManifest.xml
<uses-permission …INTERNET"/>
01Decode
02Profile
03Mutate
04Rebuild & sign

Open the APK.

APKTool decodes the app into SMALI — Android’s bytecode, as text — plus its resources.

Find failure points.

The operator catalog, rewritten as SMALI rules, builds a Potential Failure Profile.

DifferentActivityIntentDefinition NullIntent InvalidKeyIntentPutExtra MissingPermissionManifest
34operators in MutAPK
32shared with MDroid+

One fault per copy.

Each location is mutated in its own copy of the decoded app, in parallel.

Back to APKs.

Every mutant is rebuilt and signed into an installable APK, with a log of what changed.

Same fault. Two levels.

DifferentActivityIntentDefinition: launch the wrong screen.

MDroid+JAVA SOURCE
- new Intent(main.this, ImportActivity.class);
+ new Intent(main.this, ExportActivity.class);
MutAPKSMALI IN THE APK
- const-class v3, L…/activity/ImportActivity;
+ const-class v3, L…/activity/ExportActivity;
55 open-source apps · MutAPK vs. MDroid+
0.0%
faster than MDroid+ to mutate and build, end to end
0.04%non-compilable mutants per app
69,742functional mutants · 8,579 for MDroid+
Java · Kotlin · DartAndroid’s native languages, one tool

Source or APK? Each has its edge.

MDroid+source code
MutAPKAPK
Mutants per app (avg.)
167
1.3k+
Non-compilable (avg.)
0.56%
0.04%
Trivial — crash on launch (avg.)
2.42%
9%
Mutate + build time
baseline
87.2% faster

Enabling Mutant Generation for Open- and Closed-Source Android Apps

Camilo Escobar-Velásquez · Mario Linares-Vásquez · Gabriele Bavota · Michele Tufano · Kevin Moran · Massimiliano Di Penta · Christopher Vendome · Carlos Bernal-Cárdenas · Denys Poshyvanyk
TSE 2020 · IEEE Transactions on Software Engineering