栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

我的第一份UI自动化测试框架

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

我的第一份UI自动化测试框架

我的第一份UI自动化测试框架 一、框架介绍:

1、本框架使用Python开发语言,结合selenium,unnitest单元测试框架,再采用PO模型进行封装,整个框架结构一共包含了十大模块,如下图所示:

1、base层:基础层,存放我们的基础定位元素的方法,一共八种常用的方法;
2、business层:业务层,存放我们业务功能处理;
3、case层:存放我们测试用例;
4、congfig层:存放元素的定位信息;
5、handle层:存放页面的操作信息;
6、img层:存放图片信息;
7、log层:存放日志信息;
8、page层:存放页面信息;
9、report层:存放测试报告信息;
10、until层:存放工具类信息;

二、框架搭建

1、本框架配置文件采用的是ini文件存储,所以第一步是在until层,创建读取ini文件:

    # 定义全局属性
    def __init__(self, file_name=None, node=None):
		# 定义默认文件读取
        if file_name is None:
            file_name = r'C:UsersMrlinPycharmProjectsCost_management_systemconfigYuanGon.ini'
		# 定义默认ini文件头读取
        if node is None:
            self.node = 'RegisterElement'
        else:
            self.node = node
            
        self.cf = self.getIni(file_name)

    # 读取ini文件
    def getIni(self, file_name):
        cf = configparser.ConfigParser()
        cf.read(file_name, encoding='UTF-8')
        return cf

    # 获取ini文件的数据值
    def getMessage(self, node, key):
        data = self.cf.get(node, key)
        return data

2、写好读取ini配置文件之后,开始进行第二步,在base层定义我们selenium操作页面元素的方法:

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

    def get_element(self, file_path, note, key):
        # 读取ini文件相关元素配置信息
        read_ini = Read_ini(file_path)
        data = read_ini.getMessage(note, key)
        # 规定配置文件定位信息写法,>左边为定位方法、右边为定位信息
        by = data.split('>')[0]
        value = data.split('>')[1]

    # 八大定位方式
        try:
            if by == 'id':
                return self.driver.find_element_by_id(value)
            elif by == 'name':
                return self.driver.find_element_by_name(value)
            elif by == 'className':
                return self.driver.find_element_by_class_name(value)
            elif by == 'xpath':
                return self.driver.find_element_by_xpath(value)
            elif by == 'link_text':
                return self.driver.find_element_link_text(value)
            elif by == 'partial_link_text':
                return self.driver.find_element_partial_link_text(value)
            elif by == 'css_selector':
                return self.driver.find_element_css_selector(value)
            else:
                return self.driver.find_element_tag_name(value)
        except:
            return None

3、两份文件编写完成后,就可以在开始第三步,再config层编写我们的定位元素配置信息了:

;登录页面相关定位信息
;[]内内容为node,=号左边为key,右边内容根据‘>’拆分

[LoginElement]
;选择账号登录
salecard_select = xpath>//span[text()='账号登录']
;用户名
salecard_login_Name = xpath>//input[@placeholder='账号']

;密码
salecard_login_Password = xpath>//input[@placeholder='密码']

;验证码
salecard_code = xpath>//input[@placeholder='请输入验证码']

;验证码图片
salecard_code_img = xpath>//img[@alt='验证码']

;登录按钮
salecard_login_Button = xpath>//span[text()='登录']

[URL]
;系统网址
login_url = http://test-passport.gzjunbo.net/login/index.html?callback=http://test-card-admin.liulianglf.cn/index.html

4、配置信息编写完成之后,便可以开始第四步,在page层编写业务所需的页面信息:

    def __init__(self, driver):
    	# base层读取ini文件实例化
        self.login_find_element = MatchElementPosition(driver)
        # 登录元素信息配置文件存放路径
        self.file_path = os.path.abspath(os.path.dirname(os.getcwd())) + r'config' + r'salecard_login.ini'

    # 获取登录方式选择框定位信息
    def get_login_select(self):
        return self.login_find_element.get_element(self.file_path, 'LoginElement', 'salecard_select')

    # 获取用户名输入框定位信息
    def get_login_name(self):
        return self.login_find_element.get_element(self.file_path, 'LoginElement', 'salecard_login_Name')

    # 获取密码输入框定位信息
    def get_login_password(self):
        return self.login_find_element.get_element(self.file_path, 'LoginElement', 'salecard_login_Password')

    # 获取验证码定位信息
    def get_login_code(self):
        return self.login_find_element.get_element(self.file_path, 'LoginElement', 'salecard_code')

    # 获取验证码图片定位信息
    def get_login_code_img(self):
        return self.login_find_element.get_element(self.file_path, 'LoginElement', 'salecard_code_img')

    # 获取登录按钮定位信息
    def get_login_button(self):
        return self.login_find_element.get_element(self.file_path, 'LoginElement', 'salecard_login_Button')

5、编写完成页面信息之后,便可以开始第五步,再handle层编写页面操作信息了:

    def __init__(self, driver):
    	# page层实例化
        self.salecard_login_page = SalecradLoginPage(driver)

    # 选择登录方式
    def click_select(self):
        return self.salecard_login_page.get_login_select().click()

    # 输入用户名
    def send_name(self, username):
        return self.salecard_login_page.get_login_name().send_keys(username)

    # 输入密码
    def send_password(self, password):
        return self.salecard_login_page.get_login_password().send_keys(password)

    # 输入验证码
    def send_code(self, code):
        return self.salecard_login_page.get_login_code().send_keys(code)

    # 点击登录按钮
    def click_button(self):
        return self.salecard_login_page.get_login_button().click()

6、编写完成页面操作的脚本之后,可以开始开始第六步,在business层编写业务处理逻辑:

    def __init__(self, driver):

        self.driver = driver
        self.login_handle = LoginHandle(driver)
        self.getcode = GetCode(driver)

    # 登录公共类
    def user_operate(self, name, password):
        # 选择登录方式
        self.login_handle.click_select()
        time.sleep(1)
        # 输入用户名
        self.login_handle.send_name(name)
        time.sleep(1)
        # 输入密码
        self.login_handle.send_password(password)
        time.sleep(1)
        # 获取验证码
        self.getcode.get_img(r'E:Knowledgeimgwhole_code.png', r'E:Knowledgeimgcode.png')
        code = self.getcode.get_code(r'E:Knowledgeimgcode.png')
        # 输入验证码
        self.login_handle.send_code(code)
        time.sleep(1)

    def success_assert(self):
    	# 获取页面标题,用于断言
        text = self.driver.title
        # 成功断言
        if text == '酬金业务-运营管理后台':
            return True
        elif text == '登录中心':
            return True
        else:
            return False

    # 登录业务操作
    def user_normal_operate(self, name, password):
        # 输入用户信息
        self.user_operate(name, password)
        time.sleep(1)
        # 点击登录按钮
        self.login_handle.click_button()
        time.sleep(5)
        # 判断是否登录成功
        return self.success_assert()

7、到这已经完成所有的基本操作,接下来便是在case层编写我们的测试用例,因为我们在case层使用了log日志记录、读取excel进行参数化、以及使用HTMLtestrunner进行报告输出,所以呢需要在until层把这些工具类先编写好,方便调用;
<1>创建日志文件,读取log日志:

    def __init__(self):
		
        self.logger = logging.getLogger()
        self.logger.setLevel(logging.INFO)

        # 文件名字
        base_dir = os.path.abspath(os.path.join(os.path.dirname("__file__"), os.path.pardir))  # 获取根目录
        log_file = datetime.datetime.now().strftime('%Y-%m-%d') + '-' + 'log.ini'  # 获取带时间文件名
        log_name = base_dir + "/log/" + log_file  # 拼接日志存放路径

        # 文件输出日志
        self.file_handle = logging.FileHandler(log_name, 'a', encoding='utf-8')
        formatter = logging.Formatter('%(asctime)s %(filename)s ---> %(funcName)s %(levelno)s: %(levelname)s ---> %(message)s')
        self.file_handle.setFormatter(formatter)
        self.logger.addHandler(self.file_handle)

    def get_log(self):
        return self.logger

    def close_log(self):
        self.logger.removeHandler(self.file_handle)
        self.file_handle.close()

<2>创建excel文件,读取excel文件:

    def __init__(self, excel_path=None, index=None):

        # Excel表存放路径;
        if excel_path is None:
            excel_path = r'E:KnowledgeconfigTest_case_parameters.xls'
        else:
            self.excel_path = excel_path

        # 数据表位置确定;
        if index is None:
            index = 0
        else:
            self.index = index

        # 打开Excel表格;
        self.data = xlrd.open_workbook(excel_path)
        self.table = self.data.sheets()[index]  # 确定数据表位置;

    # 获取表格数据行数
    def get_row(self):
        rows = self.table.nrows  # 获取表格的行;
        if rows >= 1:
            return rows
        return None

    # 获取某个单元格内容
    def get_cell(self, row, column):
        rows = self.get_row()
        if rows >= row:
            title = self.table.cell(row, column).value
            return title
        return None

    # 获取excel表某列数据
    def get_column_data(self, column):
        result = []
        rows = self.get_row()
        if rows is not None:
            for i in range(1, rows):
                value = self.table.cell(i, column).value
                result.append((value))
            return result
        return None

    # 获取excel表格全部数据
    def get_excel_data(self):
        result = []
        rows = self.get_row()
        if rows is not None:
            for i in range(1, rows):
                value = self.table.row_values(i)
                result.append((value))
            return result
        return None

    # 写入数据
    def write_data(self, row, column, value):
        # 复制旧数据
        excel_value = self.data
        write_data = copy(excel_value)
        # 写入新数据
        if row >= 1 and column >= 0:
            write_data.get_sheet(0).write(row, column, value)
            write_data.save(r'E:KnowledgeconfigTest_case_parameters.xls')
        return None

<3>做完这两步,接下来可以直接在case层编写我们的测试用例文件:

@ddt.ddt
class Knowledge(unittest.TestCase):

    @classmethod
    def setUpClass(cls):
        cls.log = RecordLog()
        cls.logger = cls.log.get_log()

    def setUp(self):
        # 打开网页
        self.RP = Premise()
        self.RP.get_url()

    # 正常登录测试
    # unnitest框架采用ddt进行参数化操作
    @ddt.data(*data)
    def test_normal_login(self, data):
        # 输入数据
        name, password = data
        # 向business层输入数据
        case = self.RP.LB.user_normal_operate(name, password)
        # 根据business层断言返回的结果判断用例是否执行成功
        self.assertTrue(case)
        # 输出日志信息
        self.logger.info('test is chrome')

    def tearDown(self):
        # 关闭网页
        self.RP.driver.quit()

    @classmethod
    def tearDownClass(cls):
        cls.log.close_log()

8、最后一步便是,执行我们的case,报告采用HTMLtestrunner:

# 待执行用例的目录
def allcase():
    case_dir = os.path.abspath(os.path.dirname(os.getcwd())) + r'case'
    # case_path=os.path.join(os.getcwd(),"case")
    testcase = unittest.TestSuite()
    discover = unittest.defaultTestLoader.discover(case_dir,
                                                   pattern='test_*.py',
                                                   top_level_dir=None)
    # discover方法筛选出来的用例,循环添加到测试套件中
    # print(discover)
    for test_suite in discover:
        for test_case in test_suite:
            # 添加用例到testcase
            print(test_case)
            testcase.addTest(test_case)
    return testcase


if __name__ == "__main__":
    # 生成测试报告格式;
    # 获取当前时间
    now_time = time.strftime('%Y-%m-%d %H_%M_%S')
    # 测试报告生成存放路径;
    file_path = os.path.abspath(os.path.dirname(os.getcwd())) + r'report' + r'Automation_Report_'+ now_time + '.html'
    f = open(file_path, 'wb')  # 以读写的方式打开文件;
    runner = HTMLTestRunner.HTMLTestRunner(stream=f, title='专业知识点掌握情况反馈系统自动化测试报告', description='专业知识点掌握情况反馈系统自动化测试报告', verbosity=2)
    runner.run(allcase())
    f.close()
结语

最后到这框架介绍就结束了,这是一个简单的UI自动化框架,里面还有很多可以优化的地方;

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/280415.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号