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


This project was created by the Software Engineering Maintenance and Evolution Research Unit (SEMERU) at the College of William & Mary, in collaboration with The Software Design Lab at the Universidad de los Andes, The University of Sannio, REVEAL at the The University of Lugano, and the Miami University, Oxford, OH. The major goal of the project is to help mobile application developers and testers improve the quality of their test suites. This project empirically derived a set of 38 Android-specific mutation operators which can be automatically seeded into a target application and analyzed on a set of test cases.


Tools



Pitest Wrapper

Overview » View code »



Fault Taxonomy


The black rectangle in the bottom-right part of Figure 1 reports the number of documents tagged as false positive or as un- clear. e other rectangles—marked with the Android and/or with the Java logo—represent the 14 high-level categories that we identified. Categories marked with the Android logo (e.g., Activities and Intents) group together Android-specific bugs while those marked with the Java logo (e.g., Collections and Strings) group bugs that could affect any Java application. Both symbols together indicate categories featuring both Android-specific and Java-related bugs (see e.g., I/O).

Fault-Taxonomy

Mutant Operators


These operators were implemented in Java (for source code-based mutations in MDroid+) and SMALI (for APK-based mutations in MutAPK). The locations for the mutations are identified by using a Potential Failure Profile (PFP). The PFP lists code locations that could be modified to inject a mutation. The locations of the analyzed apps which can be source code statements, XML tags or locations in other resource files that can be the source of a potential fault, given the faults catalog from the taxonomy.

  • MDroid+
  • Available in MDroid+
  • MutAPK
  • Available in MutAPK
  • AST
  • Changes are done directly over AST
  • Text
  • Changes are done over resource files


Category 1 - Activity/Intents
ActivityNotDefined
MDroid+ MutAPK Text
Description:

Delete an activity < android:name="Activity" /> entry in the Manifest file

How to find a mutant of this kind:

Provide a sequence of events that visits the removed activity



DifferentActivityIntentDefinition
MDroid+ MutAPK AST
Description:

Replace the Activity.class argument in an Intent instantiation

How to find a mutant of this kind:

Provide a sequence of events that exercises the modified intent



InvalidActivityName
MDroid+ MutAPK Text
Description:

Randomly insert typos in the path of an activity defined in the Manifest file

How to find a mutant of this kind:

Provide a sequence of events that visits the modified activity



InvalidKeyIntentPutExtra
MDroid+ MutAPK AST
Description:

Randomly generate a different key in an Intent.putExtra(key, value) call

How to find a mutant of this kind:

Provide a sequence of events that exercises the modified intent



InvalidLabel
MDroid+ MutAPK Text
Description:

Replace the attribute "android:label" in the Manifest file with a random string

How to find a mutant of this kind:

Provide a sequence of events that visits the modified activity and checks for the activity name



NullIntent
MDroid+ MutAPK AST
Description:

Replace an Intent instantiation with null

How to find a mutant of this kind:

Provide a sequence of events that exercises the modified intent



NullValueIntentPutExtra
MDroid+ MutAPK AST
Description:

Replace the value argument in an Intent.putExtra(key, value) call with new Parcelable[0]

How to find a mutant of this kind:

Provide a sequence of events that exercises the modified intent



WrongMainActivity
MDroid+ MutAPK Text
Description:

Randomly replace the main activity definition with a different activity

How to find a mutant of this kind:

Check at app start for content expected to appear on launching




Category 2 - Connectivity
BluetoothAdapterAlwaysEnabled
MDroid+ MutAPK AST
Description:

Replace a BluetoothAdapter.isEnabled() call with "true"

How to find a mutant of this kind:

Call the method that has the bluetooth status validation while the adapter is turned off



NullBluetoothAdapter
MDroid+ MutAPK AST
Description:

Replace a BluetoothAdapter instance with null

How to find a mutant of this kind:

Exercise the method where the mutation was performed




Category 3 - GUI
BuggyGUIListener
MDroid+ AST
Description:

Assign null to a listener

How to find a mutant of this kind:

Provide a sequence of events that exercise the GUI component related to the modified "onClickListener"



FindViewByIdReturnsNull
MDroid+ MutAPK AST
Description:

Assign a variable (returned by Activity.findViewById) to null

How to find a mutant of this kind:

Execute a sequence of test steps that covers the branch where the nulled variable is used



InvalidColor
MDroid+ MutAPK Text
Description:

Randomly change colors in layout files

How to find a mutant of this kind:

Perform visual regression over GUI for a sequence of events that visits the activity where the modified color is used



InvalidIdFindView
MDroid+ MutAPK AST
Description:

Replace the id argument in an Activitity.findViewById call

How to find a mutant of this kind:

Execute a sequence of test steps that covers the branch where the modified variable value is used



InvalidViewFocus
MutAPK AST
Description:

Randomly focus a GUI component

How to find a mutant of this kind:

TODOs



ViewComponentNotVisible
MDroid+ MutAPK AST
Description:

Set visible attribute (from a View) to false

How to find a mutant of this kind:

Define a set of steps thar visits the activity where the component should appear, and then check existence of component




Category 4 - Database
ClosingNullCursor
MDroid+ MutAPK AST
Description:

Assign a cursor to null before it is closed

How to find a mutant of this kind:

Call the method where the modification was done, check for correct handling of error



InvalidIndexQueryParameter
MDroid+ MutAPK AST
Description:

Randomly modify indexes/order of query parameters

How to find a mutant of this kind:

Call the modified method and checks the correct handling of the error or empty result



InvalidSQLQuery
MDroid+ MutAPK AST
Description:

Randomly mutate a SQL query

How to find a mutant of this kind:

Call the modified method, checks for correct handling of error




Category 5 - General Programming
InvalidDate
MDroid+ MutAPK AST
Description:

Set a random Date to a date object

How to find a mutant of this kind:

Check integrity of data related to the modified date



InvalidMethodCallArgument
AST
Description:

Randomly mutate a method call argument of a basic type

How to find a mutant of this kind:

Call the modified method, check the correct handling of the error



NotSerializable
MDroid+ AST
Description:

Select a serializable class, remove "implements Serializable"

How to find a mutant of this kind:

Identify an element from the modified class, and try to exercise its serialization



NullMethodCallArgument
MutAPK AST
Description:

Set null to a method call argument

How to find a mutant of this kind:

Call the modified method and check for correct handling of the error




Category 6 - I/O
InvalidFilePath
MDroid+ MutAPK AST
Description:

Randomly mutate paths to files

How to find a mutant of this kind:

Call for modified file usage and exercise it. Check for correct handling of the error



NullInputStream
MDroid+ MutAPK AST
Description:

Assign an input stream to null before it is closed

How to find a mutant of this kind:

Call the modified method, checks for the correct handling of the error



NullOutputStream
MDroid+ MutAPK AST
Description:

Assign an output stream to null before it is closed

How to find a mutant of this kind:

Call the modified method, checks for the correct handling of the error




Category 7 - Data
InvalidURI
MDroid+ MutAPK AST
Description:

If URIs are used internally, randomly mutate the URIs

How to find a mutant of this kind:

Call for modified URI usage and exercise it. Check for correct handling of the error




Category 8 - Non-Functional Requirements
LengthyBackEndService
MDroid+ MutAPK AST
Description:

Inject large delay right-after a call to a back-end service. Current implementation add 10 second delay since a 5 second delay produces an ANR

How to find a mutant of this kind:

Check for correct handling of ARN



LenghtyGUICreation
MDroid+ MutAPK AST
Description:

Insert a long delay (\ie Thread.sleep(..)) in the creation GUI thread. Current implementation add 10 second delay since a 5 second delay produces an ANR

How to find a mutant of this kind:

Check for correct handling of ARN



LenghtyGUIListener
MDroid+ MutAPK AST
Description:

Insert a long delay (\ie Thread.sleep(..)) in a GUI Listener

How to find a mutant of this kind:

Check for correct handling of ARN



LongConnectionTimeOut
MDroid+ MutAPK AST
Description:

Increase the time-out of connections to back-end services

How to find a mutant of this kind:

Check for correct handling of ARN



OOMLargeImage
MDroid+ MutAPK AST
Description:

Increase the size of bitmaps by explicitly setting large dimensions. Current implementation modifies dimension into a size no device could fit

How to find a mutant of this kind:

Check for correct handling of oversized image




Category 9 - Android Programming
MissingPermissionManifest
MDroid+ MutAPK Text
Description:

Select and remove an <uses-permission /> entry in the Manifest file

How to find a mutant of this kind:

Define a sequence of events that exercise the usage of the removed permission



NotParcelable
MDroid+ AST
Description:

Select a parcelable class, remove "implements Parcelable" and the @override annotations

How to find a mutant of this kind:

Identify an element from the modified class, and try to use it inside a intend as parameter



NullGPSLocation
MDroid+ MutAPK AST
Description:

Inject a Null GPS location in the location services

How to find a mutant of this kind:

Exercise the usage of the modified location variable



SDKVersion
MDroid+ MutAPK Text
Description:

Randomly mutate the integer values in the SdkVersion-related attributes

How to find a mutant of this kind:

Executes the app in a not-previously supported OS version



WrongStringResource
MDroid+ MutAPK Text
Description:

Select a <string /> entry in /res/values/strings.xml file and mutate the string value

How to find a mutant of this kind:

Identify a sequence of step that reach the activity where modified string is used and check for the expected value




Category 10 - BackEnd Services
NullBackEndServiceReturn
MDroid+ MutAPK AST
Description:

Assign null to a response variable from a back-end service

How to find a mutant of this kind:

Check for correct error handling






Empirical Study



Apps used in Studies


App Name Category Package Name Version ESEC/FSE'17 TSE'20
A2DP Volume Transportation a2dp.Vol 2.8.11
AardDictionary Books & Reference aarddict.android 1.4.1
FTP Server Tools be.ppareit.swiftp_free 2.2
Bites Lifestyle caldwell.ben.bites 1.3
Battery Circle Tools ch.blinkenlights.battery 1.81
KeePassDroid Tools com.android.keepass 1.9.8
LolcatBuilder Entertainment com.android.lolcat 2
SpriteMethodTest Sample com.android.spritemethodtest 1
Alarm Clock Tools com.angrydoughnuts.android.alarmclock 1.7
Translate Tools com.beust.android.translate 1.6
Manpages Productivity com.chmod0.manpages 1.51
BookCatalogue Productivity com.eleybourn.bookcatalogue 3.8
Mileage Finance com.evancharlton.mileage 3.1.1
Auto Answer Tools com.everysoft.autoanswer 1.5
Amazed Casual com.example.amazed 2.0.2
RandomMusicPlayer Music com.example.android.musicplayer 1
AnyCut Productivity com.example.anycut 0.5
HNDroid News & Magazines com.gluegadget.hndroid 0.2.1
SpriteText Sample com.google.android.opengles.spritetext -
Triangle Sample com.google.android.opengles.triangle -
Photostream Media & Video com.google.android.photostream 1.1
Multi SMS Communication com.hectorone.multismssender 2.3
World Clock Tools com.irahul.worldclock 0.6
SyncMyPix Media & Video com.nloko.android.syncmypix 0.15
Jamendo Music com.teleca.jamendo 1.0.6-legacy
Yahtzee Casual com.tum.yahtzee 1
Sanity Communication cri.sanity 2.11
Mirrored News & Magazines de.homac.Mirrored 0.2.3
FileExplorer Productivity edu.killerud.fileexplorer 1
WeightChart Health & Fitness es.senselesssolutions.gpl.weightchart 1.0.4
SoundBoard Sample hiof.enigma.android.soundboard 1
ADSdroid Books & Reference hu.vsza.adsdroid 1.2
myLock Tools i4nc4mp.myLock 42
LockPatternGenerator Tools in.shick.lockpatterngenerator 2
MunchLife Entertainment info.bpace.munchlife 1.4.2
aGrep Tools jp.sblo.pandora.aGrep 0.2.1
CountdownTimer Tools net.everythingandroid.timer 1.1.0
LearnMusicNotes Puzzle net.fercanet.LNM 1.2
NetCounter Tools net.jaqpot.netcounter 0.14.1
TippyTipper Finance net.mandaria.tippytipper 1.1.3
BaterryDog Tools net.sf.andbatdog.batterydog 0.1.1
Bomber Casual org.beide.bomber 1
Dialer2 Productivity org.dnaq.dialer2 2.9
FrozenBubble Puzzle org.jfedor.frozenbubble 1.12
aLogCat Tools org.jtb.alogcat 2.6.1
AnyMemo_135 Education org.liberty.android.fantastischmemo 8.3.1
PasswordMakerPro Tools org.passwordmaker.android 1.1.7
Blokish Puzzle org.scoutant.blokish 2
ZooBorns Entertainment org.smerty.zooborns 1.4.4
Wordpress_394 Productivity org.tomdroid 0.5.0
MyExpenses Finance org.totschnig.myexpenses 1.6.0
ImportContacts Tools org.waxworlds.edam.importcontacts 1.1
Wikipedia Books & Reference org.wikipedia 1.2.1


Operators Across Tools




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


RQ1. Are the mutation operators (available for Java and Android apps) representative of real bugs in Android apps?

MDroid+ and MutAPK outperformed the other six mutation tools by achieving the highest coverage both in terms of bug types and bug instances. However, the results shows that Android- specific mutation operators should be combined with classic operators to generate mutants that are representative of real faults in mobile apps.

Fault-Taxonomy

Bug Types not Covered by Taxonomy

RQ2. What is the rate of non-compilable (e.g., those leading to failed compilations), trivial (e.g., those leading to crashes on app launch), equivalent, and redundant mutants produced by the studied tools when used with Android apps?

First figure depicts the achieved results as percentage of Stillborn Mutants, the second figure presents the percentage of Trivial Mutants generated by each tool on each app. Third figure shows that on average, 67, 207, 1.3k+, 904, 2.6k+, and 1.5k+ mutants were generated by MDroid+, MutAPK-Shared, MutAPK, Major, PIT, and muDroid, respectively for each app. The larger number of mutants generated by PIT is due in part to the larger number of mutation operators available for the tool.

fse-generated-mutants
fse-trivial-mutants
fse-nc-mutants

As for the generation of mutants, all the analyzed tools (Major, Pit, muDroid, MDroid+, MutAPK) generated a relatively low rate of trivial mutants, with muDroid being the worst with a 11.8% average rate of trivial mutants. Additionally, no equivalent mutants were found for any tool,according to a hash-based comparison between the original APKs and the corresponding mutants. Nevertheless, 4 tools (MutAPK, MutAPK-Shared, PIT and muDroid) generated redundant mutants, with muDroid being the worst with a 6.55% of total redundant mutants.

RQ3. What are the major causes for non-compilable, trivial, equivalent, and redundant mutants produced by the mutation testing tools when applied to Android apps?

The performed analysis indicate that the PIT tool outperforms others in terms of ratio between non-compilable and generated mutants, because it does not generate any non-compilable mutant. However,MDroid+ and MutAPK provide Android-specific mutations, which make the tools (i.e.,Pit, MDroid+, MutAPK) complementary for mutation testing of Android apps. MDroid+ and MutAPK generated the lowest rate of both non-compilable and trivial mutants (when compared to Major and muDroid), illustrating its immediate applicability to Android apps. Major and muDroid generate non-compilable mutants, with the latter having a critical average rate of 58.7% non-compilable mutants per app. Also, even when PIT generates redundant mutants, the number is insignificant when compared to the number of mutants generated; at the same time MutAPK and MutAPK-Shared also generate a low number of redundant mutants; some of them can be fixed by improving the current implementation.


RQ4. What are the benefits and trade-offs of performing mutation testing at APK level vs source code level?

The clear benefit of performing APK-level mutation analysis (MutAPK) as opposed to source code-level mutation analysis (MDroid+) relates primarily to the ease of use of the system, as it only requires a single file (i.e., an APKfile instead of several source files), and generates mutants with higher compilability ratio in less time. Moreover, this makes the mutation tool applicable to apps written with various languages, i.e., Java, Kotlin, and Dart. However, this ease of use comes with as light trade-off in terms of generating a higher number of mutants (which leads to an extensive execution effort from developers), and a higher number of trivial and redundant mutants for certain operators that are likely to be discarded during mutant analysis.





Enabling Mutation Testing for Android Apps - ESEC/FSE 2017


RQ1. Are the mutation operators (available for Java and Android apps) representative of real bugs in Android apps?

MDroid+ outperformed the other six mutation tools by achieving the highest coverage both in terms of bug types and bug instances. However, the results shows that Android- specific mutation operators should be combined with classic operators to generate mutants that are representative of real faults in mobile apps.

Fault-Taxonomy

Bug Types not Covered by Taxonomy

RQ2. What is the rate of stillborn mutants (e.g., those leading to failed compilations) and trivial mutants (e.g., those leading to crashes on app launch) produced by the studied tools when used with Android apps?

First figure depicts the achieved results as percentage of Stillborn Mutants, the second figure presents the percentage of Trivial Mutants generated by each tool on each app. Third figure shows that on average, 167, 904, 2.6k+, and 1.5k+ mutants were generated by MDroid+, Major, PIT, and muDroid, respectively for each app. The larger number of mutants generated by PIT is due in part to the larger number of mutation operators available for the tool.

fse-generated-mutants
fse-trivial-mutants
fse-nc-mutants

MDroid+ generated the smallest rate of both stillborn and trivial mutants illustrating its immediate applicability to Android apps. Major and muDroid generate stillborn mutants, with the latter having a critical average rate of 58.7% stillborn mutants per app.

RQ3. What is the rate of stillborn mutants (e.g., those leading to failed compilations) and trivial mutants (e.g., those leading to crashes on app launch) produced by the studied tools when used with Android apps?

All four tools generated a relatively low rate of trivial mutants, with muDroid again being the worst with an 11.8% average rate of trivial mutants. Our analysis shows that the PIT tool is most applicable to Android apps when evaluated in terms of the ratio between failed and generated mutants. However, MDroid+ is both practical and based on Android-specific operations implemented according to an empirically derived fault-taxonomy of Android apps.



ESEC/FSE 2017 - Study Data


Please click the button below to obtain a copy of the data generated for each Mutation framework relating to RQ2 & RQ3 outlined above.



Publications