Appium Page Object 模式断言是否应该包含在 Page 对象中?

Sutune · January 09, 2018 · Last by 克克克劳德 replied at July 30, 2019 · 1871 hits

问题描述

当前我是将断言和业务流程封装在 page 对象之中,然后在 unittest 直接去调用对应的方法执行,没有单独使用 unittest 的 assert 断言。部分代码所下所示:

page 层-DeepRecoveryView

class DeepRecoveryView(RecycleBinView,BasicRecoveryView):
    btnDeepRecovery=(By.ID,'com.wondershare.drfone:id/btnDeepRecovery')
    nextBtn=(By.ID,'com.wondershare.drfone:id/btnRecoverData')
    try_DeeprecoverBtn=(By.ID,'com.wondershare.drfone:id/onePageTxt')


    dialog_ok=(By.ID,'com.wondershare.drfone:id/dialog_ok')
    btnHideDeepRecovery=(By.ID,'com.wondershare.drfone:id/btnHideDeepRecovery')

    def deep_recover_h5_action(self):
        ''' 扫描完成后下一步进行发送邮件操作'''

        # 等待next按钮出现
        WebDriverWait(self.driver, 20).until(lambda x: x.find_element(*self.nextBtn_loc))
        #点击next按钮
        self.find_element(*self.nextBtn_loc).click()
        self.type_h5_action()

    def check_recycleBin(self):
        '''
        检测扫描结果页面是否存在资源
        :return: True,False
        '''
        try:
            self.find_element(*self.imageBtn)
        except NoSuchElementException:
            logging.info('No resource')
            return False
        else:
            logging.info('Resource exist!')
            return True

    def deepRecovery_from_recycleBin(self):
        '''
        从recycle bin进入
        '''
        self.open_recycleBin_page()
        #如果存在资源则直接点击资源下方的Banner菜单,没有资源则点击界面文字“Deep recobery”
        logging.info('========deepRecovery_from_recycleBin==========')

        if self.check_recycleBin():
            #点击页面下方banner栏恢复
            self.getScreenShot('deepRecovery_from_recycleBin')
            self.find_element(*self.try_DeeprecoverBtn).click()
            self.deep_recover_h5_action()
        else:
            #点击页面深度恢复文字提示
            self.getScreenShot('deepRecovery_from_recycleBin')
            self.find_element(*self.btnDeepRecovery).click()
            self.deep_recover_h5_action()

        #退出到主界面
        for i in range(3):
            self.find_element(*self.closeBtn).click()

    def deepRecover_from_RecoverMenu(self):
        '''
        从Recovery 主菜单页面 进入
        '''
        logging.info('============= deepRecover_from_RecoverMenu =============')
        #进入recover界面主页
        self.find_element(*self.basic_recoveryBtn).click()
        self.getScreenShot('deepRecover_from_RecoverMenu')
        #点击deep recovery
        self.find_element(*self.btnDeepRecovery).click()
        self.deep_recover_h5_action()

        # 退出到主界面
        for i in range(3):
            self.find_element(*self.closeBtn).click()

    def deepRecover_from_quickRecover(self):
        '''
        #从quickRecovery 进入
        '''
        logging.info('===============deepRecover_from_quickRecover============')
        self.open_quickRecover_page()
        if self.check_quickRecover_resource():
            #如果存在资源向上滑动屏幕
            self.swipeUp()
            self.find_element(*self.btnHideDeepRecovery).click()
            self.getScreenShot('deepRecover_from_quickRecover')
            self.deep_recover_h5_action()

        else:
            # 没有资源点击页面深度恢复文字提示
            logging.info('start click btnDeepRecovery')
            self.getScreenShot('deepRecover_from_quickRecover')
            self.find_element(*self.btnDeepRecovery).click()
            self.deep_recover_h5_action()

        # 退出到主界面
        for i in range(4):
            self.find_element(*self.closeBtn).click()

unittest

class TestDeepRecovery(StartEnd):
    @tag(Tag.DR,Tag.SMOKE,Tag.DR_High)
    def test_deepRecovery_from_recycleBin(self):
        """从recycleBin入口恢复"""
        deep=DeepRecoveryView(self.driver)
        deep.deepRecovery_from_recycleBin()

    @tag(Tag.DR,Tag.SMOKE,Tag.DR_High)
    def test_deepRecover_from_RecoverMenu(self):
        """从Recover主菜单恢复"""
        deep=DeepRecoveryView(self.driver)
        deep.deepRecover_from_RecoverMenu()

但是看到一种说法说这样会 混合访问页面数据和断言逻辑的职责,导致 page 层过于臃肿,不应当在 page 层中包含断言,不知大家是如何设计断言的?

共收到 11 条回复 时间 点赞

我的理解是 page 就是 page,断言还是放 case 里面吧

没啥应该不应该,看具体情况和个人习惯。如果重复 asster 写很多为啥不封装呢?具体怎么封装就看个人习惯和要求了。

看习惯

业务流程比较简单放 case 里面其实还是可以的,但是业务流程场景比较复杂的话放 case 有点不太方便。

chen 回复

嗯,这个得根据项目实际情况来处理。

恒温 回复

ok,谢谢指点。😀

Sutune 回复

我喜欢把断言放在测试用例里,把页面逻辑放在 po 里

Sutune 回复

理论上来说,一些 assertion 放到 page 里面,多 cases 调用相同方法的时候,会少很多事,但是我觉得 case 还是应该就是 case,page 就是 page。当然了,主要还是习惯了,只要你们团队认可就行了,主要还是团队好执行好写即可

个人习惯,功能测试用例管输入和输出,所以断言在用例,page 管流程(方法)和页面元素(属性),这是比较面向对象的对象,当然,这个看具体要求吧,怎么方便怎么做

Sutune #10 · January 10, 2018 Author
terrychow 回复

嗯,断言在用例里面还有一个好处就是生成的 html 报告对应的测试结果 Pass,Fail 会比较直观的展示,而放在 page 层就比较笼统,只有脚本运行出错才会显示对应报错信息。

也看用例怎么设计的吧,比如做数据驱动,我的业务层就封装业务,用例调用业务层方法会在数据驱动下有不同测试结果,所以不同用例用同一业务肯定结果不同,就要在用例中断言

需要 Sign In 后方可回复, 如果你还没有账号请点击这里 Sign Up