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.