UnitTest + Selenium 完成在线加法器自动化测试
1. 任务概述
利用 UnitTest 与 Selenium 编写自动化用例,测试在线加法器中的整数单次加法功能【如1+2=3 】
人工操作流程(测试 1+2 是否等于 3):
- 打开在线加法器
- 点击按钮
1
,再点击按钮+
,再点击按钮2
,再次点击按钮=
- 观察计算机框框的计算结果是否等于
3
,若出现错误则截图保留,否则测试通过 - 关闭浏览器
自动化测试编写流程:
-
使用 selenium 实例化浏览器,打开在线加法器并最大化窗口
-
使用 CSS 选择器定位至按钮
清屏
,点击【此处是为了保险】使用 CSS 选择器定位至按钮
1
,点击使用 CSS 选择器定位至按钮
+
,点击使用 CSS 选择器定位至按钮
2
,点击使用 CSS 选择器定位至按钮
=
,点击 -
使用 CSS 选择器定位至结果框框,获取此组件
value
值并与预期结果3
进行比对,过程中发生错误截图保留 -
关闭浏览器
2. PO模式
Page Objece,分层机制,让不同层去做不同类型的事情,让代码结构清晰,增加复⽤性
- 两层:对象逻辑层 + 业务数据层
- 三层:对象库层 + 逻辑层 + 业务数据层【本案例所使用】
- 四层:对象库层 + 逻辑层 + 业务层 + 数据层
base层
将最基础的一类方法进行封装,如点击click,获取value值,浏览器实例化等操作,通过被继承从而实现复用
page层
定义一些配置数据,如在线计算器网址,各按钮的定位方式等,同时通过继承 Base 类得到一些基础方法,在此基础上进一步完善处理逻辑
scripts层
编写测试类,完善业务处理流程,script 调用 page 并设置断言【即结果是否正确】,发生错误时完成截图并存储至于 image 层
3. 源码详情
base层
base.py
import time
from selenium.webdriver.support.wait import WebDriverWait
class Base:
# 初始化方法
def __init__(self,driver):
self.driver = driver
# 查找元素
def base_find_element(self,loc,timeout=30,poll_frequency=0.5):
"""
:param loc: 元素的定位信息,格式为元组
:param timeout: 显式等待最长时间
:param poll_frequency: 显式等待请求间隔
:return: 返回查找到的对象
"""
# 显式等待特定组件
return WebDriverWait(self.driver,
timeout=timeout,
poll_frequency=poll_frequency).until(lambda x:x.find_element(*loc))
# 点击
def base_click(self,loc):
self.base_find_element(loc).click()
# 获取组件value属性值
def base_get_value(self,loc):
return self.base_find_element(loc).get_attribute('value')
# 截图
def base_get_img(self):
self.driver.get_screenshot_as_file(f'../image/{time.strftime("%Y_%m_%d %H_%M_%S")}.png')
get_driver.py
from selenium import webdriver
from calcTestProject import page
class GetDriver:
driver = None
# 获取driver
@classmethod
def get_driver(cls):
if cls.driver is None:
option = webdriver.ChromeOptions()
# 指定chrome存储路径的二进制形式
option.binary_location = page.binary_location
# 实例化浏览器
cls.driver = webdriver.Chrome(options=option)
# 最大化窗口
cls.driver.maximize_window()
# 打开浏览器
cls.driver.get(page.url)
return cls.driver
# 推出driver
@classmethod
def quit_driver(cls):
if cls.driver:
cls.driver.quit()
# 置空
cls.driver=None
page层
__init__.py
from selenium.webdriver.common.by import By
""""以下为服务器域名配置数据"""
url = "http://zaixianjisuanqi.bmcx.com"
# 谷歌浏览器位置
binary_location='D:\Chrome\Google\Chrome\Application\chrome.exe'
"""以下为计算器配置数据"""
# 加号
clac_add = (By.CSS_SELECTOR,'#simpleAdd')
# 等号
clac_eq = (By.CSS_SELECTOR,'#simpleEqual')
# 获取结果
clac_result = (By.CSS_SELECTOR,'#resultIpt')
# 清屏
clac_clear = (By.CSS_SELECTOR,'#simpleClearAllBtn')
page_calc.py
from calcTestProject.base.base import Base
from selenium.webdriver.common.by import By
from calcTestProject import page
class PageCalc(Base):
# 点击数字方法
def page_click_num(self,num):
for n in str(num):
# 按照计算需求拼接数字按键的loc
loc = (By.CSS_SELECTOR,f'#simple{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):
self.base_get_value(page.clac_result)
# 点击清屏
def page_click_clear(self):
self.base_click(page.clac_clear)
# 截图
def page_get_image(self):
self.base_get_img()
# 组装加法业务方法
def page_add_calc(self,a,b):
# 清屏
self.page_click_clear()
# 点击第一个数
self.page_click_num(a)
# 点击加号
self.page_click_add()
# 点击第二个数
self.page_click_num(b)
# 点击等号
self.page_click_eq()
# 返回计算结果
return self.page_get_value()
script层
test_calc.py
import unittest
from parameterized import parameterized
from calcTestProject.page.page_calc import PageCalc
from calcTestProject.base.get_driver import GetDriver
class TestCalc(unittest.TestCase):
# 类前置操作
@classmethod
def setUpClass(cls):
# 获取driver对象
cls.driver = GetDriver().get_driver()
cls.calc = PageCalc(cls.driver)
# 下拉条,防止广告遮挡
js = "window.scrollTo(0,256)"
cls.driver.execute_script(js)
# 类后置操作
@classmethod
def tearDownClass(cls):
GetDriver().quit_driver()
# 测试加法方法(1+2是否等于3)
@parameterized.expand(((1,2,3),))
def test_add_calc(self,a,b,expect):
# 调用计算业务方法
self.calc.page_add_calc(a,b)
try:
# 断言【判断测试结果】
self.assertEqual(self.calc.page_get_value(),str(expect))
except:
# 截图
self.calc.page_get_image()