项目框架如下图:
base完成的测试所需的操作的封装,有查找定位,点击,获取值,截屏
import time
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
class Base:
def __init__(self, driver):
# 确保类的init方法接收一个driver参数,并将其保存为实例变量
self.driver = driver
def base_find_element(self, loc, timeout=30, poll=0.5):
return WebDriverWait(self.driver, timeout=timeout, poll_frequency=poll).until(lambda x: x.find_element(*loc))
def base_click(self, loc):
self.base_find_element(loc).click()
def base_get_value(self, loc):
return self.base_find_element(loc).get_attribute("value")
def base_get_img(self):
return self.driver.get_screenshot_as_file("img/{}.png".format(time.strftime("%Y_%m_%d_%H_%M_%S")))
将浏览器的打开与关闭的操作分离,下面用到的是单例的思想
from selenium import webdriver
from script05.计算器案例 import page
class GetDriver:
driver = None
@classmethod
def get_driver(cls):
if cls.driver is None:
cls.driver = webdriver.Edge()
cls.driver.maximize_window()
cls.driver.get(page.url)
# 采用了单例的思想,driver的地址不变
return cls.driver
@classmethod
def quit_driver(cls):
if cls.driver:
# 使用quit关闭之后,driver的内容会消失,但会留下driver本身的地址
cls.driver.quit()
# 多条例需要重新为None,重新置空后,driver的地址也没了
cls.driver = None
测试用例
{
"clac_001": {"a": 1,"b": 2,"expect": 3},
"clac_002": {"a": 11,"b": 21,"expect": 32}
}
保存截图的软件包
将测试所用到的页面数据全部结合到这里,且调用page时会自动获取
from selenium.webdriver.common.by import By
url = "http://cal.apple886.com/"
clac_add = By.CSS_SELECTOR, "#simpleAdd"
# clac_reduce=By.CSS_SELECTOR,"#simpleSubtr"
clac_eq = By.CSS_SELECTOR, "#simpleEqual"
clac_result = By.CSS_SELECTOR, "#resultIpt"
clac_clear = By.CSS_SELECTOR, "#simpleClearAllBtn"
page页面相关,里面的方法对应的测试所用到的页面元素
from selenium.webdriver.common.by import By
from script05.计算器案例.base.base import Base
from script05.计算器案例 import page
class PageClac(Base):
def page_click_num(self, num):
for n in str(num):
# 元组(By.CSS_SELECTOR, "#simple{}")
loc = By.CSS_SELECTOR, "#simple{}".format(n)
self.base_click(loc)
def page_click_add(self):
self.base_click(page.clac_add)
def page_click_eq(self):
self.base_click(page.clac_eq)
def page_get_value(self):
return self.base_get_value(page.clac_result)
def page_click_clear(self):
self.base_click(page.clac_clear)
def page_get_img(self):
self.base_get_img()
def page_add_calc(self, num1, num2):
self.page_click_num(num1)
self.page_click_add()
self.page_click_num(num2)
self.page_click_eq()
测试的执行过程十分明了,获取用例数据,打开浏览器,输入用例,完成操作步骤,比对预期与实际结果
import json
import unittest
from script05.计算器案例.tools.read_json import read_json
from script05.计算器案例.base.driver import GetDriver
from script05.计算器案例.page.page_calc import PageClac
from parameterized import parameterized
# 此函数除了获取数据之外,还对数据进行加工,以达到所需的数据类型
def get_data():
# 这里调用了tool中的read_json方法将数据提取出来
datas = read_json("calc.json")
arr = []
for data in datas.values():
arr.append((data['a'], data['b'], data['expect']))
return arr
class TestClac(unittest.TestCase):
driver = None
@classmethod
def setUpClass(cls):
cls.driver = GetDriver().get_driver()
# cls.driver会通过PageClac保存到base的driver中
cls.clac = PageClac(cls.driver)
@classmethod
def tearDownClass(cls):
# # 这里是不会给提示的,这里的driver是base的,让base关闭浏览器
# cls.clac.driver.quit()
GetDriver().quit_driver()
@parameterized.expand(get_data())
def test_add(self, num1, num2, expect):
self.clac.page_add_calc(num1, num2)
try:
result = self.clac.page_get_value()
print("期望结果:", result, "实际结果", expect)
self.assertEqual(result, str(expect))
except AssertionError:
self.clac.page_get_img()
print("计算错误")
这是一个小工具,方便打开测试数据的文件
import json
def read_json(filename):
filepath = "../data/" + filename
with open(filepath, encoding="utf-8") as f:
return json.load(f)
# 用于在本方法中进行测试,对外部调用无影响
if __name__ == '__main__':
# 在read_json方法中加入data下对应文件的名称即可使用
data = read_json("calc.json")
print(data)
# 期望:[(1, 2, 3), (11, 21, 32)]
# 实际:{'clac_001': {'a': 1, 'b': 2, 'expect': 3}....
# 由此可用以下方式解决
# 传输的参数不需要alac_00x、a、b和expect,故需要将其一一清除
# parameterized只接受元组数据,故n['a'], n['b'], n['expect']需要加上()
# 还需要创建一个列表,将每组元组数据放入,这还需要列表的append方法
arr = []
# data.values()清除alac_00x
for n in data.values():
print(n)
# n[' ']清除a、b和expect
arr.append((n['a'], n['b'], n['expect']))
print(arr)