Appium 求问 page object 框架下如何处理 page 之间的跳转问题

lvxy · 2021年08月09日 · 最后由 YoungLeo 回复于 2022年06月22日 · 4069 次阅读

比如一个登录注销的流程:

\\page_object\login_page.py

from page_object import BasePage
from page_object import MainPage

class LoginPage(BasePage):
    ...

    def login(self):
        ...
        self.click(self.btn_login)
        return MainPage() 

\\page_object\main_page.py

from page_object import BasePage
from page_object import LoginPage # 会报错

class MainPage(BasePage):
    ...

    def logout(self):
        ...
        self.click(self.btn_logout)
        return LoginPage()

这样相互 Import 肯定是会报错的,所以想问一下这样可以相互跳转的界面应该如何处理呢?

共收到 10 条回复 时间 点赞

简单粗暴的解决办法是在 logout 方法的内部 import LoginPage 。
或者想想 logout 为什么要得到一个 LoginPage 对象呢,哪里要用这个返回值,有没有替代方案。

lvxy #2 · 2021年08月09日 Author
MarvinWu 回复

这样在 testcase 里 只需要 import MainPage 就可以了

\\test_case\test_login_module.py
from page_object import MainPage

class test_login_module():

    def test_logout(self):
        ...
        login_page = MainPage().logout()
        assert login_page.find_element_by_id(login_page.btn_login) != None

你这是要测试登录--》注销的一个流程?login 可以写个公共的方法吧,注销的时候调一下。或者使用 pytest 框架的话可以将 login 写到 conftest 里面用,我想这样应该可以解决。

lvxy #4 · 2021年08月09日 Author
七街老酒 回复

登录界面只是一个举例,类似的还有群聊,从主界面进入邀请界面,勾选联系人以后点击创建,跳转到群聊界面,在群聊界面又可以跳转到邀请界面

看这架势是我没说明白😅
粗暴解决:

from page_object import BasePage


class MainPage(BasePage):
    ...

    def logout(self):
        from page_object import LoginPage # 放这里不报错
        ...
        self.click(self.btn_logout)
        return LoginPage()

或者在用例里

\\test_case\test_login_module.py
from page_object import MainPage
from page_object import LoginPage
class test_login_module():

    def test_logout(self):
        ...
        MainPage().logout()
        login_page = LoginPage()
        # 下面的断言也不太合适,都面向页面了,就别在用例里查找元素了吧
        assert login_page.find_element_by_id(login_page.btn_login) != None

5 楼正解,不要放到脚本最上面,哪里用才引入包,就可以了

5 楼正解。就是这么操作,不要放程序最上面,放到需要用到的方法里面可以解决相互依赖的问题

1 楼和 5 楼是同一个人的解答,我倾向同意 1 楼不同意 5 楼。
确切说我同意的是 1 楼这句 “logout 为什么要得到一个 LoginPage 对象呢,哪里要用这个返回值”。别人都是努力让模块间解耦,你的做法刚好相反,是在强行引入耦合。明确职责范围划分,login 方法做到点击 login 按钮就够了,不该返回 mainpage 对象。logout 方法同理。
testcase 层分别引用 loginpage 和 mainpage。测试登录,先调用 loginpage 提供的 login 方法,再调用 mainpage 提供的结果验证方法,这种做法是不是更清晰明了些?

一个页面的元素 能单独操作的就封装成一个 如点击 输入 都单独封装成方法 最后封装一个该页面核心流程的方法
到时候在写测试用例时,可以灵活调用每个页面的各个按钮,或者核心方法进行融合成一个整体业务流程

之前做过一种方法是在底层基类封装一个 goto 跳转函数,做当前页面到目标页面跳转的操作逻辑,所有页面跳转都调用它进行

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