1、新建一个项目
    2、在项目中写两条用例:
    启动雪球-进入我的页面进入登录-登录成功后获取登录名验证是否成功登录

    1. import time
    2. from appium import webdriver
    3. from appium.webdriver.common.mobileby import MobileBy as By
    4. from appium.webdriver.common.touch_action import TouchAction
    5. # 初始化app
    6. desired_caps = {}
    7. desired_caps['platformName'] = 'Android' # 'Android' or ’Ios'
    8. desired_caps['deviceName'] = 'emulator-5554' # 设备名称,可以自定义
    9. # desired_caps['appPackage'] = 'com.iodkols.onekeylockscreen'
    10. # desired_caps['appActivity'] = '.OneLock'
    11. desired_caps['appPackage'] = 'com.xueqiu.android'
    12. desired_caps['appActivity'] = 'view.WelcomeActivityAlias'
    13. #desired_caps['noReset'] = 'True'
    14. driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps) # 类似于driver = webdriver.Chrome()
    15. driver.implicitly_wait(10)
    16. time.sleep(8)
    17. #在首页进入【我的】页面
    18. driver.find_element(By.XPATH, "//*[@text='我的']").click()
    19. #在【我的】页面点击【账号密码登录】进入登录页面
    20. driver.find_element(By.XPATH, "//*[@text='帐号密码登录']").click()
    21. #在登录页面输入账号
    22. driver.find_element(By.XPATH, "//*[@resource-id='com.xueqiu.android:id/login_account']").send_keys('13262506790')
    23. #在登录页面输入密码
    24. driver.find_element(By.XPATH, "//*[@resource-id='com.xueqiu.android:id/login_password']").send_keys('1111111a')
    25. #在登录页面点击【登录】
    26. driver.find_element(By.XPATH, "//*[@text='登录']").click()
    27. # 对一键导入弹框进行判断处理
    28. try:
    29. cancel_ele = driver.find_element(By.XPATH, "//*[@text='取消']").click()
    30. except:
    31. pass
    32. #登录后在我的页面获取登录昵称
    33. name_ele = driver.find_element(By.XPATH, "//*[@resource-id='com.xueqiu.android:id/name']")
    34. name_text = name_ele.get_attribute("text")
    35. print(name_text)
    36. assert '思源_smile' == name_text
    37. driver.quit()

    启动雪球-进行登录-在首页进入讨论帖页面-编辑并发布帖子-进入我的页面校验帖子是否成功生成

    1. import time
    2. from appium import webdriver
    3. from appium.webdriver.common.mobileby import MobileBy as By
    4. from appium.webdriver.common.touch_action import TouchAction
    5. # 初始化app
    6. desired_caps = {}
    7. desired_caps['platformName'] = 'Android' # 'Android' or ’Ios'
    8. desired_caps['deviceName'] = 'emulator-5554'
    9. desired_caps['appPackage'] = 'com.xueqiu.android'
    10. desired_caps['appActivity'] = 'view.WelcomeActivityAlias'
    11. #desired_caps['noReset'] = 'True'
    12. driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps) # 类似于driver = webdriver.Chrome()
    13. driver.implicitly_wait(10)
    14. time.sleep(8)
    15. #在首页进入【我的】页面
    16. driver.find_element(By.XPATH, "//*[@text='我的']").click()
    17. #在【我的】页面点击【账号密码登录】进入登录页面
    18. driver.find_element(By.XPATH, "//*[@text='帐号密码登录']").click()
    19. #在登录页面输入账号
    20. driver.find_element(By.XPATH, "//*[@resource-id='com.xueqiu.android:id/login_account']").send_keys('13262506790')
    21. #在登录页面输入密码
    22. driver.find_element(By.XPATH, "//*[@resource-id='com.xueqiu.android:id/login_password']").send_keys('1111111a')
    23. #在登录页面点击【登录】
    24. driver.find_element(By.XPATH, "//*[@text='登录']").click()
    25. #登录后进入雪球首页
    26. driver.find_element(By.XPATH, "//*[@text='雪球']").click()
    27. #在首页点击【编辑】按钮
    28. driver.find_element(By.XPATH, "//*[@resource-id='com.xueqiu.android:id/post_status']").click()
    29. #点击【发讨论】按钮进入发布讨论页面
    30. driver.find_element(By.XPATH, "//*[@text='发讨论']").click()
    31. #在发布讨论页面输入框中输入讨论内容
    32. title_text = "随着气候变暖,今年会不会有一个寒冷的冬天?"
    33. driver.find_element(By.XPATH, "//*[@resource-id='com.xueqiu.android:id/status_edit']").send_keys(title_text)
    34. #点击【发布】返回首页
    35. driver.find_element(By.XPATH, "//*[@text='发布']").click()
    36. #进入【我的】页面
    37. driver.find_element(By.XPATH, "//*[@text='我的']").click()
    38. #在【我的】页面点击【讨论】进入讨论页面
    39. driver.find_element(By.XPATH, "//*[@text='讨论']").click()
    40. #在讨论页面获取讨论标题元素
    41. eles = driver.find_elements(By.XPATH, "//*[@resource-id='com.xueqiu.android:id/statusText']")
    42. #对标题元素获取text属性存入列表
    43. title_list = [ele.get_attribute("text") for ele in eles]
    44. # 写个函数对结果进行断言
    45. def assert_title():
    46. for title in title_list:
    47. if title == title_text:
    48. return True
    49. else:
    50. return False
    51. assert assert_title()
    52. driver.quit()

    处理用例中公共的部分app初始化,对公共部分单独封装实现模块化及分层复用
    3、对初始化app代码单独封装
    新建py_page包-包下新建app模块,定义一个App类,类下定义一个start()实例方法对driver进行初始化并返回创建的driver

    1. import time
    2. from appium import webdriver
    3. from appium.webdriver.common.mobileby import MobileBy as By
    4. from appium.webdriver.common.touch_action import TouchAction
    5. class App:
    6. def start(self):
    7. # 初始化app
    8. desired_caps = {}
    9. desired_caps['platformName'] = 'Android'
    10. desired_caps['deviceName'] = 'emulator-5554'
    11. desired_caps['appPackage'] = 'com.xueqiu.android'
    12. desired_caps['appActivity'] = 'view.WelcomeActivityAlias'
    13. self.driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps) # 类似于driver = webdriver.Chrome()
    14. self.driver.implicitly_wait(10)
    15. return self.driver

    在测试用例中app初始化通过from py_page.app import App及driver = App().start()来代替,即实现所有用例共用app中的初始化代码;
    4、比较多个用例存在公共页面元素交互部分,把这部分元素的定位与交互单独封装,以页面为模块归类,类中方法为在该页面执行的元素交互;

    1. from py_page.app import App
    2. from appium.webdriver.common.mobileby import MobileBy as By
    3. class LoginPage(App):
    4. def __init__(self):
    5. self.driver = self.start()
    6. def account_login(self):
    7. # 在登录页面进行账号密码登录
    8. self.driver.find_element(By.XPATH, "//*[@text='我的']").click()
    9. self.driver.find_element(By.XPATH, "//*[@text='帐号密码登录']").click()
    10. self.driver.find_element(By.XPATH, "//*[@resource-id='com.xueqiu.android:id/login_account']").send_keys(
    11. '13262506790')
    12. self.driver.find_element(By.XPATH, "//*[@resource-id='com.xueqiu.android:id/login_password']").send_keys('1111111a')
    13. self.driver.find_element(By.XPATH, "//*[@text='登录']").click()
    1. from appium.webdriver.common.mobileby import MobileBy as By
    2. class MainPage(App):
    3. def __init__(self):
    4. self.driver = self.start()
    5. def goto_myPage(self):
    6. # 在首页进入【我的】页面
    7. self.driver.find_element(By.XPATH, "//*[@text='我的']").click()
    1. from py_page.app import App
    2. from appium.webdriver.common.mobileby import MobileBy as By
    3. class MyPage(App):
    4. def __init__(self):
    5. self.driver = self.start()
    6. def goto_login(self):
    7. # 在我的页面进入【登录】页面
    8. self.driver.find_element(By.XPATH, "//*[@text='我的']").click()
    9. def is_cancel(self):
    10. # 对一键导入弹框进行判断处理
    11. try:
    12. self.driver.find_element(By.XPATH, "//*[@text='取消']").click()
    13. except:
    14. pass
    15. def get_login_name(self):
    16. # 登录后在我的页面获取登录昵称
    17. name_ele = self.driver.find_element(By.XPATH, "//*[@resource-id='com.xueqiu.android:id/name']")
    18. name_text = name_ele.get_attribute("text")
    19. return name_text

    5、在修改原来测试用例,采用调用py_page中各方法来实现测试业务的流转执行

    1. from py_page.main_page import MainPage
    2. class TestLogin:
    3. def test_login_pos(self):
    4. name_text = MainPage().goto_myPage().goto_login().account_login().is_cancel().get_login_name()
    5. print(name_text)
    6. assert name_text == '思源_smile'

    似乎存在什么问题?
    优化上述py_page保证链式调用

    1. from appium.webdriver.common.mobileby import MobileBy as By
    2. class MainPage(App):
    3. def __init__(self):
    4. self.driver = self.start()
    5. def goto_myPage(self):
    6. # 在首页进入【我的】页面
    7. self.driver.find_element(By.XPATH, "//*[@text='我的']").click()
    8. from py_page.my_page import MyPage
    9. return MyPage()
    1. from py_page.app import App
    2. from appium.webdriver.common.mobileby import MobileBy as By
    3. class MyPage(App):
    4. def __init__(self):
    5. self.driver = self.start()
    6. def goto_login(self):
    7. # 在我的页面进入【登录】页面
    8. self.driver.find_element(By.XPATH, "//*[@text='我的']").click()
    9. return LoginPage()
    10. def is_cancel(self):
    11. # 对一键导入弹框进行判断处理
    12. try:
    13. self.driver.find_element(By.XPATH, "//*[@text='取消']").click()
    14. except:
    15. pass
    16. return self
    17. def get_login_name(self):
    18. # 登录后在我的页面获取登录昵称
    19. name_ele = self.driver.find_element(By.XPATH, "//*[@resource-id='com.xueqiu.android:id/name']")
    20. name_text = name_ele.get_attribute("text")
    21. return name_text
    1. from py_page.app import App
    2. from appium.webdriver.common.mobileby import MobileBy as By
    3. class LoginPage(App):
    4. def __init__(self):
    5. self.driver = self.start()
    6. def account_login(self):
    7. # 在登录页面进行账号密码登录
    8. self.driver.find_element(By.XPATH, "//*[@text='我的']").click()
    9. self.driver.find_element(By.XPATH, "//*[@text='帐号密码登录']").click()
    10. self.driver.find_element(By.XPATH, "//*[@resource-id='com.xueqiu.android:id/login_account']").send_keys(
    11. '13262506790')
    12. self.driver.find_element(By.XPATH, "//*[@resource-id='com.xueqiu.android:id/login_password']").send_keys('1111111a')
    13. self.driver.find_element(By.XPATH, "//*[@text='登录']").click()
    14. from py_page.my_page import MyPage
    15. return MyPage()

    上述代码似乎还存在问题,在测试用例的链式调用中,涉及页面跳转的每次调用页面类都会调用app初始化一个driver,而不是传递原来的driver;
    初步解决方案,每个页面类在构造方法中对driver进行判断,并在涉及页面跳转的方法中return 页面类(self.driver),即把当前页面的driver作为参数传入要跳转的页面,需要引入单例设计

    1. from py_page.app import App
    2. from appium.webdriver.common.mobileby import MobileBy as By
    3. class MainPage(App):
    4. def __init__(self,driver=None):
    5. if driver == None:
    6. self.driver = self.start()
    7. else:
    8. self.driver = driver
    9. def goto_myPage(self):
    10. # 在首页进入【我的】页面
    11. self.driver.find_element(By.XPATH, "//*[@text='我的']").click()
    12. from py_page.my_page import MyPage
    13. return MyPage(self.driver)
    from py_page.app import App
    from appium.webdriver.common.mobileby import MobileBy as By
    
    class MyPage(App):
    
        def __init__(self,driver=None):
            if driver == None:
                self.driver = self.start()
            else:
                self.driver = driver
    
        def goto_login(self):
            # 在我的页面进入【登录】页面
            self.driver.find_element(By.XPATH, "//*[@text='我的']").click()
            from py_page.login_page import LoginPage
            return LoginPage(self.driver)
    
        def is_cancel(self):
            # 对一键导入弹框进行判断处理
            try:
                self.driver.find_element(By.XPATH, "//*[@text='取消']").click()
            except:
                pass
            return self
    
        def get_login_name(self):
            # 登录后在我的页面获取登录昵称
            name_ele = self.driver.find_element(By.XPATH, "//*[@resource-id='com.xueqiu.android:id/name']")
            name_text = name_ele.get_attribute("text")
            return name_text
    
    from py_page.app import App
    from appium.webdriver.common.mobileby import MobileBy as By
    
    class LoginPage(App):
    
        def __init__(self,driver=None):
            if driver==None:
                self.driver = self.start()
            else:
                self.driver=driver
    
        def account_login(self):
            # 在登录页面进行账号密码登录
            self.driver.find_element(By.XPATH, "//*[@text='我的']").click()
            self.driver.find_element(By.XPATH, "//*[@text='帐号密码登录']").click()
            self.driver.find_element(By.XPATH, "//*[@resource-id='com.xueqiu.android:id/login_account']").send_keys(
                '13262506790')
            self.driver.find_element(By.XPATH, "//*[@resource-id='com.xueqiu.android:id/login_password']").send_keys('1111111a')
            self.driver.find_element(By.XPATH, "//*[@text='登录']").click()
            from py_page.my_page import MyPage
            return MyPage(self.driver)
    

    再次执行测试用例,即可实现完整的元素定位交互以及页面跳转
    6、继续优化py_page中的代码,把页面类中的构造方法封装到app中,减少代码冗余
    app模块的初步实现

    from appium import webdriver
    from appium.webdriver.common.mobileby import MobileBy as By
    from appium.webdriver.common.touch_action import TouchAction
    
    
    
    class App:
    
        def __init__(self,driver=None):
            self.driver = driver
    
    
        def start(self):
        # 初始化app
            if self.driver==None:
                desired_caps = {}
                desired_caps['platformName'] = 'Android' 
                desired_caps['deviceName'] = 'emulator-5554'         
                desired_caps['appPackage'] = 'com.xueqiu.android'
                desired_caps['appActivity'] = 'view.WelcomeActivityAlias'
                #desired_caps['noReset'] = 'True'
    
                self.driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)  # 类似于driver = webdriver.Chrome()
                self.driver.implicitly_wait(10)
            return self.driver
    
    from py_page.app import App
    from appium.webdriver.common.mobileby import MobileBy as By
    
    class MainPage(App):
    
    
        def goto_myPage(self):
            # 在首页进入【我的】页面
            self.driver.find_element(By.XPATH, "//*[@text='我的']").click()
            from py_page.my_page import MyPage
            return MyPage(self.driver)
    
    from py_page.app import App
    from appium.webdriver.common.mobileby import MobileBy as By
    
    class MyPage(App):
    
    
        def goto_login(self):
            # 在我的页面进入【登录】页面
            self.driver.find_element(By.XPATH, "//*[@text='账号密码登录']").click()
            from py_page.login_page import LoginPage
            return LoginPage(self.driver)
    
        def is_cancel(self):
            # 对一键导入弹框进行判断处理
            try:
                self.driver.find_element(By.XPATH, "//*[@text='取消']").click()
            except:
                pass
            return self
    
        def get_login_name(self):
            # 登录后在我的页面获取登录昵称
            name_ele = self.driver.find_element(By.XPATH, "//*[@resource-id='com.xueqiu.android:id/name']")
            name_text = name_ele.get_attribute("text")
            return name_text
    
    from py_page.app import App
    from appium.webdriver.common.mobileby import MobileBy as By
    
    class LoginPage(App):
    
    
        def account_login(self):
            # 在登录页面进行账号密码登录
            self.driver.find_element(By.XPATH, "//*[@text='我的']").click()
            self.driver.find_element(By.XPATH, "//*[@text='帐号密码登录']").click()
            self.driver.find_element(By.XPATH, "//*[@resource-id='com.xueqiu.android:id/login_account']").send_keys(
                '13262506790')
            self.driver.find_element(By.XPATH, "//*[@resource-id='com.xueqiu.android:id/login_password']").send_keys('1111111a')
            self.driver.find_element(By.XPATH, "//*[@text='登录']").click()
            from py_page.my_page import MyPage
            return MyPage(self.driver)
    
    from py_page.main_page import MainPage
    
    class TestLogin:
    
        def test_login_pos(self):
            name_text = MainPage().goto_myPage().goto_login().account_login().is_cancel().get_login_name()
            print(name_text)
            assert name_text == '思源_smile'
    

    基于上面代码修改app后原测试用例会报错,想一想这是为什么?
    因为测试用例中调用MainPage()时由于继承了app,会调用app中的构造方法初始化一个driver=None,但goto_myPage()中有self.driver.find_element(By.XPATH, “//*[@text=’我的’]”).click(),然而这个driver是一个None自然没有find_element这个方法
    修改方案如下

    from appium import webdriver
    from appium.webdriver.common.mobileby import MobileBy as By
    from appium.webdriver.common.touch_action import TouchAction
    
    
    
    class App:
    
        def __init__(self,driver=None):
            self.driver = driver
    
    
        def start(self):
        # 初始化app
            if self.driver==None:
                desired_caps = {}
                desired_caps['platformName'] = 'Android' 
                desired_caps['deviceName'] = 'emulator-5554'         
                desired_caps['appPackage'] = 'com.xueqiu.android'
                desired_caps['appActivity'] = 'view.WelcomeActivityAlias'
                #desired_caps['noReset'] = 'True'
    
                self.driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)  # 类似于driver = webdriver.Chrome()
                self.driver.implicitly_wait(10)
            return self
    
        def main(self):
            from py_page.main_page import MainPage
            return MainPage(self.driver)
    

    测试用例修改如下:

    from py_page.main_page import MainPage
    from py_page.app import App
    
    class TestLogin:
    
        def test_login_pos(self):
            name_text = App().start().main().goto_myPage().goto_login().account_login().is_cancel().get_login_name()
            print(name_text)
            assert name_text == '思源_smile'
    

    7、继续优化py_page,使元素定位及交互从页面类中分离,减少页面类中的代码量,方便维护与管理
    (1)在py_page中新建base_page.py封装页面基类,实现对页面元素的定位及交互,页面元素的查找常用有两种形式:查找单个元素&&查找多个元素集,即封装find && finds方法,每个查找元素的形式包含id, xpath, class ,ACCESSIBILITY_ID四种方式故作如下封装,由于BasePage中find&&finds方法需要用到driver,故BasePage初始化一个driver来实现调用self.driver

    from appium.webdriver.common.mobileby import MobileBy as By
    
    
    class BasePage:
    
         def __init__(self, driver: webdriver = None):
            self.driver = driver
    
    
        def find(self, by, locator):
            by_locator = None
            if by == 'id' or by == 'ID':
                by_locator = (By.ID, locator)
            elif by == 'xpath' or by == 'XPATH':
                by_locator = (By.XPATH, locator)
            elif by == 'class' or by == 'CLASS':
                by_locator = (By.CLASS_NAME, locator)
            elif by == 'ACCESSIBILITY_ID' or by == 'accessibility_id':
                by_locator = (By.ACCESSIBILITY_ID, locator)
            ele = self.driver.find_element(*(by_locator))
            return ele
    
        def finds(self, by, locator):
            by_locator = None
            if by == 'id' or by == 'ID':
                by_locator = (By.ID, locator)
            elif by == 'xpath' or by == 'XPATH':
                by_locator = (By.XPATH, locator)
            elif by == 'class' or by == 'CLASS':
                by_locator = (By.CLASS_NAME, locator)
            elif by == 'ACCESSIBILITY_ID' or by == 'accessibility_id':
                by_locator = (By.ACCESSIBILITY_ID, locator)
            eles = self.driver.find_elements(*(by_locator))
            return eles
    
        def find_and_click(self, by, locator):
            ele = self.find(by, locator)
            ele.click()
    
        def finds_and_click(self, by, locator, index):
            eles = self.finds(by, locator)
            eles[index].click()
    
        def finds_and_send(self, by, locator, index, text):
            eles = self.finds(by, locator)
            eles[index].send_keys(text)
    
        def find_and_send(self, by, locator, text):
            self.find(by, locator).send_keys(text)
    
        def find_and_clear(self, by, locator):
            self.find(by, locator).clear()
    
        @staticmethod
        def get_yaml_eles(yaml_path):
            with open(yaml_path, "r", encoding="UTF-8") as f:
                datas = yaml.safe_load(f)
            return datas
    

    修改app.py,使App继承BasePage, 因此调用这个App()时会调用BasePage中的构造方法,初始化一个self.driver==None

    from appium import webdriver
    from appium.webdriver.common.mobileby import MobileBy as By
    from appium.webdriver.common.touch_action import TouchAction
    
    from py_page.base_page import BasePage
    
    
    
    
    class App(BasePage):
    
    
        def start(self):
        # 初始化app
            if self.driver==None:
                desired_caps = {}
                desired_caps['platformName'] = 'Android' # 'Android' or ’Ios'
                desired_caps['deviceName'] = 'emulator-5554'
                desired_caps['appPackage'] = 'com.xueqiu.android'
                desired_caps['appActivity'] = 'view.WelcomeActivityAlias'
                #desired_caps['noReset'] = 'True'
    
                self.driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)  # 类似于driver = webdriver.Chrome()
                self.driver.implicitly_wait(10)
            return self
    
        def main(self):
            from py_page.main_page import MainPage
            return MainPage(self.driver)
    
    
        def stop(self):
            self.driver.quit()
    

    �py_page中其他页面类继承页面基类BasePage,使得页面类能够调用页面基类中元素定位及交互方法,后续在测试中需要用到页面元素交互的方法都可以封装在BasePage中,供页面类直接调用;
    基于BasePage的封装,优化py_page中页面类的代码实现:

    from appium.webdriver.common.mobileby import MobileBy as By
    
    from py_page.base_page import BasePage
    
    class MainPage(BasePage):
    
    
        def goto_myPage(self):
            # 在首页进入【我的】页面
            self.find_and_click(By.XPATH, "//*[@text='我的']")
            from py_page.my_page import MyPage
            return MyPage(self.driver)
    
    from appium.webdriver.common.mobileby import MobileBy as By
    
    from py_page.base_page import BasePage
    
    class MyPage(BasePage):
    
    
        def goto_login(self):
            # 在我的页面进入【登录】页面
            self.find_and_click(By.XPATH, "//*[@text='帐号密码登录']")
            from py_page.login_page import LoginPage
            return LoginPage(self.driver)
    
        def is_cancel(self):
            # 对一键导入弹框进行判断处理
            try:
                self.find_and_click(By.XPATH, "//*[@text='取消']")
            except:
                pass
            return self
    
        def get_login_name(self):
            # 登录后在我的页面获取登录昵称
            name_ele = self.find(By.XPATH, "//*[@resource-id='com.xueqiu.android:id/name']")
            name_text = name_ele.get_attribute("text")
            return name_text
    
    from appium.webdriver.common.mobileby import MobileBy as By
    
    from py_page.base_page import BasePage
    
    class LoginPage(BasePage):
    
    
        def account_login(self):
            # 在登录页面进行账号密码登录
            self.find_and_send(By.XPATH, "//*[@resource-id='com.xueqiu.android:id/login_account']",'13262506790')
            self.find_and_send(By.XPATH, "//*[@resource-id='com.xueqiu.android:id/login_password']",'1111111a')
            self.find_and_click(By.XPATH, "//*[@text='登录']")
            from py_page.my_page import MyPage
            return MyPage(self.driver)
    

    (2)把py_page页面类中的页面元素集中管理,从代码中分离,当前端页面元素及交互变更时,我们减少对页面类中代码的修改,从数据载体中集中统一维护;
    新建yaml_page,yaml_page文件夹下对应每一个页面类创建对应的yamlPage
    login_page.yaml

    account_login:
      login_account: [XPATH, "//*[@resource-id='com.xueqiu.android:id/login_account']"]
      login_password: [XPATH, "//*[@resource-id='com.xueqiu.android:id/login_password']"]
      login_button: [XPATH, "//*[@text='登录']"]
    

    main_page.yaml

    goto_myPage:
      my: [XPATH, "//*[@text='我的']"]
    

    my_page.yaml

    goto_login:
      account_login: [XPATH, "//*[@text='帐号密码登录']"]
    
    is_cancel:
      cancel: [XPATH, "//*[@text='取消']"]
    
    get_login_name:
      login_name: [XPATH, "//*[@resource-id='com.xueqiu.android:id/name']"]
    

    修改对应py_page中页面类中的代码
    mian_page.py

    from py_page.base_page import BasePage
    
    class MainPage(BasePage):
    
        yaml_path = './yaml_page/main_page.yaml'
        yaml_datas = BasePage.get_yaml_eles(yaml_path)
    
    
        def goto_myPage(self):
            # 在首页进入【我的】页面
            datas = self.yaml_datas['goto_myPage']
            self.find_and_click(*datas['my'])
            from py_page.my_page import MyPage
            return MyPage(self.driver)
    

    (3)继续优化py_page中页面类的代码,下面login_page.py中的account_login方法包含多个步骤,可用行为驱动的方式优化
    login_page.py

    from py_page.base_page import BasePage
    
    class LoginPage(BasePage):
    
        yaml_path = './yaml_page/login_page.yaml'
        yaml_datas = BasePage.get_yaml_eles(yaml_path)
    
        def account_login(self):
            # 在登录页面进行账号密码登录
            datas = self.yaml_datas['account_login']
            self.find_and_send(*datas['login_account'],'13262506790')
            self.find_and_send(*datas['login_password'],'1111111a')
            self.find_and_click(*datas['login_button'])
            from py_page.my_page import MyPage
            return MyPage(self.driver)