PO模式 数据驱动

数据驱动:以数据来驱动整个测试用例的执行,测试数据决定测试结果

数据驱动的实现要依赖参数化的技术

传入数据的方式:

  • 直接定义在测试脚本中
  • 从文件读取数据,如JSON,excel,xml,txt等格式文件
  • 从数据库中读取数据
  • 直接调用接口获取数据源
  • 本地封装一些生成数据的方法

示例一:对网页计算器,进行加法的测试操作,通过读取数据文件中的数据来执行用例

PO模式实现

utils

'''
通用工具类
'''

from selenium import webdriver


class UtilsDriver:
    _driver = None

    @classmethod
    def get_driver(cls):
        if cls._driver is None:
            cls._driver = webdriver.Chrome()
            cls._driver.maximize_window()
            cls._driver.implicitly_wait(10)
            cls._driver.get('http://cal.apple886.com/')
        return cls._driver

    @classmethod
    def quit_driver(cls):
        if cls._driver:
            cls.get_driver().quit()
            cls._driver = None

base_page

from selenium.webdriver.support.wait import WebDriverWait
from test_data.utils import UtilsDriver


# 基类的对象层
class BasePage:
    def __init__(self):
        self.driver = UtilsDriver.get_driver()

    def get_element(self, location):
        wait = WebDriverWait(self.driver, 10, 1)
        element = wait.until(lambda x: x.find_element(*location))
        return element


# 基类的操作层
class BaseHadle:
    # 暂时没用到
    def input_text(self, element, text):
        pass

main_page

from selenium.webdriver.common.by import By

from test_data.base.base_page import BasePage


# 首页的对象层,定位元素
class MainPage(BasePage):
    def __init__(self):
        super().__init__()
        # 获取数字元素
        self.digit_btn = (By.ID, 'simple{}')
        # 获取加号元素
        self.add_btn = (By.ID, 'simpleAdd')
        # 获取等号元素
        self.eq_btn = (By.ID, 'simpleEqual')
        # 获取结果
        self.res = (By.ID, 'resultIpt')

    def find_digit_btn(self, digit):
        '''
        获取数字元素
        :return:
        '''
        location = (self.digit_btn[0], self.digit_btn[1].format(digit))
        return self.get_element(location)

    def find_add_btn(self):
        '''
        获取加号元素
        :return:
        '''
        return self.get_element(self.add_btn)

    def find_eq_btn(self):
        '''
        获取等号元素
        :return:
        '''
        return self.get_element(self.eq_btn)

    def find_res(self):
        '''
        获取结果
        :return:
        '''
        return self.get_element(self.res)


# 首页的操作层,对元素的操作
class MainHandle:
    def __init__(self):
        self.main_page = MainPage()

    def click_digit_btn(self, digit):
        '''
        点击数字
        :return:
        '''
        self.main_page.find_digit_btn(digit).click()

    def click_add_btn(self):
        '''
        点击加号
        :return:
        '''
        self.main_page.find_add_btn().click()

    def click_eq_btn(self):
        '''
        点击等号
        :return:
        '''
        self.main_page.find_eq_btn().click()

    def get_res(self):
        '''
        获取结果
        :return:
        '''
        return self.main_page.find_res().get_attribute("value")

    def input_numbers(self, numbers):
        '''
        输入计算数字
        :param numbers:
        :return:
        '''
        for num in numbers:
            self.click_digit_btn(num)


# 首页的业务层,一个业务功能
class MainProxy:
    def __init__(self):
        self.main_handle = MainHandle()

    def add(self, num1, num2):
        '''
        完成一次加法运算
        :return:
        '''
        self.main_handle.input_numbers(str(num1))
        self.main_handle.click_add_btn()
        self.main_handle.input_numbers(str(num2))
        self.main_handle.click_eq_btn()

    def get_res(self):
        '''
        获取计算结果
        :return:
        '''
        return self.main_handle.get_res()

test_add

import json

import pytest

from test_data.page.main_page import MainProxy
from test_data.utils import UtilsDriver


def build_data():
    test_data = []
    with open("../data_driver/calculator.json", encoding='UTF-8') as f:
        test_data = json.load(f)
    print("test_data=", test_data)
    return test_data


class TestAdd:
    def setup_class(self):
        # 实例化业务对象
        self.main_proxy = MainProxy()

    def teardown_class(self):
        UtilsDriver.quit_driver()

    @pytest.mark.parametrize('num1,num2,expect', build_data())
    def test_add(self, num1, num2, expect):
        '''
        加法测试
        :return:
        '''
        print('num1={} num2={} expect={}'.format(num1, num2, expect))

        self.main_proxy.add(num1, num2)
        res = self.main_proxy.get_res()

        print("result=", res)

        assert res == str(expect)

calculator.json

[
  [1,1,2],
  [2,2,4],
  [1,0,1],
  [0,0,1],
  [12,23,35]
]

结构

 

结果

示例二: 实现登录模块的单元测试,对上次的改造

之前的test_login

# 定义测试类

from test_po.page.login_page import LoginProxy
from test_po.page.main_page import MainProxy
from test_po.utils import UtilsDriver, get_msg


class TestLogin:
    def setup_class(self):
        # 实例化首页和登录的业务对象
        self.main_proxy = MainProxy()
        self.login_proxy = LoginProxy()

        # 通过首页页面的业务层操作实现登录的跳转
        self.main_proxy.go_login_page()

    # 创建方法级别的fixture初始化的操作方法
    def setup(self):
        UtilsDriver.get_driver().refresh()

    # 创建类级别fixture销毁的操作方法
    def teardown_class(self):
        UtilsDriver.quit_driver()

    # 定义测试方法  账号不存在
    def test_login_01(self):
        self.login_proxy.login("13333337777", "123456")
        msg = get_msg()
        assert "账号或密码错误,请重试。" in msg

    # 定义测试方法  密码错误
    def test_login_02(self):
        self.login_proxy.login("cherishgf", "123456")
        # 获取提示信息
        msg = get_msg()
        assert "账号或密码错误。" in msg

    # 定义测试方法  用户名为空
    def test_login_03(self):
        self.login_proxy.login(" ", "123456")
        # 获取提示信息
        msg = get_msg()
        assert "继续操作前请注册或者登录。" in msg

修改后的test_login

# 定义测试类
import json

import pytest

from test_po.page.login_page import LoginProxy
from test_po.page.main_page import MainProxy
from test_po.utils import UtilsDriver, get_msg


def build_data():
    test_data = []
    with open('../data_driver/test_data.json', encoding='utf-8') as f:
        json_data = json.load(f)
        for case_data in json_data:
            test_data.append((case_data.get("username"),
                              case_data.get("password"),
                              case_data.get("is_success"),
                              case_data.get("expect")))
    print(test_data)
    return test_data


class TestLogin:
    def setup_class(self):
        # 实例化首页和登录的业务对象
        self.main_proxy = MainProxy()
        self.login_proxy = LoginProxy()

        # 通过首页页面的业务层操作实现登录的跳转
        self.main_proxy.go_login_page()

    # 创建方法级别的fixture初始化的操作方法
    def setup(self):
        UtilsDriver.get_driver().refresh()

    # 创建类级别fixture销毁的操作方法
    def teardown_class(self):
        UtilsDriver.quit_driver()

    # 定义测试方法
    @pytest.mark.parametrize('username, password,is_success, expect', build_data())
    def test_login(self, username, password, is_success, expect):
        print('username={} password={}  is_success={} expect={}'.
              format(username, password, is_success, expect))

        self.login_proxy.login(username, password)
        msg = get_msg()
        assert expect in msg

 结果

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值