Transferred from: http://blog.csdn.net/qingchunjun/article/details/42580937
February 3, 2015 update:
Some friends throw a InputStream cannot be null exception when attempting this method with a real machine. This exception is due to the fact that ADB runs in the Robotium framework when it is fully running on the phone, and its permissions are limited by the Android system. The original frame was used on the PC side, which led to the appearance of the exception. The specific reason analysis can see my this article: http://blog.csdn.net/qingchunjun/article/details/43343735.
The modification of this problem can be referred to here: http://blog.csdn.net/qingchunjun/article/details/43448371
Note: If you are using a real machine, be sure to use a phone that has already been rooted, otherwise the file will not be born because of the system directory permission limit.
Robotium is the next best automated testing Framework on Android platform, and it's the advantage of Android platform Automation it should be clear to people who see this article. But the advantages of the advantages, the shortcomings are more, the most obvious shortcomings have two, one must be and the system signed by the test is consistent, the second is not to do any cross-process operation.
Many small partners know how to use Robotium and know it has these limitations, but they don't know why. To put it simply, the main reason for Robotium's congenital deficiency is that it is based on the instrumentation mechanism, which has both advantages and disadvantages. The benefit is that it is injected into the process through instrumentation, and thus runs in the same process space as the process being tested, making it very easy to identify the objects under test and manipulate them. The downside is that since Robotium has been "fit" with the application under test, it is naturally isolated from other processes by the Android process isolation mechanism, and cannot manipulate any objects across processes, as shown in (1).
Figure (1) Android process sandbox
In fact, the use of the same signature for single-application testing is not difficult, there are many online application of re-signing methods and tools for everyone to use. But can not cross-process operations really become the robotium biggest weakness, many third-party application testing more or less have some cross-process operation of the test scenario, so many people because of this problem and give up the robotium, it is a pity ah.
As one of the Robotium's hardcore powders (I was the first to touch Android Automation testing is the Robotium), intermittent for several years, has always felt that the Android platform is the best use of one of the automated testing tools. For Robotium how to break through the limitations of the process has also done some research, online more than the solution of more than the following several:
1. Write your own service to do the server, based on Aidl or write sockets and monkeyserver to communicate, and then in the Robotium test script call interface method to perform cross-process operations indirectly, this way can refer to the following example of this article:/http www.robotium.cn/archives/584. The author of the article just give out the idea, I have to follow this method to achieve, found that the advantages of this method is relatively stable, the disadvantage is that the implementation is indeed more complex, and some operations can not find out the existing system Aidl interface to operate, such as the call to take pictures, so in fact, the example is not many, The technical limitations are large.
2. Based on broadcast and service services. The implementation of this method can be referred to http://www.ltesting.net/ceshi/open/kygncsgj/2013/0507/206229.html the description of this article. This method I did not personally to try, but it is not difficult to find that this method is slightly simpler, but the method seems to require a system signature, and write their own broadcast and service to invoke the system API, it is not very difficult to use this method is generally not recommended.
The integration of these cross-process solutions, in fact, are not very ideal, for many beginners is not too difficult to achieve is the limitations are relatively large, has not found a more ideal solution. Until later on in the Testerhome saw a technology very cattle brothers to the usual adb command made a very complete package (PS: Really is full, at least the usual ADB commands are in, I didn't even think of the ADB command can do so many things), made a separate test aids. I suddenly wonder why I can't use the ADB command to assist Robotium in cross-process operations? Since the framework already encapsulates all ADB-based operations, and the ADB is not system-constrained, there is no problem in the theory of cross-process operations based on this framework. Later, after the test, the effect is good, lightweight, easy to operate, easy to use, and easy to cross the process, really home testing, cock silk anti-Attack of the necessary artifact ah. Well, gossip doesn't say much, so let's take a closer look at how it's used.
Let's start with a simple introduction to the common interface of this ADB command framework. There are three main packages in this framework, each of which is described below:
Xuxu.autotest There are two main classes in this package, one is Adbdevice, which encapsulates some of the operations commonly used in functional testing, such as getting the name and package name of the current activity, obtaining the device resolution, closing the application, and clicking on objects. Another class is xuimage, as the name implies, encapsulates some common picture operations, such as getting a picture of a specified boundary, comparing a picture to a consistent, capturing a picture, and so on.
Xuxu.autotest.element This package is mainly used to obtain the object under test, mainly encapsulates a position object, which is used to obtain a measured object through the class Name, Id, Contentdesc and other properties. The underlying is the XML file that is used by Uiautomator to dump the current UI XML file, which can be obtained to all object nodes.
Xuxu.autotest.utils This package mainly provides the operation of the date datetime, imageutil the operation of the picture and the operation of the regular expression and shell statements, convenient for everyone to use. In general, the overall framework of the interface design is very complete, you can achieve a lot of common functions, specific features you can see the source code and help the document to explore.
The next step is to move on to our theme, the cross-process. To make it easy for everyone to understand, I'll choose two very common cross-process scenarios in this article to illustrate how you can take pictures and phone calls across processes, which are popular cameras .
Example 1: Take a picture of a camera across the process.
The program is very simple, the program interface as shown in (2):
Figure (2)
Click on the first screen of the "Take photos" button, enter the interface 2, click on the "Take a picture" after the system to start the camera, when the user presses the photo function key, the system can be taken by the user's photos displayed in the application, in case of subsequent browsing or upload. Since the camera application and the test application we wrote are two different applications, this is a typical cross-process operation, and the Robotium framework itself cannot operate on the camera interface.
Let's look at how the key test project was created. The method of creating the test project is very simple and the following steps are done:
1. First create a routine test project in accordance with the conventional Android test engineering method.
2. Introduction of Robotium and Adbforandroid jar packages in the project.
In this way, our test project is ready.
The next step is to write the test script. Since the Adbforandroid framework locates and locates the object under test based on its related attributes, it is first to clarify the information of the objects on the cross-process interface that we are manipulating, which we can see through a number of ready-made tools, I'm here to choose the uiautomatorviewer that comes with Android. First, manually open the program under test on the simulator, enter the camera interface, and use Uiautomatorviewer to view the interface element information as shown in (3):
Figure (3)
As we can see, the properties of the photo button we want to click are all shown in the list in the lower right corner of the figure (3). So which one should we choose? This issue depends on which properties the Adbforandroid framework supports to get elements. By querying its help documentation, we know that the current method of finding elements commonly used in this framework is as follows:
Because the emulator version I'm using now is 4.2.2, so uiautomatorviewer cannot display the id attribute, and if you use the 4.3 version above, you can see the id attribute of the element.
Now, in this case, we'd better choose the Contentdesc property to locate the object. The code is simple, as follows:
[Java]View Plaincopy
- Element element =position.findelementbycontentdesc ("Shutter button");
- Adbdevice.tap (Element); //Click the Take photo button
OK, next click on the photo button, the photo function will also let you choose whether to confirm or cancel the operation, as shown in (4):
Figure (4)
So, we know by query, this is used to determine the "√" button, its properties can be used to locate the only class attribute. However, it is important to note that at this point, because we are using the class attribute, we can see that the class attribute on the interface is the same object as the "√" button we want to click, so we must use the Findelementsbyclass method. This method returns a Arraylist<element>, so we can write the following code to get the list of all elements with the class attribute "Android.widget.ImageView".
[Java]View Plaincopy
- Arraylist<element> imageviews =position.findelementsbyclass ("Android.widget.ImageView");
OK, after writing, now the question is, exactly which index in this array is the corresponding "√" button we want to click? After experimenting, I found that when several identical elements in the interface were returned to the array, the corresponding element position was from top to bottom, from left to right, so the index of the button we were going to click on was 4. So click on its code as follows:
[Java]View Plaincopy
- Adbdevice.tap (Imageviews.get (4)); //2 is x,3 is a re-shoot, 4 is √
After the above code is finished, the interface will go back to our test program, the operation will not need me to say more, we look at it is very simple?
Example 2, cross-process operation of the call
With the foundation of the first example, the second example is very well implemented. The program being tested is very simple, as shown in (5):
Figure (5)
After tapping "Dial this number", the system automatically enters the dial-up interface, so it is also a typical cross-process test scenario.
The implementation method is the same as in Example 1, the first is to use Uiautomatorviewer to view the object information in the interface, and then use the corresponding method to manipulate the object. And in this case, I also show you another situation, that is, some cross-process operations not only to operate, but also to obtain some object properties to verify, which is also basic. Here I give my test code directly (slightly encapsulated):
[Java]View Plaincopy
- Public Boolean callutil (String callnumber) {
- element element;
- Boolean result;
- //Verify that the correct number is dialed
- if (callnumber.length () = = one ) {//normal number needs to be converted to x xxx-xxx-xxxx format
- Stringformatcallnumber = callnumber.substring (0, 1) + " " "+callnumber.substring (1, 4) + "-"+ Call Number.substring (4,7) +"-" + callnumber.substring (7, Callnumber.length ());
- Element= Position.findelementbytext (Formatcallnumber);
- try{
- Thread.Sleep (2000); //thread sleeps for 2 seconds
- }catch (Interruptedexception e) {
- E.printstacktrace ();
- }
- }else{
- Element= Position.findelementbytext (Callnumber); //In addition to normal numbers, numbers in other formats are not formatted for conversion
- }
- if (element! = null) {
- Result= true;
- }else{
- Result= false;
- }
- element= Position.findelementbycontentdesc ("End"); //Hang up the phone
- if (element! = null) Adbdevice.tap (element);
- return result;
- }
OK, the whole process is very simple. I believe that the use of Robotium shoes should not be any problem, all the code is very easy to understand.
I believe that through the previous examples, you can find that this is "the simplest in history," robotium cross-process operation solution I guess no one would object, it's not exaggerating the facts, bo people eyeball, it is very simple, the function is very strong. I don't have to say anything else, so I'll come back to the framework to summarize the following:
Advantages:
1. It is very full, basically encapsulates all the common commands of the ADB, which is itself an adb command used Daquan.
2. The frame interface design is clear and understandable, simple and clear, packaged into a jar package, it is also very convenient to use. In addition, we hope that everyone can look at its source code and understand its implementation details, the author encapsulation is still very good, it is worth learning, and not just to use it simply.
Current known deficiencies:
1. Mobile phone version must be more than 4.1, that is, at least support Uiautomator mobile phone, because the framework itself is dependent on uiautomator to dump out the object layout XML file, finally get the coordinates of the object to operate, so your phone version itself does not support uiautomator words, You cannot implement the dump operation.
2. If it is a real machine, it must be rooted.
2. Some objects are uiautomator and can not be identified and manipulated, of course, the framework is powerless. For example, the top of the screen notification message Bar object, all the tools can not be displayed and recognized, this certainly no way, and also such as input text when the pop-up keyboard button object, and so on, can not be recognized, we may try.
The improvements you want to try later:
1. For the support of mobile phone version, the individual feel that there is a way to solve the problem of national salvation. That is, we can slightly modify the source code, added to determine the phone version of the codes, judging the current mobile phone version if more than 4.1, directly through the uiautomator to dump, if less than 4.1, then read the PC on the pre-export to the specified location of the XML file. In this case, if you use a mobile phone is not more than 4.1 version, only need to be tested in the application with more than 4.1 version of the mobile phone through the uiautomator first dump to a specified path of the PC on the line, so the effect should be the same, as long as the final object coordinates can be OK.
2. Add some more useful functions. For example, the object can now be found according to text, but in fact, many times we may get the object, but want to use this object to get other properties of the object, so it is recommended to add similar getxxxxbyelement (Element e) Such a method, have time to try, hehe.
These are just some of my personal ideas, if you have some other suggestions, also welcome everyone to come up, together to improve this very practical framework.
Finally, thanks again to the author of the Adbforandroid Framework: Xuxu.
Want to study the framework of the source of children's shoes, can go to github address download: Https://github.com/gb112211/Adb-For-Robotium
The relevant sample works in this article source code (including the tested program and test program) download
In addition, if you really do not know how to use this framework of children's shoes, you can refer to the glorious road of the beauty of the instructor's video, there is talk about how to use this framework: Http://pan.baidu.com/s/1i3raNv3?qq-pf-to=pcqq.group
Robotium cross-process operations based on ADB framework