混淆Android测试项目和项目(在发布时运行测试和混淆版本)

混淆Android测试项目和项目(在发布时运行测试和混淆版本),android,testing,proguard,Android,Testing,Proguard,假设我有一个android应用程序项目,有测试 我们有没有办法针对发布版本运行测试套件(在单独的测试项目中)?您的测试和源代码是否在一个项目中?如果是这样的话,我相信android maven会在您执行发布时删除测试代码 要解决这个问题,您需要将测试转移到一个单独的项目,该项目链接到您的实际应用程序(假设您依赖于实际项目的代码/资产),然后该单独的项目仍然能够针对您的应用程序的发布版本进行插入(假设它们由相同的密钥签名) 在阅读了赏金的评论后,我意识到OP实际上问的不仅仅是一个简单的是/否回答,

假设我有一个android应用程序项目,有测试


我们有没有办法针对发布版本运行测试套件(在单独的测试项目中)?

您的测试和源代码是否在一个项目中?如果是这样的话,我相信android maven会在您执行发布时删除测试代码


要解决这个问题,您需要将测试转移到一个单独的项目,该项目链接到您的实际应用程序(假设您依赖于实际项目的代码/资产),然后该单独的项目仍然能够针对您的应用程序的发布版本进行插入(假设它们由相同的密钥签名)

在阅读了赏金的评论后,我意识到OP实际上问的不仅仅是一个简单的是/否回答,所以我将把我的评论扩展到一个答案。一般来说,适当设计的proguard.cfg和项目结构足以防止这种困境

一个典型的proguard配置(参见中的第7节,完整的Android应用程序部分)保证在混淆过程中保留所有与Android相关的内容,如活动、视图等。更改配置(例如,混淆Acticity.onCreate()方法)没有任何意义,因为它显然会在运行时破坏应用程序。换句话说,设计良好的proguard.cfg将保护底层运行时框架的所有公共接口,并保持它们不变

... ...

-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*(...);
}

... ...
。。。
-keep public class*扩展android.app.Activity
-keep public class*扩展android.app.Application
-keep public class*扩展了android.app.Service
-keep public class*扩展了android.content.BroadcastReceiver
-keep public class*扩展了android.content.ContentProvider
-keep public class*扩展了android.view.view{
public(android.content.Context);
public(android.content.Context、android.util.AttributeSet);
public(android.content.Context,android.util.AttributeSet,int);
公共无效集*(…);
}
... ...
另一方面,Android测试项目应该专注于测试Android组件(在混淆过程中故意保留),即,视图被预先渲染,按钮点击执行正确的任务,并且应该避免为不依赖任何Android API的POJO类编写测试,注意这些POJO是我们通常混淆的。最好在应用程序或引用的java项目中为这些POJO编写纯junit测试,以便在创建最终版本(模糊、签名和zipaligned)之前,这些junit测试在maven测试阶段参与。此外,良好的OO设计将屏蔽这些中间POJO依赖项,并使它们对外透明,即运行时框架

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
  ... ...
app/
src/main/java/

src/test/java/您可以指示proguard使用
-printmapping
指令将其创建的映射写入文件。该文件的结构很明显,可以解析为哈希表。然后我将编写一个脚本,将这些转换应用到您的测试中(制作它们的副本)。混淆仅仅意味着将类和方法名称从Java字节码规范中的某些内容(人类可读且有效)替换为另一些内容(简短且非人类可读,但也有效),因此这应该是可行的。针对模糊化的项目编译适应的测试并运行它们。

只要您使用相同的发布密钥库对test.apk进行签名,简短的回答是肯定的,不管app.apk和/或test.apk是否模糊化。您是否使用ant构建?我猜你是在问如何测试由ant release构建的项目,对吗?不太对,我现在正在使用maven android插件。我已经有了一个单独的项目。我很关心测试代码中对模糊代码的调用。谢谢您的回答。这是我一直在寻找的细节层次。事实上,我可能不同意你关于将POJO测试排除在android测试项目之外的建议。AndroidTestCase就是为了这个目的(与测试上下文的InstrumentedTest相反)。此外,eclipse不支持标准应用程序布局中的junit测试。android maven插件甚至值得一试,因为应用程序的apk中包含了测试依赖项。防止混淆对我来说似乎相当麻烦,因为测试应该不会对代码或配置产生影响,特别是在已发布的代码和已发布的apk.1中。编写POJO测试不需要AndroidTestCase,因为它扩展了junit.framework.TestCase,所以我们可以直接使用TestCase。2. <代码>甚至更糟??android maven插件作为测试依赖项包含在应用程序的apk中,你确定吗?我对此表示怀疑,请查看apk,它应该排除测试依赖性。在我看来,仪器测试并不完全遵循经典单元测试的策略。单元测试通常在打包最终版本之前执行(单元测试失败/错误通常会停止构建过程),而插装测试纯粹是在运行时针对完全构建的apk。但是,正如我在最后一段中提到的,没有简单的对/错观点,整个观点都是关于合理性的。lol指出一个封闭的问题只能用yes/noIs来回答。有没有办法告诉proguard使用给定的映射?是的,你可以给proguard一个映射文件,在它运行时使用。是的,
-applymapping
。有关详细信息,请参阅。即使在测试项目中使用-applymapping来使用目标项目的映射,我仍然会遇到问题。问题来自静态方法和字段以及实例字段。当从测试代码访问这些代码时,我得到NoSuchMethodError和NoSuchFieldError。