I am trying to get started with Appium for testing my company's mobile applications. I wish to use the Python bindings to write the scripts, and I need to start with Android apps.
I have the Appium examples all working. I can run grunt android
and the tests work, and I can run the android.py
sample app.
But I'm a total newbie and I don't have a clear picture of how to identify the controls in my company's apps. I'm experienced with Python so I thought I would just build a list of control elements and introspect them.
I'm stuck! All of the methods like driver.find_elements_by_tag_name()
require a specific identifier (or at least I haven't found any wildcard that works).
How can I introspect the Appium tree of elements that represents the Android app under test? How can I enumerate all the elements so I can introspect them? Is there a tree I can walk to find all elements in the app?
I was hoping I could figure out the elements without needing to get the source code for the apps, build the apps in Eclipse, etc. but I can do this if necessary.
P.S. I would prefer to use Python, but would be open to using something else to do the introspection if that works better. I could still write the actual tests in Python, unless the other language was significantly better somehow.
I still would like a way to introspect the Selenium interface from Python. But I have found a workable way to get a clear image of how the app is laid out, and it's pretty easy to then figure out how to write the Selenium tests.
First, get your app running, either on a real device connected to your Android development computer or in an emulator. Basically if you run adb devices
you want to see a single device, the one running your app. Next, run the uiautomatorviewer
tool, and then click on the Device Screenshot
toolbar icon. (There are only two toolbar icons: the first is the Open
icon and looks like a file folder, and the one you want looks like a stack of mobile phones.)
Once you have done that, an image of your app appears, with a screenshot on the left, and a browsable tree outline on the right. The outline shows all the controls of the app, along with their text labels if any, and other information (such as whether the clickable
property is true
or false
for that control).
One warning: the controls are shown numbered, but in the Selenium bindings, the numbers might not be the same. On the ApiDemos
example app, the Graphics
button has index number 4 as it is the fifth button, but to access it by its position I had to use index 5. Index 0 was a non-clickable object holding the text "API Demos", in a different FrameLayout
object making up the header for the screen.
So, I was able to make this change to the android.py
script:
#elem = driver.find_element_by_name('Graphics')
elem = driver.find_elements_by_tag_name('TextView')[5]
Comment out the driver.find_element_by_name()
call, and instead find the sixth TextView
in the entire app. That's not best practice but it shows that the uiautomationviewer
results do let me view the stuff I need to know about the controls.
Now I know enough to do a little bit of introspection:
for elem in driver.find_elements_by_tag_name('TextView'):
if elem.text == "Graphics":
break
else:
print("Could not find desired item")
This isn't better than just calling driver.find_element_by_name()
but it shows that I am on the right track.
uiautomatorviewer
is a practical solution to my problem. If you have a pure-Python one please let me know about it.
Appium supports WebDriver's "page source" method. So you can do this:
# assume you have a driver object
import json
source = driver.page_source
source = json.loads(source)
# you can now work with source as a python object
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With