【大学生自动化测试基础selenium】pageObjece

news2024/11/18 15:27:52

 

目录

目录 

base_page层

 common层

read_data.py

send_email.py

test_log.py

page层

page_ECShop_Login.py

testcase层

conftest.py

test_login.py

venv层

pytest.ini

run.tests.py

 requirements.txt


目录 

base_page层

# basepage 基础页面层(基类)
# 封装关于selenium一系列原生操作 元素定位 最大化 跳转 输入值 点击 等等


from selenium import webdriver
from selenium.webdriver.support.select import Select
from selenium.webdriver.support.wait import WebDriverWait
from common.test_log import Logger

log = Logger().get_logger()


class BasePage:  # 定义基类
    # 类的初始化
    def __init__(self):
        # try...except 代码异常处理方式
        try:
            self.driver = webdriver.Chrome()
            log.info("正在打开浏览器")
        # 负责抛出异常
        except Exception:
            log.error("无法打开浏览器")

    # 封装访问被测页面
    def base_open(self, url):
        if url != "":
            self.driver.get(url)
            self.driver.maximize_window()
            log.info("正常成功访问被测页面")
        else:
            log.error("无法打开被测页面,被测页面为空!")

    # 封装元素定位
    # 隐式等待全局  显示等待单个元素(进阶!)
    def base_element(self, loc):  # 形参
        return WebDriverWait(self.driver, timeout=10, poll_frequency=0.5).until(lambda x: x.find_element(*loc))  # 解包

    # 封装跳转frame
    def base_frame(self, loc):
        # 元素定位frame
        f1 = self.base_element(loc)
        self.driver.switch_to.frame(f1)

    # 封装输入值
    def base_send(self, loc, content):
        e = self.base_element(loc)
        e.clear()
        e.send_keys(content)

    # 封装点击
    def base_click(self, loc):
        self.base_element(loc).click()

    # 封装获取文本
    def base_text(self, loc):
        return self.base_element(loc).text

    # 封装跳出frame
    def base_default(self):
        self.driver.switch_to.default_content()

    # 封装关闭浏览器
    def base_quit(self):
        self.driver.quit()

    # 封装获取页面标题
    def base_title(self):
        return self.driver.title

    # 封装浏览器刷新
    def base_refresh(self):
        self.driver.refresh()

    # 封装下拉框
    def base_select(self, loc, content):
        s1 = Select(self.base_element(loc))
        s1.select_by_visible_text(content)

    # 封装弹窗
    def base_alert(self):
        alert = self.driver.switch_to.alert
        text = alert.text
        print("\n------" + text + "------\n")
        alert.accept()
        return text

 common层

read_data.py

import csv
from itertools import islice
import openpyxl


class ReadData:
    # 封装读取txt文件的方法
    def txt_read(self,path):
        # 打开文件(相对路径)
        with open(path, "r", encoding="utf-8") as f:
            data = f.readlines()   # 读取所有行数据 89页
        # 新建空列表 用来存储读取到的数据
        list1 = []
        # for循环遍历所有行数据
        for l in data:    # 将每一行数据得到,并暂存给临时变量l
            # 切片将每行数据最后的转置符号\n去掉,
            list2 = l[:-1].split(":")
            list1.append(list2)
        return list1

    # 封装读取csv文件的方法
    def csv_read(self, path):
        # 导入csv, reader()读取
        data = csv.reader(open(path, "r", encoding="gbk"))
        # 新建空列表
        list1 = []
        # for循环遍历读取的文件 islice()第1个参数需要遍历的文件数据,第2个参数开始遍历的位置,第3个参数表示遍历结束的位置
        for l in islice(data, 1, None):   # 每一行数据遍历到,并暂存给临时变量l
            list1.append(l)
        return list1

    # 封装读取xlsx文件的方法   XML 92   JSON 94
    def xlsx_read(self, path):
        # openpyxl  xlrd  第三方模块读取excel表格数据  下载安装 pip install openpyxl
        # 加载excel文件
        wb = openpyxl.load_workbook(path)
        # 获取sheet对象
        sheet = wb["Sheet1"]
        # 新建空列表
        list1 = []
        # 最大行sheet.max_row   最大列sheet.max_column
        # for循环遍历
        # 遍历行
        for r in range(2, sheet.max_row + 1):     # 2-5   range(1,10) 1-9   range(1,11) 1-10
            # 临时空列表
            temp_list = []
            # 遍历列
            for c in range(1, sheet.max_column + 1):   # 1-5
                # cell().value 获取每个单元格的值   cell(2,3)
                v1 = sheet.cell(r, c).value
                temp_list.append(v1)
            list1.append(temp_list)
        return list1


if __name__ == "__main__":   # 防止其他模块调用该模块的类与函数时的影响
    # 类class是一种概念模型,没有实际对象!!需要使用类!必须为类创建实例化对象!对象名=类名()
    r = ReadData()

send_email.py

import zmail


# ============HTML============
# 读取HTML文件内容
# 发送邮件功能封装
class SendEmail:
    def send_html(self, path, sub):
        with open(path, "r", encoding='utf-8') as file:
            msg = file.read()
        # 邮件内容
        msg_content = {
            'subject': '{}测试报告'.format(sub),  # 主题
            'content_html': msg,   # 正文
            'attachments': path  # 附件
        }
        # 收件人(如果有多个收件人,以列表的方式保存)
        rec = ['294885949@qq.com']
        # 发件人
        sender = {
            'username': '294885949@qq.com',
            'pwd': 'nubwqtjooeogbigb'
        }
        # 发送邮件
        # 登录
        server = zmail.server(sender['username'], sender['pwd'])
        # 把邮件发送给收件人
        server.send_mail(rec, msg_content)




test_log.py

# 日志需要使用loggin模块
import logging

# logging.debug("这是一条普通信息!!!")

"""
    1. 创建日志器
    2. 创建处理器(将日志信息输出到指定位置)
    3. 创建格式器(将处理器所输出的信息格式化)
    4. 为处理器设置格式
    5.将处理器添加到日志器
    6. 返回日志器
"""


# 定义日志类
class Logger:
    def get_logger(self):
        # 创建日志器
        logger = logging.getLogger("MyLogger")
        # 为日志器设置默认等级,记录什么等级以上的信息
        logger.setLevel(logging.DEBUG)

        # 创建处理器,将日志信息输出到控制台
        sh = logging.StreamHandler()
        # 设置需要在控制台显示什么等级以上的信息
        sh.setLevel(logging.WARNING) # 只会在控制台输出警告级别以上的信息

        # 创建处理器,将日志信息写入到文件
        fh = logging.FileHandler("../report/my_log/test_log.log", encoding="utf-8")
        # 设置等级
        fh.setLevel(logging.INFO)

        # 创建格式器  2020-01-01 0:00:00,000 INFO [root] [Test_Case.py (setUp:5)] - [测试详细信息]:登录测试开始执行初始化操作
        f1 = logging.Formatter("%(asctime)s %(levelname)s [%(name)s] %(filename)s (%(funcName)s:%(lineno)d)-%(message)s")

        # 给处理器设置输出的格式
        sh.setFormatter(f1)
        fh.setFormatter(f1)

        # 将处理器添加到日志器
        logger.addHandler(sh)
        logger.addHandler(fh)

        return logger

page层

page_ECShop_Login.py

from base.base_page import BasePage
from time import sleep
from selenium.webdriver.common.by import By


class PageLogin(BasePage):
    """用户登录"""
    """ 页面元素 """
    please_login = (By.LINK_TEXT, '请登录')  # 请登录按钮
    username = (By.CSS_SELECTOR, '[name="username"]')  # 用户名
    password = (By.CSS_SELECTOR, '[name="password"]')  # 密码
    submit = (By.CSS_SELECTOR, '[name="submit"]')  # 提交
    jump = (By.XPATH, '/html/body/div[5]/div/div/div/div/p[1]')  # 跳转通知
    out = (By.LINK_TEXT, '退出')

    admin_submit = (By.CSS_SELECTOR, '[type="submit"]')
    frame1 = (By.CSS_SELECTOR, '#menu-frame')
    frame2 = (By.CSS_SELECTOR, '#main-frame')
    admin_center = (By.PARTIAL_LINK_TEXT, 'ECSHOP 管理中心')
    admin = (By.LINK_TEXT, 'admin')
    info = (By.XPATH, '/html/body/div[1]/div/table/tbody/tr[1]/td[2]')

    vip_manage = (By.CSS_SELECTOR, '[data-key="03_users_list"]')  # 会员管理
    order_manage = (By.CSS_SELECTOR,'[data-key="02_order_list"]')  # 订单管理
    system_manage = (By.CSS_SELECTOR, '[data-key="01_shop_config"]')  # 系统设置
    vip_sign = (By.LINK_TEXT, '会员注册项设置')  # 会员注册
    add_vip = (By.LINK_TEXT, "添加会员")
    add_vip_submit = (By.CSS_SELECTOR, '[type="submit"]')  # 确定添加会员
    email = (By.CSS_SELECTOR, '[name="email"]')
    confirm_password = (By.CSS_SELECTOR, '[name="confirm_password"]')  # 确认密码

    edit=(By.LINK_TEXT, '编辑')
    view=(By.LINK_TEXT, '查看')
    ok=(By.CSS_SELECTOR, '[value="确认"]')
    payment=(By.CSS_SELECTOR, '[value="付款"]')
    action_note=(By.CSS_SELECTOR, '[name="action_note"]')
    send_form =(By.CSS_SELECTOR, '[value="生成发货单"]')
    send_ok=(By.CSS_SELECTOR, '[value="确认生成发货单"]')
    send_good=(By.CSS_SELECTOR, '[value="去发货"]')
    send=(By.CSS_SELECTOR, '[value="发货"]')
    is_no_send=(By.XPATH, '//*[@id="listDiv"]/table[1]/tbody/tr[3]/td[7]')


    # true_or_false = (By.XPATH, '//*[@id="list-table"]/tbody/tr[5]/td[4]/img')

    # length = len(driver.find_elements(By.XPATH, '//*[@id="listDiv"]/table/tbody/tr'))
    # 点击请登录按钮
    def page_please_login(self):
        self.base_click(PageLogin.please_login)

    # 输入用户名
    def page_username(self, username):
        self.base_send(PageLogin.username, username)

    # 输入密码
    def page_password(self, password):
        self.base_send(PageLogin.password, password)

    # 输入确认密码
    def page_confirm_password(self, confirm_password):
        self.base_send(PageLogin.confirm_password, confirm_password)

    # 输入邮箱
    def page_email(self, email):
        self.base_send(PageLogin.email, email)

    # 点击提交
    def page_submit(self, submit):
        self.base_click(submit)

    # 获取跳转也红字文本
    def page_jump(self):
        return self.base_text(PageLogin.jump)

    # 点击退出
    def page_out(self):
        self.base_click(PageLogin.out)

    # 获取会员人数
    def vip_num(self):
        return len(self.driver.find_elements(By.XPATH, '//*[@id="listDiv"]/table/tbody/tr'))

    # 管理员页面 frame 跳转
    def page_admin_frame(self, manage):
        self.base_frame(PageLogin.frame1)
        sleep(1)
        self.base_click(manage)
        sleep(1)
        self.base_default()
        sleep(1)
        self.base_frame(PageLogin.frame2)

    # 点击添加会员
    def page_add_vip(self, username, password, confirm_password, email):
        self.page_admin_frame(PageLogin.vip_manage)
        self.base_click(PageLogin.add_vip)
        self.page_username(username)
        self.page_email(email)
        self.page_password(password)
        self.page_confirm_password(confirm_password)
        self.page_submit(PageLogin.admin_submit)
        return self.base_text(PageLogin.info)

    # 修改会员信息
    def page_change(self,password, confirm_password, email):
        self.page_admin_frame(PageLogin.vip_manage)
        self.base_click(PageLogin.edit)
        self.page_email(email)
        self.page_password(password)
        self.page_confirm_password(confirm_password)
        self.page_submit(PageLogin.admin_submit)
        return self.base_text(PageLogin.info)

    def page_delete_vip(self):
        self.page_admin_frame(PageLogin.vip_manage)
        length = self.vip_num()
        i = 3
        while i <= length-3:
            self.driver.find_element(By.XPATH, f'//*[@id="listDiv"]/table/tbody/tr[{i}]/td[1]/input').click()
            i = i+1
        self.driver.find_element(By.CSS_SELECTOR, "#btnSubmit").click()
        return self.base_alert()

    # 系统设置手机号验证关闭
    def page_sys_manage(self):
        self.base_frame(PageLogin.frame1)
        self.base_click(PageLogin.system_manage)
        self.base_click(PageLogin.vip_sign)
        self.base_default()
        self.base_frame(PageLogin.frame2)

        src = self.driver.find_element(By.XPATH, '//*[@id="list-table"]/tbody/tr[5]/td[4]/img').get_attribute("src")
        if src == 'http://127.0.0.1/ecshop/admin/images/yes.svg':
            self.driver.find_element(By.XPATH, '//*[@id="list-table"]/tbody/tr[5]/td[4]/img').click()
        return src

    def page_send(self,action_note):
        self.page_admin_frame(PageLogin.order_manage)
        self.base_click(PageLogin.view)
        self.base_click(PageLogin.ok)
        # self.base_text(PageLogin.info)
        self.base_click(PageLogin.payment)
        self.base_send(PageLogin.action_note,action_note)
        self.base_click(PageLogin.submit)
        self.base_click(PageLogin.send_form)
        self.base_click(PageLogin.send_ok)
        self.base_click(PageLogin.send_good)
        self.base_click(PageLogin.view)
        self.base_click(PageLogin.send)
        return self.base_text(PageLogin.is_no_send)

    # 封装登录流程
    def ec_login(self, username, password):
        self.page_please_login()
        self.page_username(username)
        self.page_password(password)
        self.page_submit(PageLogin.submit)
        if username != "" and password != "":
            j1 = self.page_jump()
            if j1 == '登录成功':
                self.page_out()
            self.base_refresh()
            return j1
        else:
            a = self.base_alert()
            self.base_refresh()
            return a

    # 封装管理员登录流程
    def ec_admin_login(self, username, password):
        self.page_username(username)
        self.page_password(password)
        self.page_submit(PageLogin.admin_submit)
        if username == "":
            result = self.base_alert()
        else:
            if self.driver.title == 'ECSHOP 管理中心':
                self.base_frame(PageLogin.frame1)
                result = self.base_text(PageLogin.admin)
                self.base_click(PageLogin.admin)
                self.page_out()
            else:
                result = self.base_text(PageLogin.info)
            self.base_default()
            self.base_open("http://127.0.0.1/ecshop/admin/privilege.php?act=login")
        return result

    # 管理员模块
    def ec_admin_model(self, username, password, confirm_password, email, zsgc):
        self.page_username('admin')
        self.page_password('a1234567')
        self.page_submit(PageLogin.admin_submit)
        if zsgc == '增':
            result = self.page_add_vip(username, password, confirm_password, email)
        elif zsgc == "改":
            result = self.page_change(password, confirm_password, email)
        elif zsgc == '删':
            result = self.page_delete_vip()
        elif zsgc == '关闭验证':
            result = self.page_sys_manage()
        else:
            result = self.page_send(username)

        self.base_default()
        self.base_frame(PageLogin.frame1)
        self.base_click(PageLogin.admin)
        self.page_out()
        self.base_open("http://127.0.0.1/ecshop/admin/privilege.php?act=login")
        return result


class PageECShopUserCenter(BasePage):
    """用户中心"""
    """ 页面元素 """
    please_login = (By.LINK_TEXT, '请登录')  # 请登录按钮
    username = (By.CSS_SELECTOR, '[name="username"]')  # 用户名
    password = (By.CSS_SELECTOR, '[name="password"]')  # 密码
    submit = (By.CSS_SELECTOR, '[name="submit"]')  # 提交
    user_center = (By.LINK_TEXT, '用户中心')
    user_info = (By.LINK_TEXT, '用户信息')
    year = (By.CSS_SELECTOR, '[name="birthdayYear"]')  # 年
    month = (By.CSS_SELECTOR, '[name="birthdayMonth"]')  # 月
    day = (By.CSS_SELECTOR, '[name="birthdayDay"]')  # 日
    girl = (By.XPATH, '/html/body/div[6]/div[2]/div/div/div/form[1]/table/tbody/tr[2]/td[2]/input[3]')
    boy = (By.XPATH, '/html/body/div[6]/div[2]/div/div/div/form[1]/table/tbody/tr[2]/td[2]/input[2]')
    secrecy = (By.XPATH, '/html/body/div[6]/div[2]/div/div/div/form[1]/table/tbody/tr[2]/td[2]/input[1]')  # 性别保密
    email = (By.CSS_SELECTOR, '[name="email"]')
    submit1 = (By.XPATH, '/html/body/div[6]/div[2]/div/div/div/form[1]/table/tbody/tr[10]/td/input[2]')  # 点击用户信息下面的确认修改
    submit2 = (By.XPATH, '/html/body/div[6]/div[2]/div/div/div/form[2]/table/tbody/tr[4]/td/input[2]')  # 点击确认密码下面确认修改
    out_password = (By.CSS_SELECTOR, '[name="old_password"]')
    new_password = (By.CSS_SELECTOR, '[name="new_password"]')
    comfirm_password = (By.CSS_SELECTOR, '[name="comfirm_password"]')

    address = (By.LINK_TEXT, '收货地址')
    new_address = (By.CSS_SELECTOR, '[value="新增收货地址"]')
    # 删除最上面的地址
    del_address = (By.XPATH, '/html/body/div[6]/div[2]/div/div/div/form[1]/table/tbody/tr[5]/td[2]/input[2]')

    # 修改第一个用户的地址
    province = (By.CSS_SELECTOR, '#selProvinces_0')  # 省
    city = (By.CSS_SELECTOR, '#selCities_0')  # 城市
    district = (By.CSS_SELECTOR, '#selDistricts_0')  # 区
    consignee = (By.CSS_SELECTOR, '#consignee_0')  # 姓名
    email1 = (By.CSS_SELECTOR, '#email_0')  # 邮箱
    address1 = (By.CSS_SELECTOR, '#address_0')  # 详细地址
    mobile = (By.CSS_SELECTOR, '#mobile_0')  # 手机

    jump = (By.XPATH, '/html/body/div[5]/div/div/div/div/p[1]')  # 跳转通知
    out = (By.LINK_TEXT, '退出')

    # 用户登录
    def page_login(self, username, password):
        self.base_click(PageECShopUserCenter.please_login)
        self.base_send(PageECShopUserCenter.username, username)
        self.base_send(PageECShopUserCenter.password, password)
        self.base_click(PageECShopUserCenter.submit)

    # 用户中心
    def page_user_center(self):
        self.base_click(PageECShopUserCenter.user_center)

    # 用户信息
    def page_user_info(self):
        self.base_click(PageECShopUserCenter.user_info)

    # 点击年月日
    def page_birthday(self, year, month, day):
        sleep(1)
        if year != "":
            self.base_select(PageECShopUserCenter.year, year)
            sleep(1)
        if month != "":
            self.base_select(PageECShopUserCenter.month, month)
            sleep(1)
        if day != "":
            self.base_select(PageECShopUserCenter.day, day)
            sleep(1)

    # 选择性别
    def page_sex(self, sex):
        if sex == '1':
            self.base_click(PageECShopUserCenter.secrecy)
        elif sex == '2':
            self.base_click(PageECShopUserCenter.boy)
        else:
            self.base_click(PageECShopUserCenter.girl)

    # 修改邮箱
    def page_email(self, email):
        self.base_send(PageECShopUserCenter.email, email)

    # 点击确认修改
    def page_user_center_submit(self, submit):
        if submit == '1':
            self.base_click(PageECShopUserCenter.submit1)
        else:
            self.base_click(PageECShopUserCenter.submit2)

    # 修改密码
    def page_new_password(self, out_password, new_password, comfirm_password):
        self.base_send(PageECShopUserCenter.out_password, out_password)
        self.base_send(PageECShopUserCenter.new_password, new_password)
        self.base_send(PageECShopUserCenter.comfirm_password, comfirm_password)

    # 点击收货地址
    def page_address(self):
        self.base_click(PageECShopUserCenter.address)

    # 删除最上面的收货地址
    def page_del_address(self):
        self.base_click(PageECShopUserCenter.del_address)
        return self.base_alert()

    # # 点击新增收货地址
    # def page_new_address(self):
    #     self.base_click(PageECShopUserCenter.new_address)

    # 判断有几个收货地址
    def page_len_address(self):
        length = len(self.driver.find_elements(By.CSS_SELECTOR, '[name="theForm"]'))
        length = length - 1
        return length

    # 新增地址
    def page_new_address(self, province, city, district, consignee, address, mobile, length):
        if province != '':
            self.base_select((By.CSS_SELECTOR, f'#selProvinces_{length}'), province)
            sleep(1)
        if city != '':
            self.base_select((By.CSS_SELECTOR, f'#selCities_{length}'), city)
            sleep(1)
        if district != '':
            self.base_select((By.CSS_SELECTOR, f'#selDistricts_{length}'), district)
            sleep(1)
        self.base_send((By.CSS_SELECTOR, f'#consignee_{length}'), consignee)
        self.base_send((By.CSS_SELECTOR, f'#address_{length}'), address)
        self.base_send((By.CSS_SELECTOR, f'#mobile_{length}'), mobile)
        self.base_click(PageECShopUserCenter.new_address)
        if province == "" or city == "" or district == "" or consignee == "" or address == "" or mobile == "":
            a = self.base_alert()
            return a
        else:
            return self.base_text(PageECShopUserCenter.jump)

    # 修改地址
    def page_modify_address(self, province, city, district, consignee, address, mobile, email):
        self.base_select(PageECShopUserCenter.province, province)
        sleep(1)
        self.base_select(PageECShopUserCenter.city, city)
        sleep(1)
        self.base_select(PageECShopUserCenter.district, district)
        sleep(1)
        self.base_send(PageECShopUserCenter.email1, email)
        self.base_send(PageECShopUserCenter.consignee, consignee)
        self.base_send(PageECShopUserCenter.address1, address)
        self.base_send(PageECShopUserCenter.mobile, mobile)
        self.base_click(PageECShopUserCenter.submit)  # 确认修改

    # 点击退出
    def page_out(self):
        self.base_click(PageECShopUserCenter.out)

    # 用户信息
    def ec_user_center(self, username, password, year, month, day, sex, email, out_password,
                       new_password, comfirm_password, submit, num):
        self.page_login(username, password)
        self.page_user_center()
        self.page_user_info()
        print("------------------------------=====" + num)
        if submit == '1':
            self.page_birthday(year, month, day)

            self.page_sex(sex)

            self.page_email(email)
            self.page_user_center_submit(submit)
            sleep(2)
        else:
            print("------------------------------=====2" + num)
            self.page_new_password(out_password, new_password, comfirm_password)
            self.page_user_center_submit(submit)
            sleep(2)
        if num == '1':
            result = self.base_text(PageECShopUserCenter.jump)
            if result == '您的新密码已设置成功!':
                return result
        else:
            result = self.base_alert()
        sleep(3)
        self.page_out()
        sleep(3)
        self.base_refresh()
        return result

    # 收货地址-增删改
    def ec_address(self, username, password, province, city, district, consignee, address, mobile, email, zsg):
        self.page_login(username, password)
        self.page_user_center()
        self.page_address()
        length = self.page_len_address()

        if zsg == '改':
            self.page_modify_address(province, city, district, consignee, address, mobile, email)
            if province == "" or city == "" or district == "" or consignee == "" or address == "" or mobile == "" or email == "":
                result = self.base_alert()  # 获取警告框文本并关闭
                self.page_out()
                return result
            result = self.base_text(PageECShopUserCenter.jump)
        elif zsg == '删':
            result = self.page_del_address()
        else:
            result = self.page_new_address(province, city, district, consignee, address, mobile, length)
        self.page_out()
        self.base_refresh()
        return result

testcase层

conftest.py

# pytest的测试配置文件
# 一定要创建在测试用例所在路径
# 编写全局测试夹具
# pytest夹具
import pytest
from page.page_ECShop_Login import PageLogin, PageECShopUserCenter
from page.page_ECShop_Shopping import PageECShopSearch, PageECShopShopping
from page.page_ECShop_sign import PageSign


@pytest.fixture(scope="class")  # 非自动运行
def ec_login_fixture():   # 单独定义的函数!没有self参数!!
    # 初始化
    p = PageLogin()  # 对象
    p.base_open("http://127.0.0.1/ecshop/")
    yield p  # 与return区别
    # 还原清理
    p.base_quit()


@pytest.fixture(scope="class")  # 非自动运行
def ec_admin_login_fixture():   # 单独定义的函数!没有self参数!!
    # 初始化
    p = PageLogin()  # 对象
    p.base_open("http://127.0.0.1/ecshop/admin/privilege.php?act=login")
    yield p  # 与return区别
    # 还原清理
    p.base_quit()


@pytest.fixture(scope="class")  # 非自动运行
def ec_user_center_fixture():   # 单独定义的函数!没有self参数!!
    # 初始化
    p = PageECShopUserCenter()  # 对象
    p.base_open("http://127.0.0.1/ecshop/")
    yield p  # 与return区别
    # 还原清理
    p.base_quit()


@pytest.fixture(scope="class")  # 非自动运行
def es_fixture():   # 单独定义的函数!没有self参数!!
    # 初始化
    p = PageECShopSearch()  # 对象
    p.base_open("http://127.0.0.1/ecshop/")
    yield p  # 与return区别
    # 还原清理
    p.base_quit()


@pytest.fixture(scope="class")  # 非自动运行
def es_shopping_fixture():   # 单独定义的函数!没有self参数!!
    # 初始化
    p = PageECShopShopping()  # 对象
    p.base_open("http://127.0.0.1/ecshop/")
    yield p  # 与return区别
    # 还原清理
    p.base_quit()


@pytest.fixture(scope="class")  # 非自动运行
def ec_sign_fixture():   # 单独定义的函数!没有self参数!!
    # 初始化
    p = PageSign()  # 对象
    p.base_open("http://127.0.0.1/ecshop/")
    yield p  # 与return区别
    # 还原清理
    p.base_quit()

test_login.py

import pytest

from common.read_data import ReadData


class TestECShopSign:
    # 测试用例
    # pytest的参数化
    @pytest.mark.sign
    @pytest.mark.parametrize("username, email, password, conform_password, "
                             "QQ, work_phone, home_phone, phone, question, "
                             "passwd_answer, ass",
                             ReadData().csv_read("../data/csv_ECShop_sign.csv"))
    def test_sign(self, username, email, password, conform_password, QQ,
                    work_phone, home_phone, phone, question, passwd_answer,
                    ass, ec_sign_fixture):
        print("OOOOOOOOOOOOOOOO" + ass)
        a = ec_sign_fixture
        result = a.ec_sign(username, email, password, conform_password,
                    QQ, work_phone, home_phone, phone, question, passwd_answer)
        # 断言
        print("\nass = -->" + ass)
        print("\nresult = -->" + result)

        assert ass in result


class TestECShopLogin:
    @pytest.mark.login
    @pytest.mark.parametrize("username, password, ass", ReadData().csv_read("../data/ECShop_Login.csv"))
    def test_login(self, username, password, ass, ec_login_fixture):
        a = ec_login_fixture
        result = a.ec_login(username, password)
        # 断言
        print("\nass = -->" + ass)
        print("\nresult = -->" + result)

        assert ass in result


class TestECShopShopping:
    # 测试用例
    # pytest的参数化
    @pytest.mark.Shopping
    @pytest.mark.parametrize("user, pwd, province, city, district, consignee, address, mobile, tr, pay, ass",
                             ReadData().csv_read("../data/Ecshop_Shopping.csv"))
    def test_shopping(self, user, pwd, province, city, district, consignee, address, mobile, tr, pay, ass, es_shopping_fixture):
        a = es_shopping_fixture
        result = a.ec_shopping(user, pwd, province, city, district, consignee, address, mobile, tr, pay)
        # 断言
        assert ass in result
        print("\n+++"+ass+"\n")
        print("\n+++"+result)


class TestECSSearch:
    # 测试用例
    # pytest的参数化
    @pytest.mark.search
    @pytest.mark.parametrize("content, ass", ReadData().csv_read("../data/Ecshop_Search.csv"))
    def test_search(self, content, ass, es_fixture):
        a = es_fixture
        result = a.ec_search(content)
        # 断言
        assert ass in result
        print("\n+++"+ass+"\n")
        print("\n+++"+result)


class TestECShopUserCenter:
    @pytest.mark.center
    @pytest.mark.parametrize("username, password, year, month, day, sex, email, out_password, "
                             "new_password, comfirm_password, submit, num, ass",
                             ReadData().csv_read("../data/ECShop_UserCenter.csv"))
    def test_user_center(self, username, password, year, month, day, sex, email, out_password,
                         new_password, comfirm_password, submit, num, ass, ec_user_center_fixture):
        a = ec_user_center_fixture
        result = a.ec_user_center(username, password, year, month, day, sex, email, out_password,
                                  new_password, comfirm_password, submit, num)
        # 断言
        print("\nass = -->" + ass)
        print("\nresult = -->" + result)

        assert ass in result


class TestECShopAddress:
    @pytest.mark.address
    @pytest.mark.parametrize("username, password, province, city, district, consignee, address, mobile, email"
                             ", zsg, ass", ReadData().csv_read("../data/ECShop_Address.csv"))
    def test_address(self, username, password, province, city, district, consignee, address, mobile,
                     email, zsg, ass, ec_user_center_fixture):
        a = ec_user_center_fixture
        result = a.ec_address(username, password, province, city, district, consignee, address, mobile, email, zsg)
        # 断言
        print("\nass = -->" + ass)
        print("\nresult = -->" + result)

        assert ass in result


class TestECShopAdminLogin:
    @pytest.mark.admin_login
    @pytest.mark.parametrize("username, password, ass", ReadData().csv_read("../data/ECShop_Admin_Login.csv"))
    def test_admin_login(self, username, password, ass, ec_admin_login_fixture):
        a = ec_admin_login_fixture
        result = a.ec_admin_login(username, password)
        # 断言
        print("\nass = -->" + ass)
        print("\nresult = -->" + result)

        assert ass in result


class TestECShopAdmin:
    @pytest.mark.admin
    @pytest.mark.parametrize("username, password, confirm_password, email, zsgc, ass",
                             ReadData().csv_read("../data/ECShop_Admin.csv"))
    def test_admin(self, username, password, confirm_password, email, zsgc, ass, ec_admin_login_fixture):
        a = ec_admin_login_fixture
        result = a.ec_admin_model(username, password, confirm_password, email, zsgc)
        # 断言
        print("\nass = -->" + ass)
        print("\nresult = -->" + result)

        assert ass in result

venv层

pytest.ini

[pytest]

# 设置测试执行默认参数
addopts = -vs


# 设置默认测试用例路径
# ./当前路径venv  ../上级路径
testpaths = ../testcase

# 设置默认的模块名称
python_files = test_login.py

# 设置默认测试类名称
python_classes = Test*

# 设置默认测试用例函数名称
python_functions = test_

# 设置标记
markers =
    sign:ECShop注册
    login:ECShop登录
    Shopping:购物功能
    search:搜索功能
    center:ECShop用户中心
    address:收货地址增删改
    admin_login:管理员登录
    admin:管理模块

run.tests.py

import time
import pytest

result_name = time.strftime("%Y-%m-%d %H-%M-%S")
# pytest套件 指定路径 指定模块 指定类 指定测试用例
# pytest套件 分组执行 -m
pytest.main([f"--html=../report/{result_name}.html"])
# pytest.main(["-m=admin", f"--html=../report/{result_name}.html"])
# -m=baidu or webtour 同时运行两个标记的用例
# pytest-html 用户生成Html格式报告的第三方模块
# pytest可以兼容Unittest

 requirements.txt

pytest
pytest-xdist
pytest-ordering
pytest-rerunfailures
pytest-html
allure-pytest

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/736914.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

算法leetcode|61. 旋转链表(rust重拳出击)

文章目录 61. 旋转链表&#xff1a;样例 1&#xff1a;样例 2&#xff1a;提示&#xff1a; 分析&#xff1a;题解&#xff1a;rust&#xff1a;go&#xff1a;c&#xff1a;python&#xff1a;java&#xff1a; 61. 旋转链表&#xff1a; 给你一个链表的头节点 head &#xf…

Mysql-------SQL:DDL数据定义语言、DDM数据操作语言、DQL数据库查询语言、DQL数据控制语言

MySQL MySQL是一个关系型数据库管理系统&#xff0c;其数据是保存在不同的数据表中&#xff0c;而不是将所有数据放在一个大仓库内&#xff0c;这样就增加了速度并提高了灵活性 SQL MySQL所使用的SQL语言是用于访问数据库的最常用标准化语言&#xff0c; SQL语言可以分为&am…

JDY-31 蓝牙传输模块的使用、调试和传输

JDY-31 蓝牙基于蓝牙 3.0 SPP 设计&#xff0c;这样可以支持 Windows、Linux、android 数据透传&#xff0c; 工作频段 2.4GHZ&#xff0c;调制方式 GFSK&#xff0c;最大发射功率 8db&#xff0c;最大发射距离 30 米&#xff0c;支持用户通过 AT 命令修改设备名、波特率等指令…

java商城 开源java电子商务Spring Cloud+Spring Boot+mybatis+MQ+VR全景+b2b2c

1. 涉及平台 平台管理、商家端&#xff08;PC端、手机端&#xff09;、买家平台&#xff08;H5/公众号、小程序、APP端&#xff08;IOS/Android&#xff09;、微服务平台&#xff08;业务服务&#xff09; 2. 核心架构 Spring Cloud、Spring Boot、Mybatis、Redis 3. 前端框架…

Mybatis动态SQL解析:XML配置如何变成最终的Sql语句?

简介 动态SQL是Mybatis的一项核心功能&#xff0c;通过一份静态的XML配置 外部参数&#xff0c;动态生成最终的SQL语句&#xff0c;可以用很少的理解成本配置复杂条件的动态SQL&#xff0c;摆脱各种处理逗号、空格这些细枝末节的痛苦。 标签说明 要实现动态拼接SQL&#xf…

C++菱形继承

菱形继承 菱形继承&#xff1a;指有一个基类被两个不同的类所继承&#xff0c;且存在一个类继承于这两个类而形成的一种菱形关系&#xff0c;故称菱形继承。如下图所示&#xff1a; 菱形继承存在的问题 二义性&#xff08;ambiguity&#xff09;&#xff1a;当派生类同时继…

memset(addr , 0 , size) 导致Bus error问题分析

导致问题出现的demo代码 #define SH_DEV_MEM "/dev/mem" #define myerror printf // 获取由mmap映射的设备物理内存 static void *mymmap(u32 offset, u32 size, u8 is_rd_only, u8 is_clear) {void *ptr;s32 fd;offset 0x45E00000;size 0x1000;is_rd_only 0;is_…

【Step By Step】VM安装redhat-server7.9搭建Oracle19C RAC(一)环境配置

文章目录 环境规划网络规划文件系统规划rac用户规划grid与oracle用户规划ASM规划 虚拟机设置搭建虚拟机自定义网卡安装操作系统 操作系统设置关闭services修改/etc/hosts创建用户与组创建文件目录设置环境变量设置内核参数资源限制添加 etc/pam.d/login关闭大页关机挂载本地ISO…

【C++初阶】:vector的基本介绍

vector的基本介绍 一.vector(向量)介绍二.vector原型三.构造四.区别reserve和resize五.二维数组 一.vector(向量)介绍 二.vector原型 vector主要分为两个模板参数&#xff0c;一个是T&#xff0c;T是将数据类型进行实例化&#xff08;本质就是一个数组&#xff09;。第二个参数…

idea 搭建 SpringBoot 集成 mybatis

编译器&#xff1a;IDEA 环境&#xff1a;win10&#xff0c;jdk1.8&#xff0c;maven3.5 数据库&#xff1a;mysql 5.7 一、打开IDEA新建项目 1. 如果你是第一次使用IDEA&#xff0c;那么你需要配置你本地的maven&#xff0c;点击右下角 Configure&#xff0c;如已配置请忽…

第三章:Linux简介及面试常问问题

目录 一、Linux发展史 1.Linux前身-Unix 2.Linux诞生 3.开源文化 4.Linux系统特点 5.Linux操作系统优点 6.Linux操作系统发行版 7.Linux内核命名规则 二、Linux系统的安装 三、linux系统分区简介及如何分区 1.自动分区 2.手动分区 3.linux下查看分区信息和剩余空间…

STM32CubeMX安装

一、配置JAVA环境 1.相关资料链接 链接: CubeMX 提取码&#xff1a;13ec 双击改exe文件。 2.更改默认的安装路径 3.在该exe文件同等目录下&#xff0c;新建一个JAVA-Enviroment文件夹。 选择更改安装路径&#xff0c;放在刚才新建的JAVA-Enviroment文件夹中。 4.等待安装完…

RabbitMQ - 单机部署(超详细)

RabbitMQ部署 1.单机部署 我们在Centos7虚拟机中使用Docker来安装。 1.1.下载镜像 方式一&#xff1a;在线拉取 docker pull rabbitmq:3-management方式二&#xff1a;从本地加载 也可以从网上搜索 RabbitMQ 的 tar 包下载下来 上传到虚拟机中后&#xff0c;使用命令加载…

2023高校夏令营 | 第七年,我们又开营啦!

进入7月&#xff0c;成都的天气就不再像之前那样温和&#xff0c;迎接我们的是热浪滔天&#xff0c;以及一场场猝不及防的高温暴雨。如同当下的毕业季&#xff0c;脱离校园庇护的应届生们涌入就业市场&#xff0c;开始应对来自社会、职场的各种风雨考验。 为了加快推进产教融合…

js深拷贝、js使用递归实现深拷贝

相信看到这篇文章之前你应该多多少少了解过什么是深拷贝了为什么要什么拷贝了 这里就不介绍什么是深拷贝、浅拷贝了 最优解深拷贝方法&#xff1a;递归 这里为了方便直接在vue的页面里面演示了&#xff0c;在其他js文件中使用注意下this mounted() {const obj {str: "字…

实战解决百度旋转验证码

1、效果演示 2、如何识别 2.1准备数据集 首先需要使用爬虫&#xff0c;对验证码图片进行采集&#xff0c;尽量每一种类型都要采集到。 2.2图像矫正 接下来对采集的数据进行人工校正 2.3数据清洗 &#xff08;1&#xff09;对数据进行进行旋转&#xff0c;达到增加数据量的目…

44. 日期交叉问题

文章目录 题目需求思路一实现一原理二实现二学习链接题目来源 题目需求 现有各品牌优惠周期表&#xff08;promotion_info&#xff09;如下&#xff0c;其记录了每个品牌的每个优惠活动的周期&#xff0c;其中同一品牌的不同优惠活动的周期可能会有交叉。 现要求统计每个品牌…

聊一聊Java中的Steam流 | 京东物流技术团队

1 引言 在我们的日常编程任务中&#xff0c;对于集合的制造和处理是必不可少的。当我们需要对于集合进行分组或查找的操作时&#xff0c;需要用迭代器对于集合进行操作&#xff0c;而当我们需要处理的数据量很大的时候&#xff0c;为了提高性能&#xff0c;就需要使用到并行处…

Golang内存分配及垃圾回收

为什么需要垃圾回收&#xff1f; 自动释放不需要的对象&#xff0c;让出存储器资源&#xff0c;无需程序员手动执行 Go V1.3之前是标记-清除算法 具体步骤 缺点&#xff1a;程序卡顿、扫描整个heap、数据清除会产生heap碎片 V1.3之后&#xff0c;做了简单的优化 V1.5之后&a…

AIFORE Smart Fuzzing Based on Automatic Input Format Reverse Engineering

AIFORE: Smart Fuzzing Based on Automatic Input Format Reverse Engineering 1 中国科学院信息工程研究所2清华大学网络科学与网络空间研究院;中关村实验室3华为技术有限公司奇异安全实验室4中国科学院大学网络安全学院5中国人民大学6洛桑联邦理工学院 论文链接 &#xff1a…