Selenium3与Python3实战 Web自动化测试框架(五)

 po模型 + 数据驱动 ,完整代码

1、setting.py:

import os



base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # 项目首路径
codeerror_path = os.path.join(base_dir,'Image','codeerror.png')  # 验证码错误图片路径
code_path = os.path.join(base_dir,'Image','code.png')  # 验证码图片保存路径
config_ini_dir = os.path.join(base_dir,'setting_conf','localElement.ini')  # localElement.ini 配置文件路径
report_path = os.path.join(base_dir,'report','first_case.html')  # 测试报告路径
excel_default_path = os.path.join(base_dir,'ex_data','casedata.xls')  # excel表默认路径
excel_keyword_path = os.path.join(base_dir,'ex_data','keyword.xls')  # excel表默认路径

setting.py

2、config.py:配置文件,主要用于配送web定位元素

[RegisterElement]
user_email=id>register_email
user_email_error=id>register_email-error
user_name=id>register_nickname
user_name_error=id>register_nickname-error
password=id>register_password
password_error=id>register_password-error
code_image=id>getcode_num
code_text=id>captcha_code
code_text_error=id>captcha_code-error
register_button=id>register-btn

3、read.ini:读取config.py配置文件信息,获取value

from setting_conf.setting import config_ini_dir
import configparser

class Read_Ini(object): # 初始化
    def __init__(self,node = None):
        if node:
            self.node = node
        else:
            self.node = 'RegisterElement'  # 配置文件中的某个节点
        self.cf = self.load_ini()

    def load_ini(self):  # 加载文件
        cf = configparser.ConfigParser()  # 使用 configparser模块读取配置文件信息
        cf.read(config_ini_dir)  # 配置文件所在路径
        return cf

    def get_value(self,key): # 获取配置文件中key的value值
        data = self.cf.get(self.node,key)
        return data

read.ini

  

4、PO模型实现,将数据、业务、操作等分类开

4.1、find_element.py:查找目标元素,定位目标位置

from util.read_ini import Read_Ini
class FindElement(object):
    """获取元素所在位置"""
    def __init__(self,driver):
        self.driver = driver
    def get_element(self,key):
        read_ini = Read_Ini()
        data = read_ini.get_value(key)
        by,value = data.split('>')

        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)
            else:
                return self.driver.find_element_by_css(value)
        except Exception as e:
            # print("find_element错误信息:",e)
            return None

find_element.py

4.2、register_page.py :操作find_element.py,获取各目标元素位置

from base.find_element import FindElement
class RegisterPage(object):
    """获取元素所在位置"""
    def __init__(self,driver):
        self.fd = FindElement(driver)
    
    #获取邮箱元素
    def get_email_element(self):
        return self.fd.get_element("user_email")

    #获取用户名元素
    def get_username_element(self):
        return self.fd.get_element("user_name")
    #获取密码元素
    def get_password_element(self):
        return self.fd.get_element("password")
    #获取验证码元素
    def get_code_element(self):
        return self.fd.get_element("code_text")
    #获取注册按钮元素
    def get_button_element(self):
        return self.fd.get_element("register_button")
    #获取邮箱错误元素
    def get_email_error_element(self):
        return self.fd.get_element("user_email_error")
    #获取用户名错误元素
    def get_name_error_element(self):
        return self.fd.get_element("user_name_error")
    #获取密码错误元素
    def get_password_error_element(self):
        return self.fd.get_element("password_error")
    #获取验证码错误元素
    def get_code_error_element(self):
        return self.fd.get_element("code_text_errorr")

register_page.py

4.3、register_handle.py :操作register_page.py ,获取目标位置后,输入需求数据

 4.3.1、get_code_value.py:解析验证码图片,获取验证码内容

from PIL import Image
from setting_conf.ShowapiRequest import ShowapiRequest
import time


class GetCode:
    """获取验证码图片,解析验证码图片并返回验证码值"""
    def __init__(self, driver):
        self.driver = driver

    def get_code_image(self, file_name):
        self.driver.save_screenshot(file_name)
        code_element = self.driver.find_element_by_id("getcode_num")
        left = code_element.location['x']
        top = code_element.location['y']
        right = code_element.size['width'] + left
        height = code_element.size['height'] + top
        im = Image.open(file_name)
        img = im.crop((left, top, right, height))
        img.save(file_name)
        # time.sleep(1)

    # 解析图片获取验证码
    def code_online(self, file_name):
        self.get_code_image(file_name)
        r = ShowapiRequest("http://route.showapi.com/184-4", "62626", "d61950be50dc4dbd9969f741b8e730f5")
        r.addBodyPara("typeId", "35")
        r.addBodyPara("convert_to_jpg", "0")
        r.addFilePara("image", file_name)  # 文件上传时设置
        res = r.post()
        # print("test:",res.text)
        # time.sleep(1)
        text = res.json()['showapi_res_body']
        # print(text)
        try:
            code = text['Result']
            return code
        except Exception as e:
            print('code_error:',e)
            return None

get_code_value.py
from page.register_page import RegisterPage
from util.get_code_value import GetCode

class RegisterHandle(object):
    """打开页面后自动输入相应信息"""
    def __init__(self,driver):
        self.driver = driver
        self.register_p = RegisterPage(self.driver)

    #输入邮箱
    def send_user_email(self,email):
        # self.loger.info("输入的邮箱值是:"+email)
        self.register_p.get_email_element().send_keys(email)
    
    #输入用户名
    def send_user_name(self,username):
        # self.loger.info("输入的用户名是:"+username)
        self.register_p.get_username_element().send_keys(username)

    #输入密码
    def send_user_password(self,password):
        # self.loger.info("输入的密码是:"+password)
        self.register_p.get_password_element().send_keys(password)
    
    #输入验证码
    def send_user_code(self,file_name):
        get_code_text = GetCode(self.driver)
        code = get_code_text.code_online(file_name)
        self.register_p.get_code_element().send_keys(code)
    
    #获取文字信息
    def get_user_text(self,info,user_info):
        try:# 容错处理
            if info == 'user_email_error':
                text = self.register_p.get_email_error_element().text  # 获取邮箱错误信息
            elif info == 'user_name_error':
                text = self.register_p.get_name_error_element().text  # 获取用户名错误信息
            elif info == 'password_error':
                text = self.register_p.get_password_error_element().text  # 获取用户密码错误信息
            else:
                text = self.register_p.get_code_error_element().text  # 获取验证码错误信息
        except:
            text = None     
        return text
    #点击注册按钮
    def click_register_button(self):
        self.register_p.get_button_element().click()
    
    #获取注册按钮文字
    def get_register_btn_text(self):
        """如获取不到信息,表明页面已成功跳转"""
        return self.register_p.get_button_element().text

register_handle.py

4.4、register_business.py:

from handle.register_handle import RegisterHandle
class RegisterBusiness:
    """测试注册页面form表单功能情况"""
    def __init__(self,driver):
        self.register_h = RegisterHandle(driver)

    def user_base(self,email,name,password,file_name):
        self.register_h.send_user_email(email)
        self.register_h.send_user_name(name)
        self.register_h.send_user_password(password)
        self.register_h.send_user_code(file_name)
        self.register_h.click_register_button()
    
    def register_succes(self):
        if self.register_h.get_register_btn_text() == None:
            # 注册成功
            return True
        else:
            return False

    # 邮箱错误
    def login_email_error(self,email,name,password,file_name):
        self.user_base(email,name,password,file_name)   
        if self.register_h.get_user_text('user_email_error',"请输入有效的电子邮件地址") == None: # 没找到错误信息,说明输入格式正确,不能起到测试效果。
            #print("无错误,邮箱检验不成功")
            return True
        else:
            return False

    # 数据驱动,只执行此条代码
    # 邮箱、用户名、密码、验证码、错误信息定位元素、错误提示信息
    def register_function(self,email,username,password,file_name,assertCode,assertText):
        self.user_base(email,username,password,file_name)
        if self.register_h.get_user_text(assertCode,assertText) == None:
            return True
        else:
            return False
    # 用户名错误
    def login_name_error(self,email,name,password,file_name):
        self.user_base(email,name,password,file_name)
        if self.register_h.get_user_text('user_name_error',"字符长度必须大于等于4,一个中文字算2个字符") == None:
            #print("用户名检验不成功")
            return True
        else:
            return False
    
    # 密码错误
    def login_password_error(self,email,name,password,file_name):
        self.user_base(email,name,password,file_name)
        if self.register_h.get_user_text('password_error',"最少需要输入 5 个字符") == None:
            #print("密码检验不成功")
            return True
        else:
            return False

    # 验证码错误
    def login_code_error(self,email,name,password,file_name):
        self.user_base(email,name,password,file_name)
        if self.register_h.get_user_text('code_text_error',"验证码错误") == None:
            #print("验证码检验不成功")
            return True
        else:
            return False

register_business.py

4.5、first_ddt_case.py:数据驱动

import ddt
import unittest
import os
# import sys
from selenium import webdriver
from setting_conf import setting
from business.register_business import RegisterBusiness
from util.excel_operation import Excel_Opertion
from util.HTMLTestRunner import HTMLTestRunner

# sys.path.append(setting_conf.base_dir)
ex_opr = Excel_Opertion()  # 实例化
ex_data = ex_opr.get_data()  # 获取excel表中每行数据

@ddt.ddt
class FirstDdtCase(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        cls.driver = webdriver.Chrome()
        cls.driver.get('http://www.5itest.cn/register')
        cls.driver.maximize_window()
        cls.file_name = setting.code_path
        cls.login = RegisterBusiness(cls.driver)

    def setUp(self):
        self.driver.refresh()
        # self.login = RegisterBusiness(self.driver)

    def tearDown(self):
        for method_name, error in self._outcome.errors:  # case如果执行失败,错误会保存到_outcome.errors 中
            if error:
                # case_name = self._testMethodName  # case名,即定义好的方法名
                report_error_name = self.assertCode + '.png'
                report_error_path = os.path.join(setting.base_dir, 'report', report_error_name)
                self.driver.save_screenshot(report_error_path)

    @classmethod
    def tearDownClass(cls):
        cls.driver.close()

    @ddt.data(*ex_data)
    def test_register_case(self,ex_data):   # ex_data:[[],[],..] 列表套列表
        """数据驱动模式,会按ex_data列表数据,一行一行循环执行,直至列表数据执行完毕"""
        email, username, password, self.assertCode, assertText = ex_data  # 将ex_data每个子列表的数据按顺序赋值。验证码需要提供路径,单独给
        # 邮箱、用户名、密码、验证码、错误信息定位元素、错误提示信息
        register_error = self.login.register_function(email, username, password, self.file_name,self.assertCode, assertText)
        self.assertFalse(register_error,"测试失败:{}".format(self.assertCode))


if __name__ == '__main__':
    suite = unittest.TestLoader().loadTestsFromTestCase(FirstDdtCase)
    with open(setting.report_path, 'wb') as f:
        runner = HTMLTestRunner(stream=f,title="This is the first ddt_case report1",description="这个是我们第一次测试报告 --数据驱动",verbosity=2)
        runner.run(suite)

first_ddt_case.py

附例:关键字驱动

from util.excel_cell_value import Get_Cells_Value
from keyword_model.actionMethod import ActionMethod
from setting_conf import setting

class KeywordCase(object):
    def __init__(self):
        self.action_metood = ActionMethod()
        excel_default_path = setting.excel_keyword_path
        self.get_cell_value = Get_Cells_Value(excel_default_path)  # 实例化


    def run_main(self):
        get_lines = self.get_cell_value.get_lines  # 获取行数
        if get_lines:
            for i in  range(1,get_lines):
                is_run = self.get_cell_value.get_is_run(i)
                if is_run == 'yes':
                    carry_method = self.get_cell_value.get_action_method(i)  # 获取执行方法
                    send_value = self.get_cell_value.get_send_value(i)  # 获取输入的数据
                    oper_element = self.get_cell_value.get_oper_element(i)  # 获取操作的元素
                    expect_result_mothod = self.get_cell_value.get_expect_result(i)  # 获取预期结果
                    real_result_value = self.get_cell_value.get_real_result(i)  # 获取表中实际要求结果值
                    self.run_method(carry_method,send_value,oper_element)  # 执行excel表中对应指定的方法

                    if expect_result_mothod != '': # 预期结果有值
                        result_value = self.get_real_result_value(real_result_value)
                        if result_value[0] == 'text':  # url访问,获取网页title
                            result = self.run_method(expect_result_mothod) # expect_result_mothod:driver.get_title()方法
                            if result_value[1] in result:  # 判断实际要求结果值是否存在于实际测试结果中
                                self.get_cell_value.write_cell_value(i,'pass') # 在excel表中对应单元格写入数据
                            else:
                                self.get_cell_value.write_cell_value(i,'fail')
                        elif result_value[0] == 'element': # 获取元素,判断输入格式等
                            result = self.run_method(expect_result_mothod,result_value[1]) # expect_result_mothod:get_element()方法,result_value[1]:参数
                            if result: # 有值,表示找到对应(如:password_error)错误信息,表示格式测试通过(目的就是测试输入错误格式是否会被检查出来)
                                self.get_cell_value.write_cell_value(i,'pass')
                            else:
                                self.get_cell_value.write_cell_value(i,'fail')
                        else:
                            print("Error:实际要求结果:{},测试无效".format(real_result_value))
                    else:
                        print('第i条case:预期结果为空')


    def run_method(self,method,send_value = '',handle_value = ''):
        main_method = getattr(self.action_metood,method)
        if send_value == '' and handle_value == '':
            result = main_method()  # 关闭浏览器、等待等
        elif send_value == '' and handle_value != '':
            result = main_method(handle_value)  # 打开浏览器、访问url等
        elif send_value != '' and handle_value == '':
            result = main_method(send_value)  # 暂时没用到
        else:
            result = main_method(send_value,handle_value) # 输入用户信息
        return result

    # 对实际要求结果值进行切分(实际要求结果形似:text=注册)
    def get_real_result_value(self, data):
        return data.split('=')





if __name__ == "__main__":
    keyword_case = KeywordCase()
    keyword_case.run_main()

keyword_case.py

猜你喜欢

转载自www.cnblogs.com/fujunjie/p/13160692.html
今日推荐