pageobject分级设计模式

pageobject分级设计模式的思路

将一些公共的模块抽离出来
将元素定位方法和元素属性与业务代码分离
将功能模块封装成一个个独立的单元模块
使用unittest框架进行用例的综合管理

pageobject的目录结构

在这里插入图片描述

common里的disired_caps公共模块

from selenium import webdriver
from appium import webdriver
import yaml
import logging
import logging.config
import os
CON_LOG = '../config/log.conf'
logging.config.fileConfig(CON_LOG)
logging = logging.getLogger()

def appium_disired():
    with open('../config/kyb_caps.yaml', 'r', encoding='utf-8') as file:
        data = yaml.load(file, Loader=yaml.FullLoader)
        #解决文件没有被释放的问题
    base_path = os.path.dirname(os.path.dirname(__file__))
    app_path = os.path.join(base_path, 'app', data['appname'])
    desired_caps = {}
    desired_caps['platformName'] = data['platformName']  # android的apk还是IOS的ipa
    desired_caps['platformVersion'] = data['platformVersion']  # android系统的版本号
    desired_caps['deviceName'] = data['deviceName']  # 手机设备名称,通过adb devices  查看
    desired_caps['app'] = app_path
    desired_caps['appPackage'] = data['appPackage']  # apk的包名
    desired_caps['appActivity'] = data['appActivity']  # apk的launcherActivity
    # 不需要再次签名
    desired_caps['noSign'] = data['noSign']
    # 不需要清理数据,避免重新安装的问题
    desired_caps['noReset'] = data['noReset']
    # desired_caps['unicodeKeyboard'] = True   #使用unicodeKeyboard的编码方式来发送字符串,中文方式
    # desired_caps['resetKeyboard'] = True   #将键盘给隐藏起来
    driver = webdriver.Remote('http://' + str(data['ip']) + ':' + str(data['port']) + '/wd/hub', desired_caps)
    logging.info('caps ready')
    return driver
if __name__ == '__main__':
    appium_disired()

baseView模块,包含driver初始化,定位元素等

class BaseView(object):
    def __init__(self, driver):
        self.driver = driver
    def find_element(self, *loc):
        return self.driver.find_element(*loc)
    def find_elements(self,*loc):
        return self.driver.find_elements(*loc)
    def get_window_size(self):
        return self.driver.get_window_size()
    def swipe(self,start_x, start_y, end_x, end_y, duration):
        return self.driver.swipe(start_x, start_y, end_x, end_y, duration)

common模块,有如检查元素的方法,左右滑动,截图等方法

import logging
from baseView.baseView import BaseView
from common.disired_caps import appium_disired
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.common.by import By
import time
import os
import csv
class Common(BaseView):
    cancelBtn = (By.ID, 'android:id/button2')
    skipBtn = (By.ID, 'com.tal.kaoyan:id/tv_skip')
    wemedia_cacel = (By.ID, 'com.tal.kaoyan:id/view_wemedia_cacel')
    def check_cancelBtn(self):
        try:
            cancelBtn = self.driver.find_element(*self.cancelBtn)
        except NoSuchElementException:
            logging.info('no element')
        else:
            cancelBtn.click()
    def check_skipBtn(self):
        try:
            skipBtn = self.driver.find_element(*self.skipBtn)
        except NoSuchElementException:
            logging.info('no element')
        else:
            skipBtn.click()
    def get_size(self):
        x = self.driver.get_window_size()['width']
        y = self.driver.get_window_size()['height']
        return x, y
    def swipeLeft(self):
        l =self.get_size()
        x1 = int(l[0] * 0.9)
        y1 = int(l[1] * 0.5)
        x2 = int(l[0] * 0.1)
        self.swipe(x1, y1, x2, y1, 1000)
    def getTime(self):
        self.now = time.strftime("%Y-%m-%d-%H-%M-%S")
        return self.now
    def getScreenShot(self,module):
        time = self.getTime()
        image_file = os.path.dirname(os.path.dirname(__file__))+'/screenshots/%s_%s.png'%(module, time)
        logging.info('get %s screenshot' %module)
        self.driver.get_screenshot_as_file(image_file)
    def check_marcket_ad(self):
        logging.info('check_market_ad')
        try:
             element = self.driver.find_element(self.wemedia_cacel)
        except NoSuchElementException:
            pass
        else:
            element.click()

if __name__ == '__main__':
    driver = appium_disired()
    com = Common(driver)
    com.check_cancelBtn()
    #com.check_skipBtn()
    com.swipeLeft()
    com.getScreenShot('startApp')

功能模块继承自common,里面有如登录过程,检查登录状态等用例可调用函数

from common.disired_caps import appium_disired
from common.Common import Common
from selenium.webdriver.common.by import By
from selenium.common.exceptions import NoSuchElementException
import logging
from collections import namedtuple
import re
from time import sleep
import csv
class LoginView(Common):
    username_type = (By.ID, 'com.tal.kaoyan:id/login_email_edittext')
    password_type = (By.ID, 'com.tal.kaoyan:id/login_password_edittext')
    login_button = (By.ID, 'com.tal.kaoyan:id/login_login_btn')
    tip_commit = (By.ID, 'com.tal.kaoyan:id/tip_commit')
    button_mysefl = (By.ID, 'com.tal.kaoyan:id/mainactivity_button_mysefl')
    username = (By.ID, 'com.tal.kaoyan:id/activity_usercenter_username')
    RightButton = (By.ID, 'com.tal.kaoyan:id/myapptitle_RightButton_textview')
    logoutButton = (By.ID, 'com.tal.kaoyan:id/setting_logout_text')
    def login_action(self,username,password):
        self.check_cancelBtn()
        self.check_skipBtn()
        self.driver.find_element(*self.username_type).send_keys(username)
        self.driver.find_element(*self.password_type).send_keys(password)
        self.driver.find_element(*self.login_button).click()
        sleep(2)
    def check_account_alert(self):
        logging.info('=====check_account=====')
        try:
           element = self.driver.find_element(*self.tip_commit)
        except NoSuchElementException:
            pass
        else:
            logging.info('=====close tip_commit=====')
            element.click()
    def check_login_status(self):
        logging.info('=====check_login_status====')
        self.check_marcket_ad()
        self.check_account_alert()
        try:
           button_mysefl = self.driver.find_element(*self.button_mysefl)
        except NoSuchElementException:
            pass
        else:
            logging.info('=====click_button_myself=====')
            button_mysefl.click()
        try:
           element = self.driver.find_element(*self.username)
        except NoSuchElementException:
            logging.error('=======check_status_fail========')
            self.driver.getScreenShot('login_fail')
            return False
        else:
            logging.info('=====check_status_success=====')
            self.logout_action()
            return True
    def logout_action(self):
        logging.info('=====logout_action=====')
        self.driver.find_element(*self.RightButton).click()
        self.driver.find_element(*self.logoutButton).click()
        self.driver.find_element(*self.tip_commit).click()
    def get_csv_data(csv_file):
        with open(csv_file, encoding='utf-8-sig') as file:
            f_csv = csv.reader(file)
            headings = next(f_csv)
            # print(headings)
            # for row in f_csv:
            #     print(row)
            Row = namedtuple('Row', headings)
            for r in f_csv:
                row = Row(*r)
                print(row.No)  # 可直接通过row.Date等获取相应的元素
                if(row.No == '1'):
                    print(row.username)
        with open(csv_file, encoding='utf-8-sig') as f:
            f_csv = csv.DictReader(f)
            for row in f_csv:
                print(row['No'])
                if (row['No'] == '1'):
                    print(row['username'])
       
            return
if __name__ == '__main__':
    driver = appium_disired()
    l = LoginView(driver)
    l.login_action('15813384616', 'zhixue666666')
    l.check_login_status()
    # for i in range(4):
    # get_csv_data('../data/account.csv')

使用unittest封装用例的StartEnd模块

unittest使用流程
定义StartEnd类继承unittest.TestCase,实现setUp和TearDown方法

import unittest
from common.Common import appium_disired
import logging
from time import sleep

class StartEnd(unittest.TestCase):
    def setUp(self):
        logging.info('start')
        self.driver = appium_disired()
    def tearDown(self):
        logging.info('end')
        sleep(5)
        self.driver.close_app()
具体测试模块继承自StartEnd,进行数据驱动管理,从csv中读取用例,并测试返回值
from common.myunit import StartEnd
from business.loginView import LoginView
import logging
import unittest
#author aojaovie

class LoginTest(StartEnd):
    csv_file = '../data/account.csv'
    @unittest.skip("unitest_login_1")
    def testlogin1(self):
        logging.info('login test')
        l = LoginView(self.driver)
        data = l.get_csv_data(self.csv_file, 1)
        l.login_action(data[0], data[1])
        self.assertTrue(l.check_login_status())

    @unittest.skip("unitest_login_2")
    def testlogin2(self):
        logging.info('login test')
        l = LoginView(self.driver)
        data = l.get_csv_data(self.csv_file, 2)
        l.login_action(data[0], data[1])
        self.assertTrue(l.check_login_status())

    #@unittest.skip("unitest_login_error")
    def testlogin3(self):
        logging.info('login test')
        l = LoginView(self.driver)
        data = l.get_csv_data(self.csv_file, 3)
        l.login_action(data[0], data[1])
        self.assertTrue(l.check_login_status(), msg='login fail')
if __name__ == '__main__':
    unittest.main()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值