在ActivityInstrumentationTestCase2中测试open gl调用

时间:2011-12-06 16:51:20

标签: android unit-testing opengl-es-2.0

我不想在android仪器单元测试中测试一些开放的东西。 如果我没有弄错,所有的测试都在acual设备内运行,所以我认为opengl调用应该也能正常工作。

然而这种接缝并非如此,或者我错过了某些东西(所以我希望如此)。

我说了一个新项目&一个非常简单的测试项目来评估这个。

所以这是我的测试:

package com.example.test;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.IntBuffer;

import android.opengl.GLES20;
import android.test.ActivityInstrumentationTestCase2;
import android.test.UiThreadTest;

import com.example.HelloTesingActivity;


public class AndroidTest extends ActivityInstrumentationTestCase2<HelloTesingActivity> {

public AndroidTest(String pkg, Class<HelloTesingActivity> activityClass) {
    super(pkg, activityClass);
}

private HelloTesingActivity mActivity;

public AndroidTest() {
    super("com.example", HelloTesingActivity.class);
}



public void testTrue(){
    assertTrue(true);
}

@Override
protected void setUp() throws Exception {
    super.setUp();
    mActivity = getActivity();
}

public void testPreConditions() throws Exception {
    assertNotNull(mActivity); // passes
}

/*
 * FAILS
 */
@UiThreadTest // ensures this  test is run in the main UI thread.
public void testGlCreateTexture(){
    IntBuffer buffer = newIntBuffer();
    GLES20.glGenTextures(1, buffer);

    assertFalse(buffer.get() == 0); // this fails
}

/**
 * just a helper to setup a correct buffer for open gl to write the values into
 * @return
 */
private IntBuffer newIntBuffer() {
    ByteBuffer buff = ByteBuffer.allocateDirect(4);
    buff.order(ByteOrder.nativeOrder());
    buff.position(0);
    return buff.asIntBuffer();
}


/*
 * FAILS
 */
@UiThreadTest
public void testGlCalls(){
    GLES20.glActiveTexture(1); // set the texture unit to 1 since 0 is the default case

    IntBuffer value = newIntBuffer();
    GLES20.glGetIntegerv(GLES20.GL_ACTIVE_TEXTURE, value );

    assertEquals(1, value.get()); // this fails with expected: 1 but was: 0
}


    }

这就是活动本身,只是为了通信。

package com.example;

import android.app.Activity;
import android.opengl.GLSurfaceView;
import android.os.Bundle;

public class HelloTesingActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        GLSurfaceView surface = new GLSurfaceView(this);
        surface.setEGLContextClientVersion(2);
        setContentView(surface);

        surface.setRenderer(new MyRenderer());
    }
}

package com.example;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.opengl.GLSurfaceView.Renderer;

public class MyRenderer implements Renderer {

    @Override
    public void onDrawFrame(GL10 arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onSurfaceChanged(GL10 arg0, int arg1, int arg2) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onSurfaceCreated(GL10 arg0, EGLConfig arg1) {
        // TODO Auto-generated method stub

    }

}

2 个答案:

答案 0 :(得分:3)

我也想测试GL代码,这就是我在做的方式:

import java.util.concurrent.CountDownLatch;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.app.Activity;
import android.opengl.GLSurfaceView;
import android.test.ActivityInstrumentationTestCase2;

/**
 * <p>Extend ActivityInstrumentationTestCase2 for testing GL.  Subclasses can 
 * use {@link #runOnGLThread(Runnable)} and {@link #getGL()} to test from the 
 * GL thread.</p>
 * 
 * <p>Note: assumes a dummy activity, the test overrides the activity view and 
 * renderer.  This framework is intended to test independent GL code.</p>
 * 
 * @author Darrell Anderson
 */
public abstract class GLTestCase<T extends Activity> extends ActivityInstrumentationTestCase2<T> {
    private final Object mLock = new Object();

    private Activity mActivity = null;
    private GLSurfaceView mGLSurfaceView = null;
    private GL10 mGL = null;

    // ------------------------------------------------------------
    // Expose GL context and GL thread.
    // ------------------------------------------------------------

    public GLSurfaceView getGLSurfaceView() {
        return mGLSurfaceView;
    }

    public GL10 getGL() {
        return mGL;
    }

    /**
     * Run on the GL thread.  Blocks until finished.
     */
    public void runOnGLThreadAndWait(final Runnable runnable) throws InterruptedException {
        final CountDownLatch latch = new CountDownLatch(1);
        mGLSurfaceView.queueEvent(new Runnable() {
            public void run() {
                runnable.run();
                latch.countDown();
            }
        });
        latch.await();  // wait for runnable to finish
    }

    // ------------------------------------------------------------
    // Normal users should not care about code below this point.
    // ------------------------------------------------------------

    public GLTestCase(String pkg, Class<T> activityClass) {
        super(pkg, activityClass);
    }

    public GLTestCase(Class<T> activityClass) {
        super(activityClass);
    }

    /**
     * Dummy renderer, exposes the GL context for {@link #getGL()}.
     */
    private class MockRenderer implements GLSurfaceView.Renderer {
        @Override
        public void onDrawFrame(GL10 gl) {
            ;
        }
        @Override
        public void onSurfaceChanged(GL10 gl, int width, int height) {
            ;
        }
        @Override
        public void onSurfaceCreated(GL10 gl, EGLConfig config) {
            synchronized(mLock) {
                mGL = gl;
                mLock.notifyAll();
            }
        }
    }

    /**
     * On the first call, set up the GL context.
     */
    @Override
    protected void setUp() throws Exception {
        super.setUp();

        // If the activity hasn't changed since last setUp, assume the
        // surface is still there.
        final Activity activity = getActivity(); // launches activity
        if (activity == mActivity) {
            mGLSurfaceView.onResume();
            return;  // same activity, assume surface is still there
        }

        // New or different activity, set up for GL.
        mActivity = activity;
        mGLSurfaceView = new GLSurfaceView(activity);
        mGL = null;

        // Attach the renderer to the view, and the view to the activity.
        mGLSurfaceView.setRenderer(new MockRenderer());
        activity.runOnUiThread(new Runnable() {
            public void run() {
                activity.setContentView(mGLSurfaceView);
            }
        });

        // Wait for the renderer to get the GL context.
        synchronized(mLock) {
            while (mGL == null) {
                mLock.wait();
            }
        }
    }

    @Override
    protected void tearDown() throws Exception {
        mGLSurfaceView.onPause();
        super.tearDown();
    }   
}

答案 1 :(得分:1)

您已将测试注释为在 UIThread 上运行,但 OpenGL 调用应位于 GLThread 上。 AFAIK没有注释来运行这些测试。