app自动化测试框架(一、框架的搭建)

一、
(1)、创建autotest_app项目
(2)、封装元素的各类操作


image.png
pip install selenium
pip install Appium-Python-Client

basepage.py

from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from appium.webdriver.common.mobileby import MobileBy
from common.logger import Log
import datetime

class BasePage:

    def __init__(self,driver):
        self.driver = driver
        self.logger =Log()

    #等待元素可见
    def wait_eleVisible(self,locator,by=MobileBy.ID,wait=30,requence=0.5):
        try:
            start = datetime.datetime.now()
            WebDriverWait(self.driver,wait,requence).until(EC.visibility_of_element_located((by, locator)))
            end = datetime.datetime.now()
            wait_times = (end - start).seconds
            self.logger.info("等待元素可见:{0},起始时间:{1},等待时长:{2}".format(locator,start,wait_times))
        except Exception as e:
            self.logger.error("等待元素可见异常{0}".format(e))
            raise

    #等待元素存在
    def wait_elePrences(self, locator, by=MobileBy.ID,wait=30, requence=0.5):
        try:
            start = datetime.datetime.now()
            WebDriverWait(self.driver, wait, requence).until(EC.presence_of_element_located((by, locator)))
            end = datetime.datetime.now()
            wait_times = (end - start).seconds
            self.logger.info("等待元素存在:{0},起始时间:{1},等待时长:{2}".format(locator, start, wait_times))
        except Exception as e:
            self.logger.error("查看元素可见异常{0}".format(e))
            raise

    #查找元素
    def find_element(self, locator, by=MobileBy.ID):
        self.logger.info("开始查找元素:{0}={1}".format(by, locator))
        try:
            return self.driver.find_element(by, locator)
        except Exception as e:
            self.logger.error("元素查找不到{0}".format(e))
            raise


    #智能查找元素
    def find_element_wait_and_focus(self, locator, wait_ele, by=MobileBy.ID, wait=30,
                                    requence=0.5, index=None):
        # 查找元素
        self.logger.info("开始查找元素:{0}={1}".format(by, locator))
        # 等待元素
        if wait_ele == 'visibility':
            self.wait_eleVisible(locator, by, wait,requence)
        else:
            self.wait_elePrences(locator, by, wait,requence)

        try:
            return self.driver.find_element(by, locator)
        except Exception as e:
            self.logger.error("元素查找不到{0}".format(e))
            raise


    #查的多个元素
    def find_elements(self, locator, by=MobileBy.ID):
        self.logger.info("开始查找符合表达式的所有元素:{0}={1}".format(by, locator))
        try:
            return self.driver.find_elements(by, locator)
        except Exception as e:
            self.logger.error("元素查找不到{0}".format(e))
            raise



    #元素的点击操作。
    def click_element(self,locator,wait_ele='visibility',by=MobileBy.ID,wait=30, requence=0.5,index=None):
        ele = self.find_element_wait_and_focus(locator, wait_ele, by, wait,
                                               requence, index)
        try:
            self.logger.info("对元素{0}进行点击操作。".format(locator))
            ele.click()
        except Exception as e:
            self.logger.error("元素点击操作失败{0}".format(e))
            raise

    #元素的输入操作
    def input_text(self,value,locator,by=MobileBy.ID,wait=30,requence=0.5,wait_ele='visibility',index=None):
        ele = self.find_element_wait_and_focus(locator, wait_ele, by, wait,requence, index)
        try:
            self.logger.info("在元素:{0}={1}中输入内容:{2}".format(by, locator, value))
            ele.clear()
            ele.send_keys(value)
        except Exception as e:
            self.logger.error("元素输入操作失败{0}".format(e))
            raise

    #获取元素的属性值。
    def get_element_attribube(self,attr_name,locator,by=MobileBy.ID,wait=30,requence=0.5,
                   wait_ele='visibility',index=None):
        ele = self.find_element_wait_and_focus(locator, wait_ele, by, wait,requence, index)
        try:
            self.logger.info("获取元素{0}={1} 的属性值:{2}。".format(by, locator, attr_name))
            return ele.get_attribute(attr_name)
        except Exception as e:
            self.logger.error("获取元素属性失败{0}".format(e))
            raise

    #获取元素的文本内容
    def get_text(self,locator,by=MobileBy.ID,wait=30,requence=0.5,wait_ele='visibility',index=None):
        ele = self.find_element_wait_and_focus(locator, wait_ele, by, wait,requence, index)
        try:
            self.logger.info("获取元素{0}={1} 的文本内容。".format(by, locator))
            return ele.text
        except Exception as e:
            self.logger.error("获取元素文本内容失败{0}".format(e))
            raise

    #确定要操作的元素 - 查找多个和查找单个。确定元素操作对象。
    def _get_element(self,locator,by,index=None):
        if index is not None:
            # 在查找到多个元素的基础之上,随机选择其中的一个。
            import random
            eles = self.find_elements(locator, by)
            if index == -1 or index < 0:
                pos = random.randint(0, len(eles) - 1)
                return eles[pos]
            else:
                return eles[index]
        else:
            return self.find_element(locator, by)

import logging, time
import os,sys

# log_path是存放日志的路径
cur_path = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__)))))
log_path = os.path.join(os.path.dirname(cur_path), 'logs/autotest_app/api')

# 如果不存在这个logs文件夹,就自动创建一个
if not os.path.exists(log_path):os.makedirs(log_path)

class Log():
    def __init__(self):
        # 文件的命名

        self.logname = os.path.join(log_path, '%s.log' % ('api_'+ time.strftime('%Y_%m_%d')))
        self.logger = logging.getLogger()
        self.logger.setLevel(logging.DEBUG)
        # 日志输出格式
        self.formatter = logging.Formatter('[%(asctime)s] - %(filename)s] - %(levelname)s: %(message)s')

    def __console(self, level, message):
        # 创建一个FileHandler,用于写到本地
        fh = logging.FileHandler(self.logname, 'a', encoding='utf-8')
        fh.setLevel(logging.DEBUG)
        fh.setFormatter(self.formatter)
        self.logger.addHandler(fh)

        # 创建一个StreamHandler,用于输出到控制台
        ch = logging.StreamHandler()
        ch.setLevel(logging.DEBUG)
        ch.setFormatter(self.formatter)
        self.logger.addHandler(ch)

        # 创建一个StreamHandler,用于输出到stdout
        ch2 = logging.StreamHandler(sys.stdout)
        ch2.setLevel(logging.DEBUG)
        ch2.setFormatter(self.formatter)
        self.logger.addHandler(ch2)

        if level == 'info':
            self.logger.info(message)
        elif level == 'debug':
            self.logger.debug(message)
        elif level == 'warning':
            self.logger.warning(message)
        elif level == 'error':
            self.logger.error(message)
        # 这两行代码是为了避免日志输出重复问题
        self.logger.removeHandler(ch)
        self.logger.removeHandler(fh)
        self.logger.removeHandler(ch2)
        # 关闭打开的文件
        fh.close()

    def debug(self, message):
        self.__console('debug', message)

    def info(self, message):
        self.__console('info', message)

    def warning(self, message):
        self.__console('warning', message)

    def error(self, message):
        self.__console('error', message)

if __name__ == "__main__":
   log = Log()
   log.info("---测试开始----")
   log.info("操作步骤1,2,3")
   log.warning("----测试结束----")

3、运行第一个测试用例
pip install pytest

(1) 、创建test_suitest存放测试用例
(2)、创建page_obj 独立分离每个页面的操作
(3)、创建page_lct存放页面元素

image.png

login_lct.py

#用户名
user_name = 'xyz.nesting.intbee:id/phoneNumEt'
#密码
pwd = 'xyz.nesting.intbee:id/password'
#登录按钮
button = 'xyz.nesting.intbee:id/submitBtn'

login_page.py

from page_lct import login_lct
from common.basepage import BasePage
class LoginPage(BasePage):

    def login(self, username, password):
        # 输入用户名
        self.input_text(username, login_lct.user_name)
        # 输入密码
        self.input_text(password, login_lct.pwd)
        # 点击登录按钮
        self.click_element(login_lct.button)

-------

test_login.py

import pytest
import logging
from page_obj.login_page import LoginPage

class TestLogin:

    @pytest.mark.smoke
    def test_login_success(self, app_page):
        '''成功登录'''
        # 步骤
        LoginPage(app_page).login('xxxxxxx', 'xxxxxx')
        logging.info("开始断言")

conftest.py

import pytest, os
from selenium import webdriver
from appium import webdriver
import logging
cur_path = os.path.dirname(os.path.realpath(__file__))
@pytest.fixture()
def app_page():
    logging.info('----------------测试开始-----------------')
    desired_caps = {}
    desired_caps['platformName'] = 'Android'
    desired_caps['platformVersion'] = '8.1.0'
    desired_caps['deviceName'] = 'xxxxxx'
    desired_caps['appPackage'] = 'xxxx'
    desired_caps['appActivity'] = 'xxxxxx'
    desired_caps['autoGrantPermissions'] = True
    desired_caps['automationName'] = 'uiautomator2'

    driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', desired_caps)
    yield driver
    logging.info('----------------测试结束-----------------')
    driver.quit()

main.py

import pytest, time, os
cur_path = os.path.dirname(os.path.realpath(__file__))
now = time.strftime("%Y-%m-%d")
report_file = 'report/'+now+'_test_result.html'
pytest.main(['test_suites/test_login.py'])

运行main.py程序,成功执行测试用例

你可能感兴趣的:(app自动化测试框架(一、框架的搭建))