Appuim Source Analysis (Bootstrap)
Skyseraph Jan. 26th 2017
Email:[email protected]
More highlights please visit Skyseraph personal site directly: www.skyseraph.com
Aboutappuim
Appium is an automated testing open source tool that supports native applications, Web applications, and hybrid applications on IOS and Android platforms.
Here is a key point, cross-platform. Learn more about Appuim multi-platform support, refer to the official Platform-support
Related concepts
- C/S architecture
The core of Appium is a Web server that provides a REST interface, receives client connections, hears commands, executes these commands on a mobile device, and then returns the execution results to the client in an HTTP response.
Session mechanism
Appuim's automated testing is run in the context of a session and can be understood as a Appuim session.
Each time the Appium server starts successfully, the client library requires a session to be created with the server.
The purpose of the session is to ensure that different client requests can be distinguished from the different applications being tested, and each specific session has a specific SessionID parameter. At the beginning of each test, the client initializes a session, although different languages are initialized in different ways, but they all send post/session requests to the server side, and the requests will have an object: desired capabilities, At this point the server will start the automation session and then return a session ID, which will be matched with this seesion ID.
Appuim Service Side
Includes a wide range of language libraries (Java, Ruby, Python, PHP, javascript,c#, etc.), all of which enable Appium to extend the Webdriver protocol.
JSON Wire Protocol
A very important protocol in Appuim
Appuim Architecture
Appuim based on Nodejs, based on the HTTP protocol, can be seen as a selenium webdriver-based mobile platform Webdriver, follow the RESTful design style Web server, accept the client connection and then execute commands on the mobile device. The result of the command execution is collected at the end of the HTTP response.
The following is my Appuim Android platform under the architectural schematic diagram, iOS is similar, but the bootstrap part is replaced by instruments, Uiautomator replaced by UIAutomation.
The following two figures refer to the testerhome ppt of the Appuim Android and iOS platform under the Data flow chart.
Among them, Android platform, Android API 17+, the bottom call Android platform comes with the UI test framework uiautomator; Conversely, call the Selendroid test framework to complete.
Bootstrap source code Analysis source structure
As shown below, Appuim bootstrap part of the source structure, sub-uiwatchers, Bootstrap and uiautomator three parts, very clear.
Start timing
The Bootstrap entry class is Bootstrap.java, inherits from Uiautomatortestcase, and then opens the socket receive command, the timing is as follows.
Class diagram
The class relationship is simple, as shown in.
SOURCE Analysis
Bootstrap integral sub-socketserver part, CommandHandler part, watchers part and Uiautomator four part.
- Socketserver. Complete the PC server-side command receive and parse, and then call Uiautomator through CommandHandler's execute operation to achieve touch operation.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
try { Client = Server.accept (); Logger.debug ("Client connected"); in =New BufferedReader (New InputStreamReader (Client.getinputstream (), "UTF-8")); new bufferedwriter (new outputstreamwriter (Client.getoutputstream (), "UTF-8")); while (keeplistening) { Handleclientdata (); Out.close (); Client.close (); Logger.debug ( } catch (final ioexception e) { throw new socketserverexception ( "Error when client is trying to connect"); } /span> |
- CommandHandler, virtual base classes, function classes are integrated from this class to complete the execute operation, through the HashMap mapping, as follows.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
PrivateStatic hashmap<string, commandhandler> map =New hashmap<string, commandhandler> ();
static { Map.put ("Waitforidle",New Waitforidle ()); Map.put ("Clear",New Clear ()); Map.put ("Orientation",New Orientation ()); Map.put ("Swipe",New Swipe ()); Map.put ("Flick",New Flick ()); Map.put ("Drag",New Drag ()); Map.put ("Pinch",New Pinch ()); Map.put ("Click",New Click ()); Map.put ("Touchlongclick",New Touchlongclick ()); Map.put ("TouchDown",New TouchDown ()); Map.put ("TouchUp",New TouchUp ()); Map.put ("TouchMove",New TouchMove ()); Map.put ("GetText",New GetText ()); Map.put ("SetText",New SetText ()); Map.put ("GetName",New GetName ()); Map.put ("GetAttribute",New GetAttribute ()); Map.put ("Getdevicesize",New Getdevicesize ()); Map.put ("ScrollTo",New ScrollTo ()); Map.put ("Find",New Find ()); Map.put ("GetLocation",New GetLocation ()); Map.put ("GetSize",New GetSize ()); Map.put ("Wake",New Wake ()); Map.put ("Pressback",New Pressback ()); Map.put ("Presskeycode",New Presskeycode ()); Map.put ("Longpresskeycode",New Longpresskeycode ()); Map.put ("Takescreenshot",New Takescreenshot ()); Map.put ( "Updatestrings", new updatestrings ()); Map.put (new getdatadir ()); Map.put ( "Performmultipointergesture", new Multipointergesture ()); Map.put (new Opennotification ()); Map.put (new source ()); Map.put ( "Compressedlayouthierarchy", new Compressedlayouthierarchy ()); Map.put (new Configuratorhandler ()); } /span> |
The specific mappings are implemented through execute in Androidcommandexecutor.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
Public AndroidcommandresultExecute(Final Androidcommand command) { try { Logger.debug ("Got Command action:" + command.action ());
if (Map.containskey (Command.action ())) { Return Map.get (Command.action ()). Execute (command); } Else { return New Androidcommandresult (Wdstatus.unknown_command, "Unknown command:" + command.action ()); } } catch (final jsonexception e) { Logger.error ("Could not decode Action/params of command"); return New Androidcommandresult (Wdstatus.json_decoder_error, "Could not decode action/params of command, please check format!"); } }
|
- Watchers,android ANR and Crash, the following code.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
PublicvoidRegisteranrandcrashwatchers() { Uidevice.getinstance (). Registerwatcher ("ANR",New Uiwatcher () { @Override PublicBooleanCheckforcondition() { UiObject window =New UiObject (New Uiselector () . ClassName ("Com.android.server.am.AppNotRespondingDialog")); String ErrorText =null; if (window.exists ()) { try { ErrorText = Window.gettext (); catch (uiobjectnotfoundexception e) { LOG.E (log_ TAG, "dialog gone?", e); onanrdetected (errorText); Posthandler (); return true; //triggered return span class= "keyword" >false; //no trigger |
- Uiautomator, perform touch operation via Uiautomator.
Refs
To update the article, please visit the personal site.
SYNC POST
========
by SkySeraph-2017
Www.skyseraph.com
Appuim Source Analysis (Bootstrap)