IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 开发测试 -> 我的第一份UI自动化测试框架 -> 正文阅读

[开发测试]我的第一份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:\Users\Mrlin\PycharmProjects\Cost_management_system\config\YuanGon.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:\Knowledge\img\whole_code.png', r'E:\Knowledge\img\code.png')
        code = self.getcode.get_code(r'E:\Knowledge\img\code.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:\Knowledge\config\Test_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:\Knowledge\config\Test_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自动化框架,里面还有很多可以优化的地方;

  开发测试 最新文章
pytest系列——allure之生成测试报告(Wind
某大厂软件测试岗一面笔试题+二面问答题面试
iperf 学习笔记
关于Python中使用selenium八大定位方法
【软件测试】为什么提升不了?8年测试总结再
软件测试复习
PHP笔记-Smarty模板引擎的使用
C++Test使用入门
【Java】单元测试
Net core 3.x 获取客户端地址
上一篇文章      下一篇文章      查看所有文章
加:2021-10-01 17:11:21  更:2021-10-01 17:12:04 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/18 0:42:18-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码