Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Obfuscate Android Test project as well as project (running test on release and obfuscated version)

Let's say I got an android app project with tests.

Is there any way we can run our test suite (in a separate test project) against the release version ?

like image 864
Snicolas Avatar asked Feb 04 '13 22:02

Snicolas


People also ask

How do I obfuscate an Android library project?

In order to obfuscate your library what you need to do is: Make sure gradle settings for lib module state minifyEnabled true . run ./gradlew assemble{flavor}Release.

Which of the following is the Android obfuscation tools?

Obfuscapk is an open-source automatic obfuscation tool for Android apps that works in a black-box fashion (i.e., it does not need the app source code). Obfuscapk supports advanced obfuscation features and has a modular architecture that could be straightforwardly extended to support new obfuscation techniques.

How does obfuscation work Android?

Obfuscation changes the code and its data without modifying the behavior of the application or the user experience. It ranges from renaming classes or methods to transforming arithmetic or modifying the control flow of the app or encrypting app data.


2 Answers

After reading the bounty's comment, I realised OP actually ask something more than a simple Yes/No reply, so I am going to extend my comment to an answer. Generally speaking, a proper designed proguard.cfg and project structure is sufficient to prevent this dilemma.

A typical proguard configuration (see section 7. A complete Android application section in this link) guarantee that all android related stuff like Activity, View and etc. is preserved during obfuscation. It doesn't make any sense to alter the configuration for example, to obfuscate Acticity.onCreate() method as it will obviously ruin the application at runtime. In another word, a well design proguard.cfg will protect all public interface to the underlying runtime framework and keep them remain unchanged.

... ...

-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider

-keep public class * extends android.view.View {
    public <init>(android.content.Context);
    public <init>(android.content.Context, android.util.AttributeSet);
    public <init>(android.content.Context, android.util.AttributeSet, int);
    public void set*(...);
}

... ...

On the other hand, Android test project should focus on testing Android component (Intentionally preserved during obfuscation), i.e. a view is proerly rendered, a button click perform correct task, and should avoid writing tests for POJO class that doesn't rely on any Android API, note that these POJOs are what we obfuscate usually. It is better to write pure junit tests for these POJO in the application or referenced java project so that these junit tests are involved at maven test phase before creating the final release (obfuscated, signed and zipaligned). In addition, a good OO design will shield these intermediate POJO dependencies and make them transparent to the outside, i.e. the runtime framework.

app/
  src/main/java/
  src/test/java/  <-- intermediate POJO tests put here.
  AndroidManifest.xml
  ... ...
app-test/
  src/main/java  <-- Android component tests put here.
  AndroidManifest.xml
  ... ...

It is absolutely fine to write POJO junit tests inside Android test project, however, if you still want to keep the ability to run the test project against obfuscated apk, you need adjust application project's proguard.cfg properly and preserve the POJO class during obfuscation in order to suit the test code.

like image 88
yorkw Avatar answered Oct 20 '22 02:10

yorkw


You can instruct proguard to write out the mapping it creates into a file using the -printmapping <filename> directive. The structure of that file is obvious and can be parsed into a Hashtable. Then I would write a script that does apply those conversions onto your tests (making copies of them). Obfuscation simply means replacing class and method names from something (human-readable and) valid in terms of the Java Bytecode Specification to something other (short and not human-readable but) also valid, so this should work. Compile the adapted tests against the obfuscated project and run them.

like image 39
Matthias Ronge Avatar answered Oct 20 '22 01:10

Matthias Ronge