Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 使用毕加索和Robolectric的虚假测试失败_Android_Unit Testing_Robolectric - Fatal编程技术网

Android 使用毕加索和Robolectric的虚假测试失败

Android 使用毕加索和Robolectric的虚假测试失败,android,unit-testing,robolectric,Android,Unit Testing,Robolectric,我今天刚升级到Robolectric 2.1.1和集成毕加索。我现在有两个随机失败的测试用例(其中一个片段甚至没有使用毕加索)。如果我继续运行测试,通常所有测试都会通过(可能需要几次尝试) 测试 @Before public void setUp() throws Exception { detailActivity = Robolectric.buildActivity( ActivityUnderTest.class )

我今天刚升级到Robolectric 2.1.1和集成毕加索。我现在有两个随机失败的测试用例(其中一个片段甚至没有使用毕加索)。如果我继续运行测试,通常所有测试都会通过(可能需要几次尝试)

测试

@Before
public void setUp() throws Exception
{
    detailActivity = Robolectric.buildActivity( ActivityUnderTest.class )
                                .withIntent( createIntent() )
                                .create()
                                .start()
                                .resume()
                                .get();

    // Note: The other test case doesn't use the fancy withIntent() doohickey
}

public static Intent createIntent()
{
    Bundle bundle = DetailFragment.createBundle( getTestData() );
    Intent intent = new Intent( new ActivityUnderTest(), Activity.class );
    intent.putExtras( bundle );
    return intent;
}

@Test
public void shouldNotBeNull() throws Exception
{
    assertNotNull( detailActivity );
}
Codez

我正在向活动发送一组信息,这基本上是一个空壳。该活动通过XML显示片段。在我的片段中,我使用
getActivity().getIntent().getExtras()
从包中获取数据

说谎警告

[警告]您正在直接实例化一个活动(com.colabug.project.singlepanel.ActivityUnderTest);考虑使用RoBoCurtual.BuudActuvio()代替.< /P> Stacktrace

java.lang.RuntimeException: An unexpected exception occurred
at com.squareup.picasso.Request$1.run(Request.java:114)
at org.robolectric.util.Scheduler$PostedRunnable.run(Scheduler.java:162)
at org.robolectric.util.Scheduler.runOneTask(Scheduler.java:107)
at org.robolectric.util.Scheduler.advanceTo(Scheduler.java:92)
at org.robolectric.util.Scheduler.advanceToLastPostedRunnable(Scheduler.java:68)
at org.robolectric.util.Scheduler.unPause(Scheduler.java:25)
at org.robolectric.shadows.ShadowLooper.unPause(ShadowLooper.java:219)
at org.robolectric.shadows.ShadowLooper.runPaused(ShadowLooper.java:258)
at org.robolectric.util.ActivityController.invokeWhilePaused(ActivityController.java:202)
at org.robolectric.util.ActivityController.start(ActivityController.java:144)
at com.colabug.project.singlepanel.DetailActivityTest.setUp(DetailActivityTest.java:32)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:27)
at org.robolectric.RobolectricTestRunner$2.evaluate(RobolectricTestRunner.java:241)
at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.robolectric.RobolectricTestRunner$1.evaluate(RobolectricTestRunner.java:177)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:24)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:77)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:195)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:63)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Caused by: java.lang.NullPointerException: Bitmap config was null.
at org.robolectric.shadows.ShadowBitmap.getBytesPerPixel(ShadowBitmap.java:338)
at org.robolectric.shadows.ShadowBitmap.getRowBytes(ShadowBitmap.java:225)
at org.robolectric.shadows.ShadowBitmap.getByteCount(ShadowBitmap.java:230)
at android.graphics.Bitmap.getByteCount(Bitmap.java)
at com.squareup.picasso.Utils$BitmapHoneycombMR1.getByteCount(Utils.java:250)
at com.squareup.picasso.Utils.getBitmapBytes(Utils.java:65)
at com.squareup.picasso.Stats.processBitmap(Stats.java:64)
at com.squareup.picasso.Stats.bitmapDecoded(Stats.java:40)
at com.squareup.picasso.Picasso.loadFromType(Picasso.java:365)
at com.squareup.picasso.Picasso.resolveRequest(Picasso.java:215)
at com.squareup.picasso.Picasso.run(Picasso.java:197)
at com.squareup.picasso.Request.run(Request.java:108)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:439)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
at java.lang.Thread.run(Thread.java:680)
at com.squareup.picasso.Utils$PicassoThread.run(Utils.java:244)
pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project
    xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

    <modelVersion>4.0.0</modelVersion>
    <groupId>com.colabug</groupId>
    <artifactId>Project</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>apk</packaging>
    <name>Project</name>

    <dependencies>
        <dependency>
            <groupId>com.google.android</groupId>
            <artifactId>android</artifactId>
            <version>2.2.1</version>
            <scope>provided</scope>
        </dependency>

        <!-- Make sure this is below the android dependencies -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.8.2</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.robolectric</groupId>
            <artifactId>robolectric</artifactId>
            <version>2.1.1</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>com.squareup.picasso</groupId>
            <artifactId>picasso</artifactId>
            <version>1.0.2</version>
        </dependency>
    </dependencies>

    <build>
        <finalName>${project.artifactId}</finalName>

        <plugins>
            <plugin>
                <!-- See http://code.google.com/p/maven-android-plugin/ -->
                <groupId>com.jayway.maven.plugins.android.generation2</groupId>
                <artifactId>maven-android-plugin</artifactId>
                <version>2.8.3</version>
                <configuration>
                    <sdk>
                        <platform>17</platform>
                    </sdk>
                </configuration>
                <extensions>true</extensions>
            </plugin>
        </plugins>
    </build>
</project>

4.0.0
com.colabug
项目
1.0.0-SNAPSHOT
apk
项目
com.google.android
安卓
2.2.1
假如
朱尼特
朱尼特
4.8.2
测试
有机分子
生物分子
2.1.1
测试
毕加索
毕加索
1.0.2
${project.artifactId}
com.jayway.maven.plugins.android.generation2
maven android插件
2.8.3
17
真的

有什么想法吗?IntelliJ可能是原因,因为它出现在stacktrace中。我使用了
mvn clean
,手动清理了命令行上自动生成的文件,并在IntelliJ中重建了项目。

警告没有出现

意向意向=新意向(新ActivityUnderTest(),Activity.class)

“new ActivityUnderTest()”限定为“直接实例化活动”

在许多情况下,测试失败/通过似乎是随机的,底层代码中存在线程问题。上次我遇到这种情况时,“有时会失败”测试实际上是在我的队列代码中暴露了一个竞争条件


我发现当我有“这个测试很愚蠢!”的反应时,我几乎发现这个测试实际上比我聪明(而且也比我好,因为它试图提供帮助)。

Drew是正确的。NPE发生在后台线程中

原因:java.lang.NullPointerException:位图配置为null

从根本上说,这似乎是
阴影位图
的一个问题。然而,我选择的解决方案是创建一个
MockPicasso

存根实现阻止了NPE。它还有一个额外的好处,即首先防止单元测试通过网络请求位图

MockPicasso.java

package com.squareup.picasso;

import android.graphics.Bitmap;
import android.widget.ImageView;

public class MockPicasso extends Picasso {
    private static String lastImagePath = null;
    private static ImageView lastTargetImageView = null;

    MockPicasso() {
        super(null, null, null, Cache.NONE, null, new MockStats());
    }

    public static void init() {
        singleton = new MockPicasso();
    }

    public static String getLastImagePath() {
        return lastImagePath;
    }

    public static ImageView getLastTargetImageView() {
        return lastTargetImageView;
    }

    @Override
    public RequestBuilder load(String path) {
        lastImagePath = path;
        return new MockRequestBuilder();
    }

    class MockRequestBuilder extends RequestBuilder {
        @Override
        public void into(ImageView target) {
            lastTargetImageView = target;
        }
    }

    static class MockStats extends Stats {
        MockStats() {
            super(Cache.NONE);
        }

        @Override
        void bitmapDecoded(Bitmap bitmap) {
            // Do nothing.
        }
    }
}
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    ImageView avatar = (ImageView) findViewById(R.id.avatar);
    String path = getIntent().getStringExtra("avatar_url");
    Picasso.with(this).load(path).into(avatar);
}
@Test
public void shouldDisplayAvatar() throws Exception {
    MockPicasso.init();
    String imageUrl = "http://www.example.com/test.jpg";
    Intent intent = new Intent().putExtra("avatar_url", imageUrl);
    MyActivity myActivity = Robolectric.buildActivity(MyActivity.class)
            .create().get();

    myActivity.setIntent(intent);
    Robolectric.shadowOf(myActivity).callOnCreate(null);
    ImageView avatar = (ImageView) myActivity.findViewById(R.id.avatar);
    assertThat(MockPicasso.getLastImagePath()).isEqualTo(imageUrl);
    assertThat(MockPicasso.getLastTargetImageView()).isSameAs(avatar);
}
使用
getLastImagePath()
getLastTargetImageView()
可以测试代码是否请求了正确的图像并将其加载到正确的视图中,而不会实际触动网络

MyActivity.java

package com.squareup.picasso;

import android.graphics.Bitmap;
import android.widget.ImageView;

public class MockPicasso extends Picasso {
    private static String lastImagePath = null;
    private static ImageView lastTargetImageView = null;

    MockPicasso() {
        super(null, null, null, Cache.NONE, null, new MockStats());
    }

    public static void init() {
        singleton = new MockPicasso();
    }

    public static String getLastImagePath() {
        return lastImagePath;
    }

    public static ImageView getLastTargetImageView() {
        return lastTargetImageView;
    }

    @Override
    public RequestBuilder load(String path) {
        lastImagePath = path;
        return new MockRequestBuilder();
    }

    class MockRequestBuilder extends RequestBuilder {
        @Override
        public void into(ImageView target) {
            lastTargetImageView = target;
        }
    }

    static class MockStats extends Stats {
        MockStats() {
            super(Cache.NONE);
        }

        @Override
        void bitmapDecoded(Bitmap bitmap) {
            // Do nothing.
        }
    }
}
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    ImageView avatar = (ImageView) findViewById(R.id.avatar);
    String path = getIntent().getStringExtra("avatar_url");
    Picasso.with(this).load(path).into(avatar);
}
@Test
public void shouldDisplayAvatar() throws Exception {
    MockPicasso.init();
    String imageUrl = "http://www.example.com/test.jpg";
    Intent intent = new Intent().putExtra("avatar_url", imageUrl);
    MyActivity myActivity = Robolectric.buildActivity(MyActivity.class)
            .create().get();

    myActivity.setIntent(intent);
    Robolectric.shadowOf(myActivity).callOnCreate(null);
    ImageView avatar = (ImageView) myActivity.findViewById(R.id.avatar);
    assertThat(MockPicasso.getLastImagePath()).isEqualTo(imageUrl);
    assertThat(MockPicasso.getLastTargetImageView()).isSameAs(avatar);
}
MyActivityTest.java

package com.squareup.picasso;

import android.graphics.Bitmap;
import android.widget.ImageView;

public class MockPicasso extends Picasso {
    private static String lastImagePath = null;
    private static ImageView lastTargetImageView = null;

    MockPicasso() {
        super(null, null, null, Cache.NONE, null, new MockStats());
    }

    public static void init() {
        singleton = new MockPicasso();
    }

    public static String getLastImagePath() {
        return lastImagePath;
    }

    public static ImageView getLastTargetImageView() {
        return lastTargetImageView;
    }

    @Override
    public RequestBuilder load(String path) {
        lastImagePath = path;
        return new MockRequestBuilder();
    }

    class MockRequestBuilder extends RequestBuilder {
        @Override
        public void into(ImageView target) {
            lastTargetImageView = target;
        }
    }

    static class MockStats extends Stats {
        MockStats() {
            super(Cache.NONE);
        }

        @Override
        void bitmapDecoded(Bitmap bitmap) {
            // Do nothing.
        }
    }
}
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    ImageView avatar = (ImageView) findViewById(R.id.avatar);
    String path = getIntent().getStringExtra("avatar_url");
    Picasso.with(this).load(path).into(avatar);
}
@Test
public void shouldDisplayAvatar() throws Exception {
    MockPicasso.init();
    String imageUrl = "http://www.example.com/test.jpg";
    Intent intent = new Intent().putExtra("avatar_url", imageUrl);
    MyActivity myActivity = Robolectric.buildActivity(MyActivity.class)
            .create().get();

    myActivity.setIntent(intent);
    Robolectric.shadowOf(myActivity).callOnCreate(null);
    ImageView avatar = (ImageView) myActivity.findViewById(R.id.avatar);
    assertThat(MockPicasso.getLastImagePath()).isEqualTo(imageUrl);
    assertThat(MockPicasso.getLastTargetImageView()).isSameAs(avatar);
}

啊,接得好。很高兴我加入了我认为毫无意义的警告。我明天会试试的!谢谢你提供的所有信息,恰克!我将在这个周末检查这个,看看它是否修复了我的错误。希望这有帮助。这是我写的一个有更多背景信息和更深入一点的例子。@ecgreb:如何使MockPicasso成为com.squareup.picasso包的一部分?我刚刚在我的项目中复制了文件夹结构,并将文件放在
src/test/java/com/squareup/picasso/MockPicasso.java
中。