前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Appium自动化测试框架综合实践

Appium自动化测试框架综合实践

作者头像
清风穆云
发布2021-08-09 10:54:13
7080
发布2021-08-09 10:54:13
举报
文章被收录于专栏:QA一隅

框架功能

  • 业务功能的封装
  • 测试用例封装
  • 测试包管理
  • 截图处理
  • 断言处理
  • 日志获取
  • 测试报告生成
  • 数据驱动
  • 数据配置

测试案例

测试环境
  • Win10 64Bit
  • Appium 1.7.2
  • 考研帮App Android版3.1.0
  • 夜神模拟器 Android 5.1.1
覆盖用例

1.登录场景

用户名

密码

自学网2018

zxw2018

自学网2017

zxw2017

666

222

2.注册场景

注册一个新的账号(账户和密码可以随机生成),完善院校和专业信息 (如:院校:上海-同济大学 专业:经济学类-统计学-经济统计学)

框架设计图

代码实现

driver配置封装

kyb_caps.yaml 配置表

代码语言:javascript
复制
platformName: Android
#模拟器
platformVersion: 5.1.1
deviceName: 127.0.0.1:62025

#mx4真机
#platformVersion: 5.1
#udid: 750BBKL22GDN
#deviceName: MX4

appname: kaoyan3.1.0.apk
noReset: False
unicodeKeyboard: True
resetKeyboard: True

appPackage: com.tal.kaoyan
appActivity: com.tal.kaoyan.ui.activity.SplashActivity
ip: 127.0.0.1
port: 4723

desired_caps.py

代码语言:javascript
复制
import yaml
import logging.config
from appium import webdriver
import os

CON_LOG = '../config/log.conf'
logging.config.fileConfig(CON_LOG)
logging = logging.getLogger()

def appium_desired():

    with open('../config/kyb_caps.yaml','r',encoding='utf-8') as file:
        data = yaml.load(file)

    desired_caps={}
    desired_caps['platformName']=data['platformName']

    desired_caps['platformVersion']=data['platformVersion']
    desired_caps['deviceName']=data['deviceName']

    base_dir = os.path.dirname(os.path.dirname(__file__))
    app_path = os.path.join(base_dir, 'app', data['appname'])
    desired_caps['app'] = app_path

    desired_caps['noReset']=data['noReset']

    desired_caps['unicodeKeyboard']=data['unicodeKeyboard']
    desired_caps['resetKeyboard']=data['resetKeyboard']

    desired_caps['appPackage']=data['appPackage']
    desired_caps['appActivity']=data['appActivity']

    logging.info('start run app...')
    driver = webdriver.Remote('http://'+str(data['ip'])+':'+str(data['port'])+'/wd/hub', desired_caps)

    driver.implicitly_wait(5)
    return driver


if __name__ == '__main__':
    appium_desired()

    # with open('../config/kyb_caps.yaml','r',encoding='utf-8') as file:
    #    data = yaml.load(file)

    #base_dir = os.path.dirname(os.path.dirname(__file__))
    #app_path = os.path.join(base_dir, 'app', data['appname'])
    #print(app_path)


基类封装

baseView.py

代码语言:javascript
复制
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公共模块封装

公共方法封装 : common_fun.py

代码语言:javascript
复制
from  baseView.baseView import BaseView
from common.desired_caps import appium_desired
from selenium.common.exceptions import NoSuchElementException
import logging.config
from selenium.webdriver.common.by import By
import os
import time
import csv


class Common(BaseView):

    #取消升级和跳过引导按钮
    cancel_upgradeBtn=(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_updateBtn(self):
        logging.info("============check_updateBtn===============")

        try:
            element = self.driver.find_element(*self.cancel_upgradeBtn)
        except NoSuchElementException:
            logging.info('update element is not found!')
        else:
            logging.info('click cancelBtn')
            element.click()

    def check_skipBtn(self):
        logging.info("==========check_skipBtn===========")
        try:
            element = self.driver.find_element(*self.skipBtn)
        except NoSuchElementException:
            logging.info('skipBtn element is not found!')
        else:
            logging.info('click skipBtn')
            element.click()

    def get_screenSize(self):
        '''
        获取屏幕尺寸
        :return:
        '''
        x = self.get_window_size()['width']
        y = self.get_window_size()['height']
        return (x, y)


    def swipeLeft(self):
        logging.info('swipeLeft')
        l = self.get_screenSize()
        y1 = int(l[1] * 0.5)
        x1 = int(l[0] * 0.95)
        x2 = int(l[0] * 0.25)
        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_market_ad(self):
        '''检测登录或者注册之后的界面浮窗广告'''
        logging.info('=======check_market_ad=============')
        try:
            element=self.driver.find_element(*self.wemedia_cacel)
        except NoSuchElementException:
            pass
        else:
            logging.info('close market ad')
            element.click()
    
    def get_csv_data(self,csv_file,line):
        '''
        获取csv文件指定行的数据
        :param csv_file: csv文件路径
        :param line: 数据行数
        :return:
        '''
        with open(csv_file, 'r', encoding='utf-8-sig') as file:
            reader=csv.reader(file)
            for index, row in enumerate(reader,1):
                if index == line:
                    return row
    

if __name__ == '__main__':
    driver=appium_desired()
    # c=Common(driver)
    # c.check_updateBtn()
    # # c.check_skipBtn()
    # c.swipeLef()
    # c.swipeLef()
    # c.getScreenShot("startApp")



业务模块封装

1.登录页面业务逻辑模块

loginView.py

代码语言:javascript
复制
import logging
from common.desired_caps import appium_desired
from common.common_fun import Common,By
from selenium.common.exceptions import NoSuchElementException

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')
    loginBtn=(By.ID,'com.tal.kaoyan:id/login_login_btn')

    #个人中心元素
    username=(By.ID,'com.tal.kaoyan:id/activity_usercenter_username')
    button_myself=(By.ID,'com.tal.kaoyan:id/mainactivity_button_mysefl')

    # 个人中心下线警告提醒确定按钮
    commitBtn = (By.ID, 'com.tal.kaoyan:id/tip_commit')

    #退出操作相关元素
    settingBtn = (By.ID, 'com.tal.kaoyan:id/myapptitle_RightButtonWraper')
    logoutBtn=(By.ID,'com.tal.kaoyan:id/setting_logout_text')
    tip_commit=(By.ID,'com.tal.kaoyan:id/tip_commit')

    def login_action(self,username,password):
        self.check_updateBtn()
        self.check_skipBtn()

        logging.info('============login_action==============')
        logging.info('username is:%s' % username)
        self.driver.find_element(*self.username_type).send_keys(username)

        logging.info('password is:%s' % password)
        self.driver.find_element(*self.password_type).send_keys(password)

        logging.info('click loginBtn')
        self.driver.find_element(*self.loginBtn).click()
        logging.info('login finished!')

    def check_account_alert(self):
        '''检测账户登录后是否有账户下线提示'''
        logging.info('====check_account_alert======')
        try:
            element = self.driver.find_element(*self.commitBtn)
        except NoSuchElementException:
            pass
        else:
            logging.info('click commitBtn')
            element.click()


    def check_loginStatus(self):
        logging.info('==========check_loginStatus===========')
        self.check_market_ad()
        self.check_account_alert()
        
        try:
            self.driver.find_element(*self.button_myself).click()
            self.driver.find_element(*self.username)
        except NoSuchElementException:
            logging.error('login Fail!')
            self.getScreenShot('login Fail')
            return False
        else:
            logging.info('login success!')
            self.logout_action()
            return True

    def logout_action(self):
        logging.info('=========logout_action==========')
        self.driver.find_element(*self.settingBtn).click()
        self.driver.find_element(*self.logoutBtn).click()
        self.driver.find_element(*self.tip_commit).click()

if __name__ == '__main__':
    driver=appium_desired()
    l=LoginView(driver)
    l.login_action('自学网2018','zxw2018')
    l.check_loginStatus()
    



注册页面业务逻辑封装

registerView.py

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-07-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 QA一隅 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 框架功能
  • 测试案例
    • 测试环境
      • 覆盖用例
      • 框架设计图
      • 代码实现
        • driver配置封装
          • 基类封装
            • common公共模块封装
              • 业务模块封装
                • 1.登录页面业务逻辑模块
                • 注册页面业务逻辑封装
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档