编程语言
首页 > 编程语言> > Java-Android:如何使用Robolectric运行PIT变异测试?

Java-Android:如何使用Robolectric运行PIT变异测试?

作者:互联网

如何使用RobolectricPIT测试Android应用程序?

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

到目前为止,这是我尝试过的:

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

我现在想使用RobolectricPIT在JVM中测试MyProject.因此,我创建了另一个名为MyTest的项目,并设法成功运行了Robolectric测试,就像robolectric quick start中所述.这就是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");
    }
}

现在最棘手的部分是:我想在Robolectric测试中添加PIT的Line Coverage和Mutation Testing.第一次尝试使用Pitclipse-没有运气. Pitclipse似乎还不支持Eclipse Project Depencies.

因此,我的第二次尝试是使用命令行,如PIT quick start中所述:

首先,我确保通过命令行使用Junit成功运行了测试:

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

< classpath>包含:junit4,robolectric,MyProject类文件,MyTest类文件,android.jar和其他必要的android库.

一旦这个JUnit测试成功,我就使用相同的< classpath>在我的PIT调用中,然后在MyProject的根路径中执行该调用:

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)

解决方法:

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

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

该代码假定每个类ID在商店中都有可用的条目,因为每个ID在加载时都已在商店中注册.由于接受探测调用的类的版本与最初注册该类所针对的版本不同,因此这一假设被打破.

长话不说,0.31及以下的坑看起来与Roboelectric不兼容.

我需要看一下Roboelectric在幕后到底在做什么,以查看是否可以在将来的版本中解决此问题.

—-更新-

0.32-SNAPSHOT版本似乎可以与Roboelectric一起使用(请参阅注释).

标签:eclipse,robolectric,pitest,java,android
来源: https://codeday.me/bug/20191030/1965661.html