如何在Ubuntu中使用Appium进行Android单元测试
我想使用Appium对HelloWorld Android应用程序进行一个简单的单元测试。我的Android应用程序有一个活动,当它加载到屏幕上后,它会在文本视图上显示“Hello World”。我想要的是使用Python编写一个单元测试用例,它按照我的预期工作,并使用Appium进行测试 我不能理解的主要事情是我的Android项目、Appium和Python脚本之间的联系 我想我已经在Ubuntu-12.04中正确配置了Appium。当我在终端中发出以下命令时如何在Ubuntu中使用Appium进行Android单元测试,android,python,unit-testing,ubuntu-12.04,appium,Android,Python,Unit Testing,Ubuntu 12.04,Appium,我想使用Appium对HelloWorld Android应用程序进行一个简单的单元测试。我的Android应用程序有一个活动,当它加载到屏幕上后,它会在文本视图上显示“Hello World”。我想要的是使用Python编写一个单元测试用例,它按照我的预期工作,并使用Appium进行测试 我不能理解的主要事情是我的Android项目、Appium和Python脚本之间的联系 我想我已经在Ubuntu-12.04中正确配置了Appium。当我在终端中发出以下命令时 anuja@anuja-Mul
anuja@anuja-MulTplx:~$ appium &
它给出了以下回应
anuja@anuja-MulTplx:~$info:Appium REST http接口侦听器
从0.0.0.0:4723开始
我已经用SeleniumWebDriver编写了用于web单元测试的简单Python脚本。但我不知道如何编写Python脚本来使用Appium测试我的Android应用程序。需要一个例子或良好的文档
谢谢
我在@answer之后添加此部分。 使用一个终端启动服务器后,我从另一个包含python绑定的终端运行python脚本 在运行终端的Appium服务器上,它给出以下输出
debug: Appium request initiated at /wd/hub/session
debug: Request received with params: {"sessionId":null,"desiredCapabilities":{"app-package":"my.app.package","app":"/home/anuja/MobileDev/apks_and_keys/Trickbook.apk","browserName":"","version":"4.0.4","device":"Android","app-activity":"TrickbookSplasher"}}
info: Using local app from desiredCaps: /home/anuja/MobileDev/apks_and_keys/Trickbook.apk
info: Creating new appium session 4788d549-d39a-4730-9bdb-382418c2b2c9
info: Starting android appium
debug: Using fast reset? true
info: Preparing device for session
info: Checking whether app is actually present
info: Checking whether adb is present
info: [ADB] Using adb from /home/anuja/MobileDev/sdk/platform-tools/adb
info: Trying to find a connected android device
info: [ADB] Getting connected devices...
info: [ADB] 1 device(s) connected
info: [ADB] Setting device id to 4d017b1f209a3f7b
info: Found device, no need to retry
info: [ADB] Waiting for device 4d017b1f209a3f7b to be ready and to respond to shell commands (timeout = 5)
info: Checking whether we need to run fast reset
debug: Checking app cert for /tmp/my.app.package.clean.apk: java -jar "/usr/lib/node_modules/appium/app/android/verify.jar" "/tmp/my.app.package.clean.apk"
debug: App not signed with debug cert.
debug: Checking app cert for /home/anuja/MobileDev/apks_and_keys/Trickbook.apk: java -jar "/usr/lib/node_modules/appium/app/android/verify.jar" "/home/anuja/MobileDev/apks_and_keys/Trickbook.apk"
debug: App not signed with debug cert.
info: Building fast reset
error: uncaughtException date=Thu May 30 2013 11:28:22 GMT+0530 (IST), pid=4466, uid=1000, gid=1000, cwd=/home/anuja, execPath=/usr/bin/nodejs, version=v0.10.8, argv=[node, /usr/bin/appium], rss=27017216, heapTotal=19666944, heapUsed=12400392, loadavg=[0.26318359375, 0.201171875, 0.333984375], uptime=2427.250582503, trace=[column=18, file=fs.js, function=Object.fs.openSync, line=427, method=fs.openSync, native=false, column=15, file=fs.js, function=Object.fs.readFileSync, line=284, method=fs.readFileSync, native=false, column=36, file=/usr/lib/node_modules/appium/android/adb.js, function=ADB.buildFastReset, line=131, method=buildFastReset, native=false, column=12, file=/usr/lib/node_modules/appium/android/adb.js, function=null, line=311, method=null, native=false, column=14, file=/usr/lib/node_modules/appium/android/adb.js, function=null, line=283, method=null, native=false, column=7, file=child_process.js, function=ChildProcess.exithandler, line=641, method=exithandler, native=false, column=17, file=events.js, function=ChildProcess.EventEmitter.emit, line=98, method=EventEmitter.emit, native=false, column=16, file=child_process.js, function=maybeClose, line=735, method=null, native=false, column=5, file=child_process.js, function=Process.ChildProcess._handle.onexit, line=802, method=ChildProcess._handle.onexit, native=false], stack=[Error: ENOENT, no such file or directory '/usr/lib/node_modules/appium/app/android/AndroidManifest.xml.src', at Object.fs.openSync (fs.js:427:18), at Object.fs.readFileSync (fs.js:284:15), at ADB.buildFastReset (/usr/lib/node_modules/appium/android/adb.js:131:36), at /usr/lib/node_modules/appium/android/adb.js:311:12, at /usr/lib/node_modules/appium/android/adb.js:283:14, at ChildProcess.exithandler (child_process.js:641:7), at ChildProcess.EventEmitter.emit (events.js:98:17), at maybeClose (child_process.js:735:16), at Process.ChildProcess._handle.onexit (child_process.js:802:5)]
在我执行python绑定脚本的终端上,给出了以下内容
Traceback (most recent call last):
File "forth.py", line 12, in <module>
driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)
File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/remote/webdriver.py", line 72, in __init__
self.start_session(desired_capabilities, browser_profile)
File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/remote/webdriver.py", line 114, in start_session
'desiredCapabilities': desired_capabilities,
File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/remote/webdriver.py", line 163, in execute
response = self.command_executor.execute(driver_command, params)
File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/remote/remote_connection.py", line 349, in execute
return self._request(url, method=command_info[0], data=data)
File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/remote/remote_connection.py", line 396, in _request
response = opener.open(request)
File "/usr/lib/python2.7/urllib2.py", line 400, in open
response = self._open(req, data)
File "/usr/lib/python2.7/urllib2.py", line 418, in _open
'_open', req)
File "/usr/lib/python2.7/urllib2.py", line 378, in _call_chain
result = func(*args)
File "/usr/lib/python2.7/urllib2.py", line 1207, in http_open
return self.do_open(httplib.HTTPConnection, req)
File "/usr/lib/python2.7/urllib2.py", line 1180, in do_open
r = h.getresponse(buffering=True)
File "/usr/lib/python2.7/httplib.py", line 1030, in getresponse
response.begin()
File "/usr/lib/python2.7/httplib.py", line 407, in begin
version, status, reason = self._read_status()
File "/usr/lib/python2.7/httplib.py", line 371, in _read_status
raise BadStatusLine(line)
httplib.BadStatusLine: ''
回溯(最近一次呼叫最后一次):
文件“forth.py”,第12行,在
driver=webdriver.Remote('http://localhost:4723/wd/hub,所需的(大写)
文件“/usr/local/lib/python2.7/dist packages/selenium/webdriver/remote/webdriver.py”,第72行,在__
self.start\u会话(所需的\u功能、浏览器\u配置文件)
文件“/usr/local/lib/python2.7/dist packages/selenium/webdriver/remote/webdriver.py”,第114行,在启动会话中
“desiredCapabilities”:所需的功能,
文件“/usr/local/lib/python2.7/dist packages/selenium/webdriver/remote/webdriver.py”,执行中第163行
响应=self.command\u executor.execute(driver\u command,params)
文件“/usr/local/lib/python2.7/dist packages/selenium/webdriver/remote/remote_connection.py”,第349行,在execute中
返回self.\u请求(url,方法=命令\u信息[0],数据=数据)
文件“/usr/local/lib/python2.7/dist packages/selenium/webdriver/remote/remote\u connection.py”,第396行,在请求中
响应=opener.open(请求)
文件“/usr/lib/python2.7/urllib2.py”,第400行,打开
响应=自身打开(请求,数据)
文件“/usr/lib/python2.7/urllib2.py”,第418行,打开
"开放",
文件“/usr/lib/python2.7/urllib2.py”,第378行,在调用链中
结果=func(*args)
文件“/usr/lib/python2.7/urllib2.py”,第1207行,在http\u open中
返回self.do_open(httplib.HTTPConnection,req)
文件“/usr/lib/python2.7/urllib2.py”,第1180行,打开
r=h.getresponse(缓冲=True)
getresponse中的文件“/usr/lib/python2.7/httplib.py”,第1030行
response.begin()
文件“/usr/lib/python2.7/httplib.py”,第407行,在begin中
版本、状态、原因=self.\u读取\u状态()
文件“/usr/lib/python2.7/httplib.py”,第371行,处于读取状态
升起状态行(行)
httplib.BadStatusLine:“”
我已使用自签名apk进行上述测试
- 右键单击EclipseAndroid项目
- Android工具
- 导出已签名的应用程序包
- 彻底检查向导
有人能告诉我哪里/我做错了什么吗?
appium&
启动appium服务器。将其视为将启动selenium RC服务器的java-jar selenium.jar的等价物
启动服务器后,必须通过python绑定连接到服务器:
from selenium import webdriver
desired_caps = {}
desired_caps['device'] = 'Android'
desired_caps['browserName'] = ''
desired_caps['version'] = '4.2'
desired_caps['app'] = '/path/to.your.apk'
desired_caps['app-package'] = 'com.example.android.package'
desired_caps['app-activity'] = 'YourActivity'
driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)
一旦连接好,就可以通过普通的pythonwebdriver命令控制测试
示例:从日志中可以看出,
应用程序未使用调试证书签名。
您的apk未使用~/.android/debug.keystore中的默认调试证书签名,如下所示配置SDK
export ANDROID_HOME="$HOME/adt/sdk"
export JAVA_HOME="/usr/bin/java"
export PATH=${PATH}:~/adt/sdk/tools
export PATH=${PATH}:~/adt/sdk/platform-tools
参考代码:
import os
from time import sleep
import unittest
from appium import webdriver
# Returns absolute path relative to this file and not cwd
PATH = lambda p: os.path.abspath(
os.path.join(os.path.dirname(__file__), p))
class SimpleAndroidTests(unittest.TestCase):
def setUp(self):
desired_caps = {}
#Specify platform below(Android, iOS)
desired_caps['platformName'] = 'Android'
#Specify OS version(Settings->About phone -> android version)
desired_caps['platformVersion'] = '4.4.4'
#Obtain the Device name from Adb[For Android](Terminal Command: "adb devices")
desired_caps['deviceName'] = 'TA93304QZD'
#Specify the path to Application
desired_caps['app'] = PATH('Media Drive-com.sandisk.scotti-55-v2.0.3.apk')
self.driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)
def tearDown(self):
# end the session
self.driver.quit()
def test_images_copy(self):
self.driver.implicitly_wait(5)
for i in range(0,4):
self.driver.find_element_by_id("com.sandisk.scotti:id/txt_Next").click()
self.driver.implicitly_wait(5)
self.driver.find_element_by_id("com.sandisk.scotti:id/txt_Close").click()
self.driver.implicitly_wait(5)
self.driver.find_element_by_name("OK").click()
self.driver.implicitly_wait(5)
self.driver.find_element_by_id("com.sandisk.scotti:id/txt_Photo").click()
self.driver.implicitly_wait(5)
self.driver.find_element_by_id("com.sandisk.scotti:id/btn_Switch_Local").click()
self.driver.implicitly_wait(5)
self.driver.find_element_by_id("com.sandisk.scotti:id/txt_Name").click()
self.driver.implicitly_wait(5)
if __name__ == '__main__':
suite = unittest.TestLoader().loadTestsFromTestCase(SimpleAndroidTests)
unittest.TextTestRunner(verbosity=2).run(suite)
谢谢你的回复。我在尝试你的方法时又卡住了。我已经根据你的答案编辑了我的问题。请查看横线后的最新更新,并告诉我哪里/我做错了什么。