xiaoshengyige 2011-03-08
3. 定义test runner,以及构建UI来处理测试流程,查看测试结果等。<!--[endif]-->
MyJUnitExample.java
package com.ut.prac; import junit.framework.Test; import junit.framework.TestListener; import android.app.Activity; import android.os.Bundle; import android.test.AndroidTestRunner; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.TextView; import android.widget.Toast; public class MyJUnitExample extends Activity { static final String LOG_TAG = "junit"; Thread testRunnerThread = null; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Button launcherButton = (Button)findViewById( R.id.launch_button ); launcherButton.setOnClickListener( new View.OnClickListener() { public void onClick( View view ) { startTest(); } } ); } private synchronized void startTest() { if( ( testRunnerThread != null ) && !testRunnerThread.isAlive() ) testRunnerThread = null; if( testRunnerThread == null ) { testRunnerThread = new Thread( new TestRunner( this ) ); testRunnerThread.start(); } else Toast.makeText( this, "Test is still running", Toast.LENGTH_SHORT).show(); } } class TestDisplay implements Runnable { public enum displayEvent { START_TEST, END_TEST, ERROR, FAILURE, } displayEvent ev; String testName; int testCounter; int errorCounter; int failureCounter; TextView statusText; TextView testCounterText; TextView errorCounterText; TextView failureCounterText; public TestDisplay( displayEvent ev, String testName, int testCounter, int errorCounter, int failureCounter, TextView statusText, TextView testCounterText, TextView errorCounterText, TextView failureCounterText ) { this.ev = ev; this.testName = testName; this.testCounter = testCounter; this.errorCounter = errorCounter; this.failureCounter = failureCounter; this.statusText = statusText; this.testCounterText = testCounterText; this.errorCounterText = errorCounterText; this.failureCounterText = failureCounterText; } public void run() { StringBuffer status = new StringBuffer(); switch( ev ) { case START_TEST: status.append( "Starting" ); break; case END_TEST: status.append( "Ending" ); break; case ERROR: status.append( "Error: " ); break; case FAILURE: status.append( "Failure: " ); break; } status.append( ": " ); status.append( testName ); statusText.setText( new String( status ) ); testCounterText.setText( "Tests: "+testCounter ); errorCounterText.setText( "Errors: "+errorCounter ); failureCounterText.setText( "Failure: "+failureCounter ); } } class TestRunner implements Runnable,TestListener { static final String LOG_TAG = "TestRunner"; int testCounter; int errorCounter; int failureCounter; TextView statusText; TextView testCounterText; TextView errorCounterText; TextView failureCounterText; Activity parentActivity; public TestRunner( Activity parentActivity ) { this.parentActivity = parentActivity; } public void run() { testCounter = 0; errorCounter = 0; failureCounter = 0; statusText = (TextView)parentActivity. findViewById( R.id.status ); testCounterText = (TextView)parentActivity. findViewById( R.id.testCounter ); errorCounterText = (TextView)parentActivity. findViewById( R.id.errorCounter ); failureCounterText = (TextView)parentActivity. findViewById( R.id.failureCounter ); Log.d( LOG_TAG, "Test started" ); AndroidTestRunner testRunner = new AndroidTestRunner(); testRunner.setTest( new ExampleSuite() ); testRunner.addTestListener( this ); testRunner.setContext( parentActivity ); testRunner.runTest(); Log.d( LOG_TAG, "Test ended" ); } // TestListener public void addError(Test test, Throwable t) { Log.d( LOG_TAG, "addError: "+test.getClass().getName() ); Log.d( LOG_TAG, t.getMessage(), t ); ++errorCounter; TestDisplay td = new TestDisplay( TestDisplay.displayEvent.ERROR, test.getClass().getName(), testCounter, errorCounter, failureCounter, statusText, testCounterText, errorCounterText, failureCounterText ); parentActivity.runOnUiThread( td ); } public void endTest(Test test) { Log.d( LOG_TAG, "endTest: "+test.getClass().getName() ); TestDisplay td = new TestDisplay( TestDisplay.displayEvent.END_TEST, test.getClass().getName(), testCounter, errorCounter, failureCounter, statusText, testCounterText, errorCounterText, failureCounterText ); parentActivity.runOnUiThread( td ); } public void startTest(Test test) { Log.d( LOG_TAG, "startTest: "+test.getClass().getName() ); ++testCounter; TestDisplay td = new TestDisplay( TestDisplay.displayEvent.START_TEST, test.getClass().getName(), testCounter, errorCounter, failureCounter, statusText, testCounterText, errorCounterText, failureCounterText ); parentActivity.runOnUiThread( td ); } @Override public void addFailure(Test test, junit.framework.AssertionFailedError t) { // TODO Auto-generated method stub Log.d( LOG_TAG, "addFailure: "+test.getClass().getName() ); Log.d( LOG_TAG, t.getMessage(), t ); ++failureCounter; TestDisplay td = new TestDisplay( TestDisplay.displayEvent.FAILURE, test.getClass().getName(), testCounter, errorCounter, failureCounter, statusText, testCounterText, errorCounterText, failureCounterText ); parentActivity.runOnUiThread( td ); } }
4. 最后是xml文件<!--[endif]-->
Manifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.ut.prac" android:versionCode="1" android:versionName="1.0"> <uses-permission android:name="android.permission.WRITE_CONTACTS" /> <uses-permission android:name="android.permission.READ_CONTACTS" /> <application android:icon="@drawable/icon" android:label="@string/app_name"> <uses-library android:name="android.test.runner" /> <activity android:name=".MyJUnitExample" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> <uses-sdk android:minSdkVersion="3" /> </manifest>
Mail.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <Button android:id="@+id/launch_button" android:text="@string/launch_test" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:id="@+id/status" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="" /> <TextView android:id="@+id/testCounter" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="" /> <TextView android:id="@+id/errorCounter" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="" /> <TextView android:id="@+id/failureCounter" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="" /> </LinearLayout>
最后编译,执行。。。