A brief talk on the Android Studio unit test _android

Source: Internet
Author: User
Tags assert log log zts

The Android Studio Run Project has to wait a few minutes for pain points and has to study the unit tests of Android studio.

In fact, my goal is very simple, without the view of the operation of the premise, test some activity life cycle, or network pull data some processing, such as parsing JSON data ah, do network request Ah, etc., that is, the model layer of testing. These do not need to operate the view, but in no unit test environment, such as our network request some data, Log print to see whether the request is successful, but also use the simulator or real machine run a project, spend several minutes, this is intolerable.

As a then, powerful Android Studio also takes this into account, giving us a simple unit test class.

Let's take a quick look at the study.

First of all, to understand some of the names to facilitate the following introduction and use:

In Java we've worked with JUnit unit tests, and Android is based on the Java language, so there's also a JUnit unit test. In the Android unit test you need to import dependencies:

androidTestCompile 'junit:junit:4.12'
testCompile 'junit:junit:4.12'

Where the test directory is the directory that executes unit test code on the computer, androidtest the directory that executes the unit test code on the Android device. The following figure:

Some of the test classes on Android's own junit unit tests (androidtest tests need to run on a simulator or a real machine)

1. Instrumentationtestcase Frame:

Instrumentation is similar to activity, except that the activity requires an interface, and instrumentation is not, and we can interpret it as a kind of startup capable of monitoring other classes without a graphical interface ( A tool class that is declared with target package.

For example, use Instrumentationtestcase to start an activity:

Create a new Java class under Androidtest and inherit from Instrumentationtestcase to write a public void method, but if the method name starts with test, such as Testpublishsubject, No need for @test annotations

public class Testsubject extends Instrumentationtestcase {
  private static final String Log_tag = "Test";
 
  public void Testpublishsubject () {
 
    launchactivity ("Demo.zts.com.demo", secondactivity.class,null);
  }

2, applicationtestcase--test the entire application of the class. It allows you to inject a simulated context into the application, initialize the test parameters before the application starts, and check the application before destroying the application.

Using the context, you can browse resources, files, databases, and so on. A base class is a androidtestcase, typically a subclass of it, associated with a particular component.

The test code is as follows:

public class MyApp extends application {
  @Override public
  void OnCreate () {
    super.oncreate ();
    String app_name = Getresources (). getString (r.string.app_name);
    LOG.I ("MyApp", "...) Myapp....app_name. ... "+app_name");
  }
public class Applicationtest extends applicationtestcase<myapp> {public
  applicationtest () {
    super ( Myapp.class);
  }
  public void Teststart () {
    String str = null;
    str = mcontext.getresources (). getString (r.string.app_name);
    LOG.I ("...", "...........) Applicationtest ... app_name. ... "+str);"... .........
  

Log logs:

07-22 23:27:10.276 32259-32259/demo.zts.com.demo I/myapp: ..... Myapp....app_name..........demo
07-22 23:27:10.276 32259-32319/demo.zts.com.demo I/testrunner:started:teststart (demo.zts.com.demo.ApplicationTest )
07-22 23:27:10.286 32259-32319/demo.zts.com.demo i/......... Applicationtest..........app_name..............demo

3, Activityunittestcase-a single test class for a single activity. Using it, you can inject the simulated context or application, or both. It is used to unit test the activity. That means you can test the individual activity, although it also needs to be started with a simulator or a real machine, but you're only starting the activity that you need to test, not the other activity.
The test code is as follows:

The activity to test

public class Mainactivity extends appcompatactivity {@Override protected void onCreate (Bundle savedinstancestate) {
    Super.oncreate (savedinstancestate);
    Setcontentview (R.layout.activity_main); System.out.println ("........)
    Mainactivity......oncreate ...... ... ");

  LOG.I ("Mainactivity", "... onCreate .... ...).". ..... ..... ..... ..... ..... ..... ..... ..... ...
    } @Override protected void OnStart () {Super.onstart (); System.out.println ("........)
    Mainactivity......onstart ...... ... ");
  LOG.I ("Mainactivity", "... onStart .... ...).". ..... ..... ..... ..... ..... ..... ..... ..... ...
    } @Override protected void OnStop () {super.onstop (); System.out.println ("........)
    Mainactivity......onstop ...... ... ");
  LOG.I ("Mainactivity", "... onStop .... ...).". ..... ..... ..... ..... ..... ..... ..... ..... ...
    } @Override protected void OnDestroy () {Super.ondestroy (); System.out.println ("........)
    Mainactivity......ondestroy ...... ... "); LOG.I ("Mainactivity", ".... OnDestroy ..... ........................... ...

 }
}

Test class

public class Testactivity extends activityinstrumentationtestcase2<mainactivity> {

  private context ctx;

  Public testactivity () {
    super (Mainactivity.class);
  }

  @Override
  protected void SetUp () throws Exception {
    super.setup ();
    CTX = Getactivity (). Getapplicationcontext ();

  public void Teststart () {
    Intent Intent = new Intent (CTX, mainactivity.class);
    Intent.setflags (intent.flag_activity_new_task);
    Ctx.startactivity (intent);
    LOG.I ("Testactivity", "... startactivity ... ...) ..."... ..... ..... ..... ..... ..... ..... ..... ..... ...

  

Test log log:

* 07-22 23:39:44.146 3171-3171/demo.zts.com.demo i/system.out: ........ Mainactivity......oncreate .......
07-22 23:39:44.146 3171-3171/demo.zts.com.demo i/mainactivity: ...... ... onCreate.. ............................
07-22 23:39:44.151 3171-3171/demo.zts.com.demo D/mzperfobserver:demo.zts.com.demo onCreate consume MS
07-22 23:39:44.151 3171-3171/demo.zts.com.demo i/system.out: ........ Mainactivity......onstart .......
07-22 23:39:44.151 3171-3171/demo.zts.com.demo i/mainactivity: ... ... onStart ....... ..... ..... ..... .... ..... ..... .... .... ..... .... ..... .... ..... .... ..... .... .... ...... ..... ...... .... ...
07-22 23:39:44.326 3171-3171/demo.zts.com.demo d/openglrenderer:enabling Debug mode 0
07-22 23:39:44.361 3171-3171/demo.zts.com.demo i/system.out: ........ Mainactivity......onstop .......
07-22 23:39:44.361 3171-3171/demo.zts.com.demo i/mainactivity: ... ... onStop ....... ..... ..... ..... .... ..... ..... .... .... ..... .... ..... .... ..... .... ..... .... .... ...... ..... ...... .... ...

07-22 23:39:44.421 3171-3224/demo.zts.com.demo i/testactivity: ...... ... startactivity.. ............................

There are a lot of common tests, such as servicetestcase,providertestcase2 and so on, we need to slowly ponder.

Some of the test classes on Android's own JUnit unit tests (test tests, no simulators, computers running directly)

For example, I need to test a piece of Java code, and this Java code and Android does not matter, that is, do not have to Android resources, such as context,activity and so on, plainly is a simple Java test, of course, Hey, Android Studio can also do Java code testing.

The test code is as follows, the test 4+4 equals several:

public class Exampleunittest {
  @Test public
  void Testadd () {

    int i = 0;
    i = 4+4;
    System.out.print (".......) "+i);
    LOG.I ("TAG", "...")
    , "+i ...".... Compare I to be equal to 8, the same words pass the test!!!
    Assert.assertequals (8, I);
  }
}

Test success:

The above test class is run-click Test Right button-select Runxxxxx

/********************* Gorgeous split Line ***********************/

Look for a while did not seem to solve the article originally mentioned a pain point ah, is that I need to test the resources of Android, but do not want to run a cumbersome simulator or real machine, how to do? Mom, it's been cheated. Pay back the money.-_-、、、 Indeed, the test method mentioned above does not solve the pain point of Please simulator test, but the androidtest based on the simulator unit test is really convenient for us to do some individual function test, and can do UI test, because need Simulator or real machine, so UI Or the view test is fine. There are test tests that can be done with Java code tests that do not require Android resources, and are handy in Android development without having to run eclipse to test the direct Android studio.

Fooled, then fooled-_-////

In fact, to get out of the simulator or the real machine, but also to do the use of Android resources testing, such as using the context, browsing resources, files, databases and so on. It's also possible,!!!. Then there's only a third party test framework. Robolectric

666, are you here to do the publicity?-_-、、、 But it is really good to use, but also to solve our pain point.

Then use a demand to explain the robolectric test, lest I fool you.

Get the Android directory under the assets json01.txt file is a section of JSON data, so that after parsing, parsing the data display. Analysis: This requirement is related to the resources under Android, and we use Robolectric to do unit testing without the need for analog or real machine support.

Where the JSON data

{
 ' name ': ' coolxing ', ' Age
 ': '
 Male ': true, ' address
 ': {Street
  ': ' Huilongguan ',
  ' city ' : "Beijing",
  "Country": "The"

First you need to rely on robolectric, injecting dependencies under your app module:

Testcompile ' org.robolectric:robolectric:3.0 '
Note that it's testcompile, not androidtestcompile, or you need to start the simulator. And the test class is under test.

Test class:

 @RunWith (robolectricgradletestrunner.class) @Config (constants = Buildconfig.class,
    SDK =) public class MainActivityTest2 {@Test public void Testjson () {String str = null;

    str = RuntimeEnvironment.application.getResources (). getString (R.string.app_name);
    Assetmanager am = null;
    am = RuntimeEnvironment.application.getAssets ();
    String strdata = null;
      try {inputstream InputStream = Am.open ("Json01.txt");
      byte buf[] = new byte[1024];
      Inputstream.read (BUF);
      strdata = new String (BUF);
      Strdata =strdata.trim ();
    Strdata.trim ();
    The catch (IOException e) {} jsonbean foo = new Gson (). Fromjson (Strdata, Jsonbean.class);
    System.out.println ("...") ("+foo.name. ...)", and the other is a very, very, very, very ...
    System.out.println ("...") ("+foo.address. ...)", and the other is a very, very, very, very ...
  System.out.println ("...") ("+foo.age. ...)", and the other is a very, very, very, very ... }
}

Test results:

Look, we use application to get the resources under Android, but not like the above androidtestcompile need simulator, is not very 6, my Computer configuration is relatively low, this test requires 40S more, but the real machine is much faster.

am = RuntimeEnvironment.application.getAssets();

A few points to note, the class head needs to declare @ annotation:

@RunWith(RobolectricGradleTestRunner.class)
@Config(constants = BuildConfig.class, sdk = 21)

And the test method begins with Textxxx (), as above Testjson (), and the method also requires @test annotations!!!
Robolectric can also test activity, such as:

@RunWith (Robolectricgradletestrunner.class)
@Config (constants = buildconfig.class, SDK =) public
class MainActivityTest2 {
  @Test public
  void Testmainactivity () {

    mainactivity mainactivity = Robolectric.setupactivity (mainactivity.class);
    Mainactivity.findviewbyid (R.ID.MAIN_TV). PerformClick ();


    Intent expectedintent = new Intent (mainactivity, secondactivity.class);

    Shadowactivity openactivity = shadows.shadowof (mainactivity);
    Intent actualintent = openactivity. getnextstartedactivity ();

    Assert.assertequals (Expectedintent, actualintent);

  }

which

MainActivity mainActivity = Robolectric.setupActivity(MainActivity.class);

This code is the start of the mainactivity lifecycle

The Robolectric unit test class is also started with the test class above, select-mainactivitytest2--Right--select Run MainActivityTest2

Okay, here's the unit test.

In fact, I also just preliminary understanding, above those basic is also I do project need I just to learn to use, there are a lot of powerful features we explore slowly.

Related Article

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.