Appium 急!!!测试一个页面时一定要以另一个页面为前提,测试类该怎么写??????

Tessa · 2022年02月13日 · 最后由 Tessa 回复于 2022年02月16日 · 3556 次阅读

app.py

from appium import webdriver
from Common.yaml_util import YamlUtil
from PageObjects.navigation import Navigation

class App:

    @classmethod
    def Start(cls):
        data = YamlUtil.readYaml("Config/Config.yaml")
        server = 'http://localhost:4723/wd/hub'
        cls.driver = webdriver.Remote(server, data["desired_caps"])
        cls.driver.implicitly_wait(20)
        return Navigation(cls.driver)

    @classmethod
    def Quit(cls):
        App.qiut()

navigation.py

from appium.webdriver.common.mobileby import MobileBy
import logging
from Base.basepage import BasePage
from PageObjects.page_level_one.home_page import HomePage
from PageObjects.page_level_one.scene_page import ScenePage
from PageObjects.page_first.first_page import FirstPage
from PageObjects.page_level_one.user_page import UserPage


# 此页面为导航页,
class Navigation(BasePage):
    el_home = (MobileBy.XPATH, "//XCUIElementTypeButton[@name='首页']")
    el_scene = (MobileBy.XPATH, "//XCUIElementTypeButton[@name='场景']")
    el_user = (MobileBy.XPATH, "//XCUIElementTypeButton[@name='我的']")

    # 进入到APP启动页面
    def in_first_page(self):
        logging.info("进入到APP启动页面")
        return FirstPage(self.driver)

    # 进入到APP首页
    def in_home_page(self):
        self.find_and_click(*self.el_home)
        logging.info("进入到APP首页")
        return HomePage(self.driver)

    # 进入到APP场景页面
    def in_sence_page(self):
        self.find_and_click(*self.el_scene)
        logging.info("进入到APP场景页面")
        return ScenePage(self.driver)

    # 进入到APP我的页面
    def in_user_page(self):
        self.find_and_click(*self.el_user)
        logging.info("进入到APP我的页面")
        return UserPage(self.driver)

home_page.py

import time
from selenium.webdriver.common.by import By
from PageObjects.page_device.rgbcw_page import RGBCWPage
from Base.basepage import BasePage


# APP首页
class HomePage(BasePage):


    rgbcw_toggle = (By.XPATH, "//*[@id='app']/div/div[2]/div[3]/div[2]/div/div[3]/div[1]/div[1]/div[1]/span[2]")

    rgbcw_info = (By.XPATH, "//*[@id='app']/div/div[2]/div[3]/div[2]/div/div[3]/div[1]/div[1]/div[2]")

    rgbcw_title = (By.XPATH, "//*[@id='app']/div/div[2]/div[3]/div[2]/div/div[3]/div[1]/div[1]/div[2]/p[1]")

    rgbce_detail = (
        By.XPATH, "//*[@id='app']/div/div[2]/div[3]/div[2]/div/div[3]/div[1]/div[1]/div[2]/p[2]/span[1]")


    cw_toggle = (By.XPATH, "//*[@id='app']/div/div[2]/div[3]/div[2]/div/div[3]/div[1]/div[3]/div[1]/span[2]")
    cw_info = (By.XPATH, "//*[@id='app']/div/div[2]/div[3]/div[2]/div/div[3]/div[1]/div[3]/div[2]")
    cw_title = (By.XPATH, "//*[@id='app']/div/div[2]/div[3]/div[2]/div/div[3]/div[1]/div[3]/div[2]/p[1]")
    cw_detail = (
        By.XPATH, "//*[@id='app']/div/div[2]/div[3]/div[2]/div/div[3]/div[1]/div[3]/div[2]/p[2]/span[1]")


    w_toggle = (By.XPATH, "//*[@id='app']/div/div[2]/div[3]/div[2]/div/div[3]/div[1]/div[2]/div[1]/span[2]")
    w_info = (By.XPATH, "//*[@id='app']/div/div[2]/div[3]/div[2]/div/div[3]/div[1]/div[2]/div[2]")
    w_title = (By.XPATH, "//*[@id='app']/div/div[2]/div[3]/div[2]/div/div[3]/div[1]/div[2]/div[2]/p[1]")
    w_detail = (By.XPATH, "//*[@id='app']/div/div[2]/div[3]/div[2]/div/div[3]/div[1]/div[2]/div[2]/p[2]/span[1]")


    def in_rgbcw_page(self):
        self.find_and_click(*self.rgbcw_info)
        return RGBCWPage

    # 获取context
    def get_switch_context(self):
        # 循环等待加载H5 Context
        for i in range(5):
            print(self.driver.contexts)
            time.sleep(1)
            # 获取到Contexts列表大于1(说明获取H5 Context)
        if len(self.driver.contexts) > 1:
            print("当前获取到的Contexts_list为 " + str(self.driver.contexts))
            # 切换到H5 Context
            self.driver.switch_to.context(self.driver.contexts[1])
            print(u"切换到相应的环境下 " + str(self.driver.contexts[1]))
            return True
        # 否则就是没有获取到H5 Context
        else:
            print("当前获取到的Contexts为 " + str(self.driver.contexts[0]))
            return False

test_home_page.py

from PageObjects.app import App
from PageObjects.page_device.rgbcw_page import RGBCWPage


class TestHome:
    def setup_class(self):
        self.home_page = App.Start().in_home_page()


    def test_in_contexts(self):
        result = self.home_page.get_switch_context()
        assert result

    def test_in_rgbcw_page(self):
        result = self.home_page.in_rgbcw_page()
        assert result == RGBCWPage

Rgbcw.py

import time

from Base.basepage import BasePage
from selenium.webdriver.common.by import By


class RGBCWPage(BasePage):

    rgbcw_info = (By.XPATH, "//*[@id='app']/div/div[2]/div[3]/div[2]/div/div[3]/div[1]/div[1]/div[2]")

    el_back = (By.XPATH, "//*[@id='lightHsv']/div[1]/div[1]/span")

    el_setting_btn = (By.CLASS_NAME, "lines")

    el_show = (By.CLASS_NAME, "light-wrap")

    el_switch_btn = (By.CLASS_NAME, "right switch icon-switch")

    el_model_btn = (By.CLASS_NAME, "icon icon-mode")

    el_highly_work = (By.XPATH, "//*[@id='lightHsv']/div[6]/div[2]/div[2]/div[1]/span")

    el_lie_Fallow = (By.XPATH, "//*[@id='lightHsv']/div[6]/div[2]/div[2]/div[2]/span")

    el_night_read = (By.XPATH, "//*[@id='lightHsv']/div[6]/div[2]/div[2]/div[3]/span")

    el_sleep = (By.XPATH, "//*[@id='lightHsv']/div[6]/div[2]/div[2]/div[4]/span")

    el_temprature_btn = (By.CLASS_NAME, "icon icon-temprature")

    el_color_btn = (By.CLASS_NAME, "icon icon-colorpanel")

    el_wrap = (By.CLASS_NAME, "px-line-wrap")

    def in_rgbcw_page(self):
        self.find_and_click(*self.rgbcw_info)
        return RGBCWPage

    def in_mode(self):
        self.find_and_click(*self.el_model_btn)

    def highly_work(self):
        self.find_and_click(*self.el_highly_work)

TestRgbcw 页面

from PageObjects.app import App
from PageObjects.page_device.rgbcw_page import RGBCWPage


class TestRgbcw:
    def setup_class(self):
        self.home_page = App.Start().in_home_page()
        self.rgbcw_page = App.Start().in_home_page().in_rgbcw_page()


    def test_in_contexts(self):
        result = self.home_page.get_switch_context()
        assert result

    def test_in_rgbcw_page(self):
        result = self.home_page.in_rgbcw_page()
        assert result == RGBCWPage

    def test_in_rgbcw(self):
        self.rgbcw_page.in_rgbcw_page()

    def test_click_model(self):
        result = self.rgbcw_page.in_mode()
        assert result in '模式弹窗展示'

    def test_click_highly_work(self):
        result = self.rgbcw_page.highly_work()
        assert result == '高效工作模式'


/Users/mac/Desktop/Demo/smarthome/venv/bin/python /Users/mac/Desktop/Demo/smarthome/all.py
============================= test session starts ==============================
platform darwin -- Python 3.8.2, pytest-6.2.5, py-1.10.0, pluggy-1.0.0 -- /Users/mac/Desktop/Demo/smarthome/venv/bin/python
cachedir: .pytest_cache
rootdir: /Users/mac/Desktop/Demo/smarthome, configfile: pytest.ini, testpaths: ./TestCases
collecting ... collected 5 items

TestCases/test_rgbcw.py::TestRgbcw::test_in_contexts -------------------------------------------
/Users/mac/Desktop/Demo/smarthome
-------------------------------------------
/Users/mac/Desktop/Demo/smarthome
ERROR
TestCases/test_rgbcw.py::TestRgbcw::test_in_rgbcw_page ERROR
TestCases/test_rgbcw.py::TestRgbcw::test_in_rgbcw ERROR
TestCases/test_rgbcw.py::TestRgbcw::test_click_model ERROR
TestCases/test_rgbcw.py::TestRgbcw::test_click_highly_work ERROR

==================================== ERRORS ====================================
_________________ ERROR at setup of TestRgbcw.test_in_contexts _________________

self = <class 'TestCases.test_rgbcw.TestRgbcw'>

    def setup_class(self):
        self.home_page = App.Start().in_home_page()
>       self.rgbcw_page = App.Start().in_home_page().in_rgbcw_page()

TestCases/test_rgbcw.py:8: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
PageObjects/page_level_one/home_page.py:44: in in_rgbcw_page
    self.find_and_click(*self.rgbcw_info)
Base/basepage.py:31: in find_and_click
    self.find(by, value).click()
Base/basepage.py:17: in find
    element = self.driver.find_element(by, value)
venv/lib/python3.8/site-packages/appium/webdriver/webdriver.py:414: in find_element
    return self.execute(RemoteCommand.FIND_ELEMENT, {'using': by, 'value': value})['value']
venv/lib/python3.8/site-packages/selenium/webdriver/remote/webdriver.py:321: in execute
    self.error_handler.check_response(response)
venv/lib/python3.8/site-packages/appium/webdriver/errorhandler.py:31: in check_response
    raise wde
venv/lib/python3.8/site-packages/appium/webdriver/errorhandler.py:26: in check_response
    super().check_response(response)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

我之前没有做过 App UI 的自动化,遇到测试页面 2 时需要调用页面 2 的方法,想请教各位大佬帮忙看看;

整个程序只有一个入口,就是 App 的 Start(),且会传一个 driver 参数;
1、我想要测试 rgbcw.py,就会调用 App 的 Start() 方法启动 App;
2、进入到 navigation.py(导航类),从 navigation.py(导航类) 调用 in_first_page(首页) 方法,到首页中调用 get_switch_context 方法切换 contexts(首页是 H5 页面)
3、在首页--->contexts 中找到 rgbcw 的元素,点击该元素再进入到 RGBCWPage.py 页面(rgbcw 详情页面也是 H5 页面)
我的问题如下:
在测试 TestRgbcw.py 时,Home 类中的方法和 Rgbcw 类的方法不能共存,怎么办?

self.home_page = App.Start().in_home_page()
self.rgbcw_page = App.Start().in_home_page().in_rgbcw_page()
 或者
self.home_page = App.Start().in_home_page()
self.rgbcw_page = self.rgbcw_page.in_rgbcw_page()

都会报错

但是要测试 RGBCWPage 页面就一定要 HomePage 页面为前提

最佳回复
  1. 最关键的问题在于不应该把进入 home page 和 rgbcw page 的方法写在 setup class,rgbcw 页面会覆盖 home page
  2. 测试用例应该职责分离,test_in_contexts 和 test_in_rgbcw_page 这两个依赖 home page 的用例不应该出现 TestRgbcw 中,而实际应该出现在 TestHomePage 中,把 self.home_page 和两条 home page 的用例移除掉,TestRgbcw 应该是可以跑的。
  3. 最好每条测试用例都环境隔离,即一个类下面每条 case 的初始页面应该是一样的,每条用例执行完后可以回到初始页面或者重新加载页面。
共收到 3 条回复 时间 点赞
  1. 最关键的问题在于不应该把进入 home page 和 rgbcw page 的方法写在 setup class,rgbcw 页面会覆盖 home page
  2. 测试用例应该职责分离,test_in_contexts 和 test_in_rgbcw_page 这两个依赖 home page 的用例不应该出现 TestRgbcw 中,而实际应该出现在 TestHomePage 中,把 self.home_page 和两条 home page 的用例移除掉,TestRgbcw 应该是可以跑的。
  3. 最好每条测试用例都环境隔离,即一个类下面每条 case 的初始页面应该是一样的,每条用例执行完后可以回到初始页面或者重新加载页面。

是测试 APP 内嵌的 H5 么?
如果知道RGBCWPage页面的 url, 从原生切换到 webview 之后,可以调用driver.get(RGBCWUrl)直接进入到 RGBCWPage 页面

frankxii 回复

将 self.home_page 和两条 home page 的用例移除后确实可以跑起来,但是进不去 RGBCWPage,testRgbcw 就跑不起来

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册