Android jUnit TestCase:什么时候实际调用onCreate()活动?

时间:2011-11-22 10:45:21

标签: android robotium

我对测试很新,我正在尝试探索jUnit测试和Robotium。我的应用程序有4个屏幕。

Splash Screen --> Screen2--> Screen 3--> Autocomplete Screen.
[init()]                               [ check values generated by init() method]

自动填充屏幕是用户键入内容的位置,应用程序从大型产品数据库执行自动填充。在启动画面中,我使用另一个类中的init()方法初始化许多应用程序变量。这个init()方法将加载用户首选项,检查数据库创建等...(产品数据库预先打包在apk中,我在第一次启动时复制数据库并在SharedPreferences中将其标记为复制=真)。

问题:如何隔离自动完成屏幕的测试? autocompleteActivity的onCreate依赖于在SplashScreen中调用的init()。我不确定jUnit何时创建Activity的实例,(可能在构造函数中?)。这是我的TestCaseCode:

import android.test.ActivityInstrumentationTestCase2;
import android.view.View;
import android.widget.ListView;

import com.jayway.android.robotium.solo.Solo;
import com.supervalu.mobile.android.AutoCompleteActivity;
import com.supervalu.mobile.android.db.LocalDb;

public class AutocompleteTest extends
        ActivityInstrumentationTestCase2<AutoCompleteActivity> {
private Solo solo;

public AutocompleteTest() {
    super("com.****.*****.*****", AutoCompleteActivity.class);
}

protected void setUp() throws Exception {
    super.setUp();
    LocalDb.init(getActivity().getApplicationContext());
    solo = new Solo(getInstrumentation(), getActivity());

}

public void test1Character() {
    solo.sleep(2000);
    solo.enterText(0, "c");
    solo.sleep(10000);
View v = getActivity().findViewById(
            com.*****.****.*****.R.id.list);
    solo.waitForView(v);
    assertTrue(((ListView) v).getChildCount() > 0);


}

public void test3Character() {
    LocalDb.init(getActivity().getApplicationContext());
    solo.enterText(0, "che");
    View v = getActivity().findViewById(
            com.*****.****.*****.R.id.list);
    solo.waitForView(v);
    assertTrue(((ListView) v).getChildCount() > 0);
}

protected void tearDown() throws Exception {

    solo.finishOpenedActivities();
    super.tearDown();

}

测试用例不断崩溃,因为onCreate需要LocalDb中的某些值,必须通过init()方法进行初始化。

我无法在构造函数中的超级调用之前添加init()函数。有没有解决这个问题,或者我是否需要从启动画面启动测试用例?

问题2:如果我从splash scree开始测试,我必须首先导航到自动完成屏幕,然后才能对其执行任何测试。假设我也这样做了,然后对于每个测试:test1character()类执行setUp()然后测试然后tearDown(),然后它重新启动test3characters()函数的整个序列。在实际测试输入之前,每次重复导航到自动屏幕时都会非常痛苦。对此有何建议?

我不确定采取什么方法。有人可以指导我吗?

4 个答案:

答案 0 :(得分:3)

我有类似的问题并且能够解决它。 在你的setUp()方法中,调用getActivity()是没有用的。它不会影响您的测试方法。 你必须使用:

getInstrumentation().getTargetContext()

例如使用

getInstrumentation().getTargetContext().getContentResolver()

而不是

getActivity().getContentResolver()

希望这适合你!

干杯安东尼诺

答案 1 :(得分:0)

我发现模拟框架是执行隔离方法测试的更好选择 android活动方法。目前,jMockit只是能够有效模拟内核基类的框架。

您将能够丢弃大量的设置和拆卸代码。见测试用例:

https://github.com/ko5tik/andject/blob/master/src/test/java/de/pribluda/android/andject/ViewInjectionTest.java

答案 2 :(得分:0)

我不是很了解你的问题,但我会尽力帮助你。

执行Activity start(以及对它的onCreate回调的调用)是:

getActivity();

它的常用位置是setUp()方法(在每次测试之前调用)。

正如您所说的,每个测试都会调用setUp()tearDown()方法。

我认为测试应用程序导航的最佳方法是进行简单的测试,并根据需要创建所有意图,可以启动所有需要测试的活动。

我希望它有所帮助。

答案 3 :(得分:0)

如果您正在进行单元测试,您应该将测试类扩展到ActivityUnitTestCase以测试单个活动,并使用将调用onCreate的startActivity方法。 ActivityInstrumentationTestCase2用于对活动进行功能测试。

从Android参考文档中查看更多...

启动受测试的活动,方法与Context.startActivity()启动相同,提供它提供的参数。当您使用此方法启动活动时,它将由tearDown()自动停止。

此方法将调用onCreate(),但如果您希望进一步使用Activity生命周期方法,则必须自己从测试用例中调用它们。

请勿使用setUp()方法调用。您必须从每个测试方法中调用此方法。