Android basics 12: Android automated testing 03-JUnit-based Android testing framework 02

Source: Internet
Author: User

This article introduces the JUnit-based Android testing framework.

5. androidtestrunner

As we learned more, we found that android was ignored in the previous section. an important class in the test package, androidtestrunner, is Android. the core class of the test package is described in detail below and some related content is provided.

Testlistener interface in JUnit. Framework Package
The functions of this interface are listed as follows:

package junit.framework;/** * A Listener for test progress */public interface TestListener {/**  * An error occurred.  */public void addError(Test test, Throwable t);/**  * A failure occurred.  */ public void addFailure(Test test, AssertionFailedError t);  /** * A test ended. */ public void endTest(Test test); /** * A test started. */public void startTest(Test test);}

For this interface, only testresult is used for related classes. The related interfaces are as follows:

/** * Registers a TestListener */public synchronized void addListener(TestListener listener) {fListeners.addElement(listener);}/** * Unregisters a TestListener */public synchronized void removeListener(TestListener listener) {fListeners.removeElement(listener);}

Here we should know how to use it. The specific usage is described in the next example.
The JUnit. Runner package has the following structure:

This is a helper package for JUnit. Framework. The package is mainly the basetestrunner class, which implements the testlistener interface. The main function is to check the error and failure during the test.
With these supplementary instructions, we will learn about an important class androidtestrunner In the Android. Test package.
The androidtestrunner class structure is shown in:


Its main interface functions are listed as follows:


The parameter context of the setcontext (context) function is displayed.
Context, finally let me see the combination of JUnit and Android. After looking at several other functions, we will find that this class is Android. the core control class of test, everyone's doubts suddenly disappeared. A brief example is as follows:

AndroidTestRunner testRunner = new AndroidTestRunner();testRunner.setTest( new ExampleSuite() );testRunner.addTestListener( this );testRunner.setContext( parentActivity );testRunner.runTest();

Use androidtestrunner to control the entire test and integrate it with our activity.

6. androidtest Example Analysis

We learned about Android. most of the classes in the test package are to learn the specific examples to link the previous knowledge, so that we can have a deeper understanding. The example program code is downloaded and added to the es project, read the sample code in this article.

First, analyze the structure of the entire project, as shown below:


Androidtestcase and testsuite have already been learned in the previous sections. contesttest, mathtest, sometest, and examplesuite have already been introduced in the previous examples. Here we mainly explain how the entire program runs?

The android interface program is as follows:

public class JUnit 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 addFailure(Test test, AssertionFailedError t)         {            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 );        }        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 );        }}

The core code of the entire program is as follows:

 AndroidTestRunner testRunner = new AndroidTestRunner();            testRunner.setTest( new ExampleSuite() );            testRunner.addTestListener( this );            testRunner.setContext( parentActivity );            testRunner.runTest();

The core class androidtestrunner, which we have learned in the previous sections, is used frequently in the future ):


The red dashes represent functions of the androidtestrunner class used in the sample code. The main function of using a separate thread here is: testrunner. runtest (); takes a lot of time. If the UI thread is blocked directly in the UI thread, the interface will stop responding, which will have a great impact on user operations.
How can I display the test information in testrunner on the interface?
The android SDK provides handler, which is associated with the message queue of a thread to send and process information. In this example, the runonuithread (runnable action) function of the activity class is used. The main function of this function is to run the specified operation in the UI thread. If the current thread is a UI thread, then take the action and immediately execute it. If the current thread is not a UI thread, send a message to the event queue of the UI thread.
The whole program is introduced. The interface after running the program is as follows:


Note: Open the androidmanifest. xml file and find that <Application> has a tag that has never been seen before, as shown below:

<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"      package="aexp.junit"      android:versionCode="1"      android:versionName="1.0.0">    <uses-permission android:name="android.permission.WRITE_CONTACTS"/>    <uses-permission android:name="android.permission.READ_CONTACTS"/>    <application android:label="@string/app_name">        <uses-library android:name="android.test.runner"/>        <activity android:name=".JUnit"                  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="4" /></manifest> 

Summary
This example has been learned. Although it is relatively simple, it gives us a clear understanding of how to use androidtestrunner. We will continue to introduce some complex examples for further study.

References:
Android and JUnit


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.