Automatic Android* Testing with UiAutomator
来源:互联网 发布:网络教育学士学位证 编辑:程序博客网 时间:2024/05/16 06:35
Automatic Android* Testing with UiAutomator
Updated January 23, 2014
I want to tell you about a wonderful tool to automatically test the UI of Android* applications. The name of this tool is UiAutomator. You can find all the latest documentation here: http://developer.android.com/tools/help/uiautomator/index.html and http://developer.android.com/tools/testing/testing_ui.html
UiAutomator has some strengths and weaknesses.
Advantages:
Disadvantages:
Script development
To introduce working with UiAutomator, I want to show a simple program. This program is the standard Android Messaging application and sends SMS messages to any phone number.
Here's a short description of the actions that we implemented:
- Find and run application
- Create and send SMS messages
As you can see it’s very easy.
Preparation for the test
To analyze the UI interface we will use uiautomatorviewer.
uiautomatorviewer shows a split screenshot of all the UI components in the Node Detail so you can see their different properties. From the properties you can find a desired element.
Customizing the Development Environment
If you use Eclipse*:
- Create a new Java project in Eclipse. We will call our project: SendMessage
- Right click on your project in the Project Explorer and click on the Properties item
- In Properties, select Java Build Path and add the required libraries:
If you are using a different development environment, make sure that the android.jar and uiautomator.jar files are added to the project settings.
Create a script
Create a project in a previously created new file with the Java class. Call it SendMessage. This class is inherited from class UiAutomatorTestCase and using keys Ctrl + Shift + o (for Eclipse), add the required libraries.
Create three functions to test this application:
- Search and run the application
- Send SMS messages
- Exit to the main menu of the application
Create a function from which we will run all these features—a kind of main function:
1
public
void
test() {
2
// Here will be called for all other functions
3
}
Function to find and run the application
This function is simple. We press the Home button and once on the main window, open the menu and look for the icon with the application. Click on it and start the application.
01
private
void
findAndRunApp() throws UiObjectNotFoundException {
02
// Go to main screen
03
getUiDevice().pressHome();
04
// Find menu button
05
UiObject allAppsButton =
new
UiObject(
new
UiSelector()
06
.description(
"Apps"
));
07
// Click on menu button and wait new window
08
allAppsButton.clickAndWaitForNewWindow();
09
// Find App tab
10
UiObject appsTab =
new
UiObject(
new
UiSelector()
11
.text(
"Apps"
));
12
// Click on app tab
13
appsTab.click();
14
// Find scroll object (menu scroll)
15
UiScrollable appViews =
new
UiScrollable(
new
UiSelector()
16
.scrollable(
true
));
17
// Set the swiping mode to horizontal (the default is vertical)
18
appViews.setAsHorizontalList();
19
// Find Messaging application
20
UiObject settingsApp = appViews.getChildByText(
new
UiSelector()
21
.className(
"android.widget.TextView"
),
"Messaging"
);
22
// Open Messaging application
23
settingsApp.clickAndWaitForNewWindow();
24
25
// Validate that the package name is the expected one
26
UiObject settingsValidation =
new
UiObject(
new
UiSelector()
27
.packageName(
"com.android.mms"
));
28
assertTrue(
"Unable to detect Messaging"
,
29
settingsValidation.exists());
30
}
All of the class names, the text on the buttons, etc. came from uiautomatorviewer.
Send SMS messages
This function finds and presses the button for writing a new application, enters a phone number for whom to send a text message to, and presses the send button. The phone number and text pass through the function arguments:
01
private
void
sendMessage(String toNumber, String text) throws UiObjectNotFoundException {
02
// Find and click New message button
03
UiObject newMessageButton =
new
UiObject(
new
UiSelector()
04
.className(
"android.widget.TextView"
).description(
"New message"
));
05
newMessageButton.clickAndWaitForNewWindow();
06
07
// Find to box and enter the number into it
08
UiObject toBox =
new
UiObject(
new
UiSelector()
09
.className(
"android.widget.MultiAutoCompleteTextView"
).instance(0));
10
toBox.setText(toNumber);
11
// Find text box and enter the message into it
12
UiObject textBox =
new
UiObject(
new
UiSelector()
13
.className(
"android.widget.EditText"
).instance(0));
14
textBox.setText(text);
15
16
// Find send button and send message
17
UiObject sendButton =
new
UiObject(
new
UiSelector()
18
.className(
"android.widget.ImageButton"
).description(
"Send"
));
19
sendButton.click();
20
}
The fields for the phone number and text message display do not have any special features, as neither the text nor any description of these fields is available. Therefore, I can find them by using in this instance an element in its ordinal position in the hierarchy of the interface.
To add the ability to pass parameters to the script we can specify the number of where we want to send the message, as well as text messages. The function test () initializes the default settings, and if any of the parameters were sent messages via the command line, the substitution of the default settings would be:
01
// Default parameters
02
String toNumber =
"123456"
;
03
String text =
"Test message"
;
04
05
String toParam = getParams().getString(
"to"
);
06
String textParam = getParams().getString(
"text"
);
07
if
(toParam != null) {
08
// Remove spaces
09
toNumber = toParam.trim();
10
}
11
if
(textParam != null) {
12
text = textParam.trim();
13
}
Thus we will be able to pass parameters from the command line in the script using the small key -e, the first name of the parameter, and the second value. For example, my application sends the number to send " 777777 »:-e to 777777
There are some pitfalls. For example, this application doesn’t understand some characters and fails. It is impossible to convey just text with some characters , it does not perceive them and fails. Here are some of them: space, &, <, > , (,) , ", ' , as well as some Unicode characters. I replace these characters when applying them to script a string, such as a space line : blogspaceblog. So when the script starts UiAutomator, we use a script that will handle our input parameters. We add the function test (), where we check whether there are options, parse parameters, and replace them with real characters. Here is a sample code along with demonstrating what we inserted earlier:
01
if
(toParam != null) {
02
toParam = toParam.replace(
"blogspaceblog"
,
" "
);
03
toParam = toParam.replace(
"blogamperblog"
,
"&"
);
04
toParam = toParam.replace(
"bloglessblog"
,
"<"
);
05
toParam = toParam.replace(
"blogmoreblog"
,
">"
);
06
toParam = toParam.replace(
"blogopenbktblog"
,
"("
);
07
toParam = toParam.replace(
"blogclosebktblog"
,
")"
);
08
toParam = toParam.replace(
"blogonequoteblog"
,
"'"
);
09
toParam = toParam.replace(
"blogtwicequoteblog"
,
""
");
10
toNumber = toParam.trim();
11
}
12
if
(textParam != null) {
13
textParam = textParam.replace(
"blogspaceblog"
,
" "
);
14
textParam = textParam.replace(
"blogamperblog"
,
"&"
);
15
textParam = textParam.replace(
"bloglessblog"
,
"<"
);
16
textParam = textParam.replace(
"blogmoreblog"
,
">"
);
17
textParam = textParam.replace(
"blogopenbktblog"
,
"("
);
18
textParam = textParam.replace(
"blogclosebktblog"
,
")"
);
19
textParam = textParam.replace(
"blogonequoteblog"
,
"'"
);
20
textParam = textParam.replace(
"blogtwicequoteblog"
,
""
");
21
text = textParam.trim();
22
}
Exit to the main menu of the application
This function is the simplest of all those that we have implemented. I simply press a button in a loop back until it shows the button to create a new message.
01
private
void
exitToMainWindow() {
02
// Find New message button
03
UiObject newMessageButton =
new
UiObject(
new
UiSelector()
04
.className(
"android.widget.TextView"
).description(
"New message"
));
05
06
// Press back button while new message button doesn't exist
07
while
(!newMessageButton.exists()) {
08
getUiDevice().pressBack();
09
}
10
}
Source code
So here is our code:
001
package blog.send.message;
002
import com.android.uiautomator.core.UiObject;
003
import com.android.uiautomator.core.UiObjectNotFoundException;
004
import com.android.uiautomator.core.UiScrollable;
005
import com.android.uiautomator.core.UiSelector;
006
import com.android.uiautomator.testrunner.UiAutomatorTestCase;
007
008
public
class
SendMessage extends UiAutomatorTestCase {
009
public
void
test() throws UiObjectNotFoundException {
010
// Default parameters
011
String toNumber =
"123456"
;
012
String text =
"Test message"
;
013
014
String toParam = getParams().getString(
"to"
);
015
String textParam = getParams().getString(
"text"
);
016
if
(toParam != null) {
017
toParam = toParam.replace(
"blogspaceblog"
,
" "
);
018
toParam = toParam.replace(
"blogamperblog"
,
"&"
);
019
toParam = toParam.replace(
"bloglessblog"
,
"<"
);
020
toParam = toParam.replace(
"blogmoreblog"
,
">"
);
021
toParam = toParam.replace(
"blogopenbktblog"
,
"("
);
022
toParam = toParam.replace(
"blogclosebktblog"
,
")"
);
023
toParam = toParam.replace(
"blogonequoteblog"
,
"'"
);
024
toParam = toParam.replace(
"blogtwicequoteblog"
,
""
");
025
toNumber = toParam.trim();
026
}
027
if
(textParam != null) {
028
textParam = textParam.replace(
"blogspaceblog"
,
" "
);
029
textParam = textParam.replace(
"blogamperblog"
,
"&"
);
030
textParam = textParam.replace(
"bloglessblog"
,
"<"
);
031
textParam = textParam.replace(
"blogmoreblog"
,
">"
);
032
textParam = textParam.replace(
"blogopenbktblog"
,
"("
);
033
textParam = textParam.replace(
"blogclosebktblog"
,
")"
);
034
textParam = textParam.replace(
"blogonequoteblog"
,
"'"
);
035
textParam = textParam.replace(
"blogtwicequoteblog"
,
""
");
036
text = textParam.trim();
037
}
038
findAndRunApp();
039
sendMessage(toNumber, text);
040
exitToMainWindow();
041
}
042
// Here will be called for all other functions
043
private
void
findAndRunApp() throws UiObjectNotFoundException {
044
// Go to main screen
045
getUiDevice().pressHome();
046
// Find menu button
047
UiObject allAppsButton =
new
UiObject(
new
UiSelector()
048
.description(
"Apps"
));
049
// Click on menu button and wait new window
050
allAppsButton.clickAndWaitForNewWindow();
051
// Find App tab
052
UiObject appsTab =
new
UiObject(
new
UiSelector()
053
.text(
"Apps"
));
054
// Click on app tab
055
appsTab.click();
056
// Find scroll object (menu scroll)
057
UiScrollable appViews =
new
UiScrollable(
new
UiSelector()
058
.scrollable(
true
));
059
// Set the swiping mode to horizontal (the default is vertical)
060
appViews.setAsHorizontalList();
061
// Find Messaging application
062
UiObject settingsApp = appViews.getChildByText(
new
UiSelector()
063
.className(
"android.widget.TextView"
),
"Messaging"
);
064
// Open Messaging application
065
settingsApp.clickAndWaitForNewWindow();
066
067
// Validate that the package name is the expected one
068
UiObject settingsValidation =
new
UiObject(
new
UiSelector()
069
.packageName(
"com.android.mms"
));
070
assertTrue(
"Unable to detect Messaging"
,
071
settingsValidation.exists());
072
}
073
074
private
void
sendMessage(String toNumber, String text) throws UiObjectNotFoundException {
075
// Find and click New message button
076
UiObject newMessageButton =
new
UiObject(
new
UiSelector()
077
.className(
"android.widget.TextView"
).description(
"New message"
));
078
newMessageButton.clickAndWaitForNewWindow();
079
080
// Find to box and enter the number into it
081
UiObject toBox =
new
UiObject(
new
UiSelector()
082
.className(
"android.widget.MultiAutoCompleteTextView"
).instance(0));
083
toBox.setText(toNumber);
084
// Find text box and enter the message into it
085
UiObject textBox =
new
UiObject(
new
UiSelector()
086
.className(
"android.widget.EditText"
).instance(0));
087
textBox.setText(text);
088
089
// Find send button and send message
090
UiObject sendButton =
new
UiObject(
new
UiSelector()
091
.className(
"android.widget.ImageButton"
).description(
"Send"
));
092
sendButton.click();
093
}
094
095
private
void
exitToMainWindow() {
096
// Find New message button
097
UiObject newMessageButton =
new
UiObject(
new
UiSelector()
098
.className(
"android.widget.TextView"
).description(
"New message"
));
099
100
// Press back button while new message button doesn't exist
101
while
(!newMessageButton.exists()) {
102
getUiDevice().pressBack();
103
sleep(500);
104
}
105
}
106
}
Compile and run the test UiAutomator
- To generate configuration files for test assembly, run the following command from the command line:
<android-sdk>/tools/android create uitest-project -n <name> -t <target-id> -p <path>
Where <name> is the name of the project that was created to test UiAutomator (in our case: SendMessage), <target-id> is the choice of device and Android API Level (you can get a list of installed devices, the team (<android-sdk> / tools / android list targets), and <path> is the path to the directory that contains the project. - You must export the environment variable ANDROID_HOME:
- Go to the directory with the project file, build.xml, which was generated in step 1, and run the command:
ant build - Copy the compiled JAR file to the device using the adb push:
adb push <path_to_output_jar> /data/local/tmp/
In our case, it is:
adb push <project_dir>/bin/SendMessage.jar /data/local/tmp/ - And run the script:
adb shell uiautomator runtest /data/local/tmp/SendMessage.jar –c blog.send.message.SendMessage
About the Author
Egor Churaev (egor.churaev@intel.com) – Software Intern
Related Articles and Resources:
- Automatic Android* Testing with UiAutomator
- Android UI Testing with uiautomatorviewer and uiautomator
- Unit Testing with Android Studio
- Unit Testing With Android Studio
- Android Testing Fundamentals 2, robotium, uiautomator, monkeyrunner and monkey
- uiautomator-testing learning notes
- Android AsyncTask testing with Android Test Framework
- Android user interface testing with Robotium - Tutorial
- android uiautomator
- Android uiautomator
- Interfacing with Automatic Differentiation
- Generate Android testing reports in XML/HTML with Android CTS
- Android application testing with the Android test framework
- Automatic Conformance Testing of Web Services
- Robotium_Automated UI testing for Android applications with Robotium
- Recording and Performance testing Android applications with HP Loadrunner VuGen
- Unit testing with CPPUnit
- Testing with untrusted Https
- htop的源码编译方法
- 网易前端面试
- Swift 4.0 中的 open,public,internal,fileprivate,private
- springcloud配置中心(config)
- javaSE 常用系统类 包 访问控制符
- Automatic Android* Testing with UiAutomator
- wireless-tools
- 13-javascript map/reduce
- Android Api demo系列(24) (Graphics>RoundRects(讲解的是GradientDrawable的使用))
- 性格分析工具
- vue安装及创建项目
- oracle 的csv 导入到mongodb 部分字段会转换成int numberlong 修改方式
- 浏览器cannot read property 'msie' of undefined的解决方法
- Java面试题全集(上)