当前位置: 首页 > 知识库问答 >
问题:

Android:如何使用Robolectric运行PIT突变测试?

督宏旷
2023-03-14

如何使用智能电子和PIT测试Android应用程序?

使用Robolectic,您可以在JVM中运行Android测试。使用PIT,您可以显示行覆盖范围并进行突变测试。对我来说,使用Eclipse插件是可以的,但没有要求。

这就是我迄今为止所尝试的:

我有一个Android项目,我们称之为MyProject。

我现在想在JVM中使用Robolectic和PIT测试MyProject。因此,我创建了另一个名为MyTest的项目,并成功运行了Robolectic测试,就像robolectic快速入门中描述的那样。这就是my.app.tests.MyActivityTest的样子:

@RunWith(RobolectricTestRunner.class)
public class MyActivityTest {
    @Test
    public void myTest() throws Exception {
        String appName = new MainActivity().getResources().getString(R.string.app_name);
        Assert.assertEquals(appName, "MyProject");
    }
}

现在棘手的部分是:我想在我的机器人分子测试中添加PIT的线覆盖和突变测试。第一次尝试使用Pitclipse-运气不好。Pitclipse似乎还不支持Eclipse项目依赖性。

因此,我的第二次尝试是使用命令行,如PIT快速启动中所述:

首先,我确保从命令行使用Junit成功地运行测试:

java -cp <classpath> org.junit.runner.JUnitCore my.app.tests.MyActivityTest

<代码>

一旦这个JUnit测试成功,我使用相同的

java -cp ../MyTest/bin:../MyTest/libs/*:bin/classes:~/android-sdk-linux/platforms/android-17/android.jar \
    org.pitest.mutationtest.MutationCoverageReport \
    --reportDir ../MyTest/pit-report \
    --targetClasses my.app.* \      # package in MyProject
    --targetTests my.app.tests.* \  # package in MyTest
    --sourceDirs src/

然而,这导致了我在下面发布的异常。我想我需要使用PIT的excludedClasses参数排除一些类,但是没有关于哪个类可能导致问题的提示。请注意,MyActivityTest没有超类,也没有显式构造函数。

java.lang.NullPointerException
ERROR Description [testClass=my.app.tests.MyActivityTest, name=myTest(my.app.tests.MyActivityTest)] -> java.lang.NullPointerException
    at org.pitest.boot.CodeCoverageStore.visitProbes(CodeCoverageStore.java:92)
    at my.app.tests.MyActivityTest.<init>(MyActivityTest.java:22)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:532)
    at org.junit.runners.BlockJUnit4ClassRunner.createTest(BlockJUnit4ClassRunner.java:195)
    at org.robolectric.RobolectricTestRunner$HelperTestRunner.createTest(RobolectricTestRunner.java:647)
    at org.junit.runners.BlockJUnit4ClassRunner$1.runReflectiveCall(BlockJUnit4ClassRunner.java:244)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.BlockJUnit4ClassRunner.methodBlock(BlockJUnit4ClassRunner.java:241)
    at org.robolectric.RobolectricTestRunner$HelperTestRunner.methodBlock(RobolectricTestRunner.java:657)
    at org.robolectric.RobolectricTestRunner$2.evaluate(RobolectricTestRunner.java:227)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
    at org.robolectric.RobolectricTestRunner$1.evaluate(RobolectricTestRunner.java:175)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
    at org.pitest.junit.adapter.CustomRunnerExecutor.run(CustomRunnerExecutor.java:42)
    at org.pitest.junit.adapter.AdaptedJUnitTestUnit.execute(AdaptedJUnitTestUnit.java:86)
    at org.pitest.coverage.execute.CoverageDecorator.execute(CoverageDecorator.java:50)
    at org.pitest.containers.UnContainer.submit(UnContainer.java:46)
    at org.pitest.Pitest$3.run(Pitest.java:148)
    at java.lang.Thread.run(Thread.java:679)

共有1个答案

慎望
2023-03-14

看起来正在发生的是,正在加载pit的代码覆盖率存储类的两个副本。这是一个针对每个测试跟踪每个类的线路覆盖率的类。

被测试的类由加载时分配给它们的整数id标识-此id嵌入到由字节码操作添加的探测调用中,该探测调用调用代码覆盖存储类。

代码假设存储中每个类id都有一个可用条目,因为每个id在加载时都在存储中注册。这个假设被打破了,因为接收探测调用的类的版本与最初注册类的版本不同。

要说pit 0.31及以下看起来与Roboelectric不兼容,还有很长的路要走。

我需要看一看Roboelectric在幕后到底做了什么,看看这是否可以在未来的版本中修复。

----更新---

0.32-SNAPSHOT版本似乎适用于RoboElectric(见评论)。

 类似资料:
  • 我现在正处于一个艰难的项目中,其中一个重要部分被重构,并通过大量失败的测试进行了检入。 我在maven中运行PIT,但由于测试必须是绿色的,所以我已经很长时间不能运行了,但我希望至少在运行的测试上有PIT概述。 将失败测试与PIT隔离的最有效方法是什么?

  • 我只是想用robolectric测试某个视图是否在片段中可见。我的单元测试如下所示: 我使用的是最新的android gradle Plugin1.1.3、Robolectirc2.4和robolectric gradle Plugin1.0.1,我的单元测试在文件夹中(而不是)。我无法编译该代码,因为编译器无法解析。 我的: 更新:以下是完整的代码: 代码可以在这里找到:https://gith

  • 问题内容: 目前,我有以下 build.gradle 文件: 这 的build.gradle 文件是我的仓库 在这里 。我所有的主文件都在 src / model /中 ,它们各自的测试在 test / model中 。 如何正确添加JUnit 4 依赖项 ,然后在 测试/模型 文件夹中运行那些测试? 问题答案: 如何正确添加junit 4依赖关系? 假设您要针对标准Maven(或等效版本)存储库

  • 当前我有以下build.gradle文件: 此build.gradle文件用于我的存储库。我的所有主文件都在src/model/中,它们各自的测试都在test/model中。

  • kotlintest测试从Intellij启动时运行得非常好,但当我尝试使用gradle test task命令运行它们时,只会找到并运行我的常规JUnit测试。 kotlintest代码: build.gradle:

  • 如何传递构建变体的名称以进行测试?