使用 robolectric 测试图像处理例程

the*_*0ID 5 junit android robolectric

对于我的 Android 应用程序,我确实需要一些图像处理例程,我想使用 robolectric 对其进行测试。这些例程确实对Bitmap对象进行操作。为了做到这一点,我需要加载测试图像。令我非常失望的是,我发现 robolectric 不支持BitmapFactoryAndroid 类框架。他们说:

Robolectric 并不是为了在 JVM 上运行整个应用程序,它只是为了启用足够的功能,以便您可以测试代码

所以我决定编写自己的Bitmap加载器:

public static Bitmap loadFromFile( File file ) throws IOException
{
    final BufferedImage image = ImageIO.read( file );
    final int[] pixels = new int[ image.getWidth() * image.getHeight() ];

    image.getRGB
        ( 0                    // start x
        , 0                    // start y
        , image.getWidth()     // width
        , image.getHeight()    // height
        , pixels               // pixel array
        , 0                    // offset
        , image.getWidth() );  // stride

    final Bitmap result = Bitmap.createBitmap
        ( pixels                      // pixel array
        , image.getWidth()            // width
        , image.getHeight()           // height
        , Bitmap.Config.ARGB_8888 );  // format

    return result;
}
Run Code Online (Sandbox Code Playgroud)

我还想测试加载器是否工作,所以我编写了如下所示的简短测试例程。

@Test
public void test() throws Exception
{
    final Bitmap source = loadFromFile( new File( "in.png" ) );
    saveToFile( source, "png", new File( "out.png" ) );
}
Run Code Online (Sandbox Code Playgroud)

它使用以下例程来写入图像:

public static void saveToFile
    ( Bitmap bitmap
    , String format, File file ) throws IOException
{
    final BufferedImage image = new BufferedImage
        ( bitmap.getWidth()               // width
        , bitmap.getHeight()              // height
        , BufferedImage.TYPE_INT_ARGB );  // channels

    final int[] pixels = new int[ image.getWidth() * image.getHeight() ];

    bitmap.getPixels
        ( pixels                // pixel array
        , 0                     // offset
        , image.getWidth()      // stride
        , 0                     // start x
        , 0                     // start y
        , image.getWidth()      // width
        , image.getHeight() );  // height

    image.setRGB
        ( 0                    // start x
        , 0                    // start y
        , image.getWidth()     // width
        , image.getHeight()    // height
        , pixels               // pixel array
        , 0                    // offset
        , image.getWidth() );  // stride

    ImageIO.write( image, format, file );
}
Run Code Online (Sandbox Code Playgroud)

运行测试后,我将写入的内容out.pngin.png. 当然,in.png看起来不错,其实out.png是空的。它具有正确的尺寸,但填充了零 alpha 像素。

问题:我做错了什么?我应该如何使用 robolectric 加载测试图像处理例程所需的测试图像?

注意:如果我pixels在创建对象之前将所有条目设置为 0xFFFFFFFF Bitmap,则不会发生任何变化。书写图像保持完全透明。所以我认为错误一定是在后来的某个地方。

我正在使用 robolectric 2.2。

sai*_*kek 3

显然我通过运行常规 Android 测试解决了这个问题。例子:

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.test.ActivityInstrumentationTestCase2;
import android.test.UiThreadTest;

public class InvadersFromSpace extends ActivityInstrumentationTestCase2<ColorPickerActivity> {

    public InvadersFromSpace() {
        super(ColorPickerActivity.class);
    }

    ColorPickerActivity mainActivity;
    Bitmap forpixels;

    @Override
    protected void setUp() throws Exception {
        super.setUp();

        mainActivity = getActivity();
        BitmapFactory.Options opts = new BitmapFactory.Options();
        opts.inScaled = false;
        forpixels = BitmapFactory.decodeFile("/storage/sdcard0/photos/IMG_20130815_194838.jpg");
    }

    @UiThreadTest
    public void testImageNormallyLoaded() {
        assertTrue(forpixels.getWidth() == 1716);
        assertTrue(forpixels.getHeight() == 1709);
    }

    @UiThreadTest
    public void testFlagDarkBlue() {
        CompareFewColors(forpixels, 772, 690, new String[]{"DarkMidnightBlue","Charcoal","CoolBlack"}, true);
        CompareFewColors(forpixels, 991, 1269, new String[]{"Arsenic","DarkMidnightBlue","Charcoal"}, false);
    }
}
Run Code Online (Sandbox Code Playgroud)

因此,您应该考虑两点:1)扩展 ActivityInstrumentationTestCase2 2)使用 @UiThreadTest 属性运行测试。(否则,当您访问 ui 参数或位图时,它们具有存根/模拟/旧参数)