Android ActivityUnitTestCase如何整合目标应用程序';s AndroidManifest.xml?
我有个活动,比如说 它在给定的应用程序及其相应的清单中定义。此活动仅通过静态R索引加载contentView。比如说R.layout.foo。该布局中碰巧有一个组件,用于查看非基本android属性的内容。我看到,当一个测试应用程序运行这个活动时,主题和主题中的样式没有填充任何内容 样本清单Android ActivityUnitTestCase如何整合目标应用程序';s AndroidManifest.xml?,android,testing,Android,Testing,我有个活动,比如说 它在给定的应用程序及其相应的清单中定义。此活动仅通过静态R索引加载contentView。比如说R.layout.foo。该布局中碰巧有一个组件,用于查看非基本android属性的内容。我看到,当一个测试应用程序运行这个活动时,主题和主题中的样式没有填充任何内容 样本清单 <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.foo.bar"
android:versionCode="1"
android:versionName="Test"
android:installLocation="auto">
<uses-sdk android:minSdkVersion="3" android:targetSdkVersion="8" />
<uses-permission android:name="android.permission.INTERNET" />
<application
android:icon="@drawable/app_icon"
android:label="@string/app_name"
android:description="@string/description"
android:theme="@style/Theme.Custom"
android:name=".MyApplicationObject">
<activity android:name=".activity.A"/>
<supports-screens
android:smallScreens="true"
android:normalScreens="true"
android:largeScreens="true"
android:anyDensity="true" />
</manifest>
A布局,foo.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<com.foo.bar.CustomView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</LinearLayout>
值文件中的某些资源
public class A extends Activity {
public void onCreate(Bundle a) {
setContentView(R.layout.foo);
}
}
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Used to define a namespace for our special types -->
<declare-styleable name="CustomTypes">
<attr name="CustomViewStyle" format="reference"/>
</declare-styleable>
<!-- Used to define Attributes specific to our new View, "CustomView" -->
<declare-styleable name="CustomViewAttrs">
<attr name="layout" format="reference"/>
<attr name="anotherOne" format="reference"/>
</declare-styleable>
<!-- A usable style that we can reference later to pass to an instance of CustumView -->
<style name="CustomView">
<item name="layout">@layout/foo</item>
<item name="AnotherOne">@drawable/icon</item>
</style>
<!-- A Style to act as our Theme, referenced in our Manifest as the Theme for all activities -->
<style name="Theme.Custom" parent="android:Theme">
<item name="CustomViewStyle">@style/CustomView</item>
</style>
<resources>
@布局图/foo
@可绘图/图标
@样式/自定义视图
这很好,但当我使用ActivityUnitTest加载一个实例时,TypedArray中的值是空的
一些测试类
public class ActivityTester extends ActivityUnitTestCase<A> {
public ActivityTester() {
super(A.class);
}
public void testOne() {
Intent intent = new Intent(getInstrumentation().getTargetContext(), A.class);
// This fails with my IllegalStateException
startActivity(intent, null, null);
}
}
公共类ActivityTester扩展ActivityUnitTestCase{
公共活动测试仪(){
超级(A级);
}
公共void testOne(){
Intent Intent=newintent(getInstrumentation().getTargetContext(),A.class);
//但我的非法国家例外
startActivity(意向、无效、无效);
}
}
知道目标应用程序如何/如果得到它的清单解析吗?似乎这个主题还没有加载。startActivity()的文档说明它将以与context.startActivity()相同的方式启动活动。我不认为会发生这种情况,因为它似乎不尊重活动的清单数据。您可以改用它来测试使用系统基础结构创建的活动:
import android.test.ActivityInstrumentationTestCase2;
public class ActivityTester extends ActivityInstrumentationTestCase2<ActivityTester> {
public ActivityTester() {
super(ActivityTester.class);
}
public void testOne() {
//Intent intent = new Intent(getInstrumentation().getTargetContext(), ActivityTester.class);
// This fails with my IllegalStateException
//startActivity(intent, null, null);
getActivity();
}
}
导入android.test.ActivityInstrumentationTestCase2;
公共类ActivityTester扩展ActivityInstrumentationTestCase2用于独立的单元测试活动
您的代码中还有一些其他错误,但我认为它们是复制此处删除某些部分的结果。因此,在花费了大量时间尝试这样做之后,我发现,个人而言,最好的方法是模仿主题本身
public void setUp() {
ContextThemeWrapper context = new ContextThemeWrapper(getInstrumentation().getTargetContext(), R.style.Theme_MyTheme);
setActivityContext(context);
}
public void testOne() {
Intent intent = new Intent(getInstrumentation().getTargetContext(), A.class);
startActivity(intent, null, null);
}
就我个人而言,我不喜欢这样,因为它将单元测试实现与我想要抵消到另一个角色(如视觉设计师或图形艺术家)的风格细微差别结合起来,并增加了测试与即将发布的实现完全不同步的可能性。i、 e.有人更改清单文件,以便与活动
关联的主题
资源与正在测试的内容不同。这种测试用例类型看起来真的很短视,因为它可能会导致像这样的一系列糟糕的事情。我的意思是,您将得到一组测试基本功能的ActivityUnitTestCase
实例,然后是同一Activity
的一些测试用例,这些测试用例只是启动它或经历可能调用布局膨胀的转换。不是一个真正的应用程序正在测试 所以,当你说单元测试活动是孤立的,我的代码的哪一部分不这样做?我的意思是,如果调用onCreate()和onSaveInstanceState不是单独调用的方法,那么这个框架就有问题了。这甚至不能回答问题,也不能测试我想测试的两个东西。你怎么知道这不能测试你想测试的东西?你试过了吗?因为你刚刚创建了一个活动。我想实际测试一下我模拟出来的create。一次处于普通状态,一次从bundle状态恢复,一次使用非配置状态,一次使用提供的实例和非配置状态。所有这些我都可以嘲笑。你的解决方案基本上是说不要测试那些状态。嘿@Greg,你有没有找到解决你这个问题的方法?你介意把它贴出来作为回答吗?遗憾的是我没有。我个人想到的最多的方法是在测试上下文中手动设置主题。但即便如此,也不是很好-/该死的。:/也许你可以在这个问题上悬赏以吸引新的关注?谢谢!几个月来,我一直在寻找我为什么会遇到这个问题,以及可以做些什么来解决这个问题。
public void setUp() {
ContextThemeWrapper context = new ContextThemeWrapper(getInstrumentation().getTargetContext(), R.style.Theme_MyTheme);
setActivityContext(context);
}
public void testOne() {
Intent intent = new Intent(getInstrumentation().getTargetContext(), A.class);
startActivity(intent, null, null);
}