最近在学习 appium 示例代码是遇到错误:
示例代码中 from appium import SauceTestCase 语句在运行中报 ImportError: cannot import name SauceTestCase。
我在 python 目录下发现 SauceTestCase 是 saucetestcase 模块中的类,运行时又报 ImportError: No module named sauceclient 错误。
无奈。。。继续查看 saucetestcase 代码,代码中有 from sauceclient import SauceClient 语句。但是 appium 下没有找到 sauceclient 模块。。。。请问各个大神这个问题该怎么解决?是我 appium 的问题吗?
附示例代码:
from appium import webdriver
from appium import SauceTestCase, on_platforms
from appium.webdriver.common.touch_action import TouchAction
from appium.webdriver.common.multi_action import MultiAction
from time import sleep
app = "http://appium.github.io/appium/assets/ApiDemos-debug.apk"
platforms = [{
"platformName": "Android",
"platformVersion": "4.4",
"deviceName": "test",
"appActivity": ".graphics.TouchPaint",
"app": app,
"appiumVersion": "1.3.4"
}]
@on_platforms(platforms)
class AndroidGesturesSauceTests(SauceTestCase):
def test_drag_and_drop(self):
# first get to the right activity
self.driver.start_activity("io.appium.android.apis", ".view.DragAndDropDemo")
start = self.driver.find_element_by_id("io.appium.android.apis:id/drag_dot_3")
end = self.driver.find_element_by_id("io.appium.android.apis:id/drag_dot_2")
action = TouchAction(self.driver);
action.long_press(start).move_to(end).release().perform()
sleep(.5)
text = self.driver.find_element_by_id("io.appium.android.apis:id/drag_result_text").text
self.assertEqual(text, "Dropped!")
def test_smiley_face(self):
# just for the fun of it.
# this doesn't really assert anything.
# paint
eye1 = TouchAction()
eye1.press(x=150, y=100).release()
eye2 = TouchAction()
eye2.press(x=250, y=100).release()
smile = TouchAction()
smile.press(x=110, y=200) \
.move_to(x=1, y=1) \
.move_to(x=1, y=1) \
.move_to(x=1, y=1) \
.move_to(x=1, y=1) \
.move_to(x=1, y=1) \
.move_to(x=2, y=1) \
.move_to(x=2, y=1) \
.move_to(x=2, y=1) \
.move_to(x=2, y=1) \
.move_to(x=2, y=1) \
.move_to(x=3, y=1) \
.move_to(x=3, y=1) \
.move_to(x=3, y=1) \
.move_to(x=3, y=1) \
.move_to(x=3, y=1) \
.move_to(x=4, y=1) \
.move_to(x=4, y=1) \
.move_to(x=4, y=1) \
.move_to(x=4, y=1) \
.move_to(x=4, y=1) \
.move_to(x=5, y=1) \
.move_to(x=5, y=1) \
.move_to(x=5, y=1) \
.move_to(x=5, y=1) \
.move_to(x=5, y=1) \
.move_to(x=5, y=0) \
.move_to(x=5, y=0) \
.move_to(x=5, y=0) \
.move_to(x=5, y=0) \
.move_to(x=5, y=0) \
.move_to(x=5, y=0) \
.move_to(x=5, y=0) \
.move_to(x=5, y=0) \
.move_to(x=5, y=-1) \
.move_to(x=5, y=-1) \
.move_to(x=5, y=-1) \
.move_to(x=5, y=-1) \
.move_to(x=5, y=-1) \
.move_to(x=4, y=-1) \
.move_to(x=4, y=-1) \
.move_to(x=4, y=-1) \
.move_to(x=4, y=-1) \
.move_to(x=4, y=-1) \
.move_to(x=3, y=-1) \
.move_to(x=3, y=-1) \
.move_to(x=3, y=-1) \
.move_to(x=3, y=-1) \
.move_to(x=3, y=-1) \
.move_to(x=2, y=-1) \
.move_to(x=2, y=-1) \
.move_to(x=2, y=-1) \
.move_to(x=2, y=-1) \
.move_to(x=2, y=-1) \
.move_to(x=1, y=-1) \
.move_to(x=1, y=-1) \
.move_to(x=1, y=-1) \
.move_to(x=1, y=-1) \
.move_to(x=1, y=-1)
smile.release()
ma = MultiAction(self.driver)
ma.add(eye1, eye2, smile)
ma.perform()
# so you can see it
sleep(10)
附 saucetestcase 代码:
#!/usr/bin/env python
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import unittest
import os
import sys
import new
from appium import webdriver
from sauceclient import SauceClient
SAUCE_USERNAME = os.environ.get('SAUCE_USERNAME')
SAUCE_ACCESS_KEY = os.environ.get('SAUCE_ACCESS_KEY')
sauce = SauceClient(SAUCE_USERNAME, SAUCE_ACCESS_KEY)
def on_platforms(platforms):
def decorator(base_class):
module = sys.modules[base_class.__module__].__dict__
for i, platform in enumerate(platforms):
d = dict(base_class.__dict__)
d['desired_capabilities'] = platform
name = "%s_%s" % (base_class.__name__, i + 1)
module[name] = new.classobj(name, (base_class,), d)
return decorator
class SauceTestCase(unittest.TestCase):
def setUp(self):
self.desired_capabilities['name'] = self.id()
sauce_url = "http://%s:%s@ondemand.saucelabs.com:80/wd/hub"
self.driver = webdriver.Remote(
desired_capabilities=self.desired_capabilities,
command_executor=sauce_url % (SAUCE_USERNAME, SAUCE_ACCESS_KEY)
)
self.driver.implicitly_wait(30)
def tearDown(self):
print("Link to your job: https://saucelabs.com/jobs/%s" % self.driver.session_id)
try:
if sys.exc_info() == (None, None, None):
sauce.jobs.update_job(self.driver.session_id, passed=True)
else:
sauce.jobs.update_job(self.driver.session_id, passed=False)
finally:
self.driver.quit()