2

我正在尝试在eclipse中使用 Robolectric 运行一个简单的测试。我按照教程进行操作,但出现此错误:

java.lang.RuntimeException: java.io.FileNotFoundException: C:\Vishal\Development\workspace>\AndroidHelloWorldTester.\AndroidManifest.xml 未找到或不是文件;它 > 应该指向您项目的 AndroidManifest.xml

然后按照 Eugen 在此处的建议,我尝试按照此处的说明扩展 RobolectricTestRunner 类,但出现此错误:-(我无法完全按照指示编写构造函数,因为它会导致编译错误)

java.lang.Exception:测试类应该只有一个公共零参数构造函数

目前这是课程:-

package com.myTest;

import static org.hamcrest.CoreMatchers.equalTo;
import static org.junit.Assert.*;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.model.InitializationError;

import android.widget.Button;
import android.widget.TextView;

import com.visd.helloworld.AndroidHelloWorldActivity;
import com.visd.helloworld.R;
import com.xtremelabs.robolectric.RobolectricTestRunner;

@RunWith(RobolectricTestRunner.class)
public class Ahtest extends RobolectricTestRunner {

    public Ahtest(Class AndroidHelloWorldActivity) throws InitializationError {
    super(AndroidHelloWorldActivity, "<the project root location>");
    // TODO Auto-generated constructor stub
}

    private Button pressMeButton;
    private TextView results;
    AndroidHelloWorldActivity activity;
    @Before
    public void setUp() throws Exception {
        activity = new AndroidHelloWorldActivity();

        activity.onCreate(null);
        pressMeButton = (Button) activity.findViewById(R.id.mybut1);
        results = (TextView) activity.findViewById(R.id.text1);
    }

    @After
    public void tearDown() throws Exception {
    }

    @Test
    public void testSomethingMeaningfulToMyApp() {
         pressMeButton.performClick();
         String resultsText = results.getText().toString();
         assertThat(resultsText, equalTo("Button Clicked"));
    }

}

PN:
1)我为应用程序和测试做了不同的项目。
2)我不能完全按照指定的方式编写构造函数,因为如果我指定了:-

super(testClass, new File("../other/project-root"));

我会得到编译错误。请帮忙。

4

1 回答 1

1

维沙尔,

您正在混合测试和跑步者课程。

junit的一般工作方式如下:

for (TestClass c: allTests) {
    Test t = TestClass.newInstance();

    testListener.startTest(t.getName());
    try {
       t.beforeTest();
       t.run();
       t.afterTest();

       testListener.testPass(t.getName());
    } catch (Exception e) {
       if (t.isExpectedException(e)) {
           testListener.testPass(t.getName());
       } else if (isAssertException(e)) {
           testListener.testFail(t.getName(), getExplanation(e));
       } else {
           testListener.testError(t.getName(), e);
       }
    }

    testListener.testEnd(t.getName());
}

由于Class.newInstance()方法调用,测试类需要公共非零参数构造函数。注释@Test@Before@After标记到junit哪些类是测试类。

上面的代码是一种测试运行器类。有时您需要来自测试运行器类的额外逻辑。例如, RobolectricPowerMock正在用自己的特定目的替换标准 ClassLoader。Robolectric为 Android 类提供自己的实现。PowerMock用于模拟静态、最终类和方法,以及模拟类构造函数。

@RunWith存在注释以通知junit它应该为测试类使用另一个测试运行器。所以Robolectric Android 测试应该有@RunWith(RobolectricTestRunner.class). 但是,您可以通过扩展类向Robolectric测试运行器添加其他功能。RobolectricTestRunner例如用于自己的阴影或指向特定的 AndroidManifest.xml 文件。

因此,您应该拥有自己的测试运行器类AHTesRunner,您可以在其中将Robolectric指向特定的清单文件位置:

public class AHTestRunner extends RobolectricTestRunner {}

并且您需要通知junit它应该使用您自己的测试运行器(定制的Robolectric测试运行器):

@RunWith(AHTestRunner.class)
public class AHTest {
    @Before
    ......
    @Test
    ......
    @After
}

希望这现在很清楚

于 2012-12-25T21:21:35.760 回答