一、区分正向逆向用例
思路:在测试数据中添加一一个标识正向用例或逆向用例的标记:如:True/False
步骤:
- 调用登录方法(此登录方法中,只有输入用户名、输入密码、输入验证码、
点击登录按钮) - 判断用例标记:
#判断安全退出是否存在
#点击安全退出
#点击登录连接地址
二、实例
TPshop网站的登录模块进行单元测试(最终版),可点击链接查看之前不同模式的测试
(一)实现步骤
- 编写测试用例
- 采用PO模式的分层思想对页面进行封装
- 编写测试脚本
- 定义数据文件,实现参数化
(二)用例设计
(三)代码结构图
(四)示例代码
- 对象库层:base.py
"""base.py"""
# -*-coding:utf-8 -*-
# Auothor:yue_luo
import time
from selenium.webdriver.support.wait import WebDriverWaitclass Base:# 初始化def __init__(self,driver):self.driver = driver# 查找元素方法def base_find_element(self,loc,timeout=30,poll_frequency=0.5):return WebDriverWait(driver=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()# 输入方法def base_input(self,loc,value):element = self.base_find_element(loc)element.clear()element.send_keys(value)# 获取文本方法def base_get_text(self,loc):msg = self.base_find_element(loc).textreturn msg# 截图def base_get_image(self,):self.driver.get_screenshot_as_file("./{}.png".format(time.strftime("%Y_%m_%d_%H_%M_%S")))# 判断元素是否存在def base_if_success(self,loc):try:self.base_find_element(loc, timeout=2)# 找到元素 assertTruereturn Trueexcept:return False
"""get_driver.py"""
# -*-coding:utf-8 -*-
# Auothor:yue_luo
from selenium import webdriver
from v3 import pageclass GetDriver:driver = None@classmethoddef get_driver(cls):if cls.driver == None:cls.driver = webdriver.Chrome()cls.driver.maximize_window()cls.driver.get(page.url)return cls.driver@classmethoddef quit_driver(cls):if cls.driver:cls.driver.quit()"""置空"""cls.driver = None
- 操作层:_ _init _ _.py 和 page_login.py
"""__init__.py"""
# -*-coding:utf-8 -*-
# Auothor:yue_luo
from selenium.webdriver.common.by import By"""以下为服务器域名配置地址"""
url ="http://www.tpshop.com""""以下为登录页面配置信息"""
# 登录链接
login_link = By.PARTIAL_LINK_TEXT , "登录"
# 用户名
login_username = By.ID,"username"
# 密码
login_pwd = By.NAME,"password"
# 验证码
login_verify_code = By.CSS_SELECTOR,"#verify_code"
# 登录按钮
login_btn =By.NAME,"sbtbutton"
# 获取异常文本信息
login_err_info = By.CLASS_NAME,"layui-layer-content"
# 异常提示框 确定按钮
login_err_btn_ok = By.CSS_SELECTOR,".layui-layer-btn0"
# 安全退出
login_logout = By.PARTIAL_LINK_TEXT,"安全退出"
"""page_login.py"""
from v3 import page
from v3.base.base import Baseclass PageLogin(Base):# 点击登录链接def page_click_login_link(self):self.base_click(page.login_link)# 输入用户名def page_input_username(self,username):self.base_input(page.login_username,username)# 输入密码def page_input_passwrod(self,pwd):self.base_input(page.login_pwd,pwd)# 输入验证码def page_input_verify_code(self,code):self.base_input(page.login_verify_code,code)# 点击登录def page_click_login_btn(self):self.base_click(page.login_btn)# 获取异常提示信息def page_get_error_info(self):return self.base_get_text(page.login_err_info)# 点击异常信息框 确定def page_click_error_btn_ok(self):self.base_click(page.login_err_btn_ok)# 截图def page_get_screenshot(self):self.base_get_image()# 点击 安全退出->退出登录def page_click_logout(self):self.base_click(page.login_logout)# 判断是否登录成功def page_is_login_success(self):return self.base_if_success(page.login_logout)# 判断是否退出成功def page_is_logout_success(self):return self.base_if_success(page.login_link)# 组合业务方法def page_login(self,username,pwd,code):self.page_input_username(username)self.page_input_passwrod(pwd)self.page_input_verify_code(code)self.page_click_login_btn()
- 业务层:test_login.py
"""test_login.py"""
# -*-coding:utf-8 -*-
# Auothor:yue_luo# 导包
import unittest
from time import sleep
from parameterized import parameterizedfrom v3.base.get_driver import GetDriver
from v3.page.page_login import PageLogin# 参数化
from v3.tool.read_json import read_jsondef get_data():data = read_json("login.json")"""期望数据格式:[("13099999999","123456","8888","账号不存在!",false),("17864307785","error","8888","密码错误!",false)]"""list = []for n in data.values():list.append((n["username"], n["pwd"], n["code"], n["msg"],n["flag"]))# n["key"] 或n.get("key")return list# 新建测试类并继承
class TestLogin(unittest.TestCase):# setUp@classmethoddef setUpClass(cls):# 实例化driver并获取cls.driver = GetDriver().get_driver()# 实例化 获取登录对象cls.login =PageLogin(cls.driver)# 点击登录链接cls.login.page_click_login_link()# tearDown@classmethoddef tearDownClass(cls):# 关闭driver浏览器驱动对象sleep(3)GetDriver().quit_driver()# 登录测试方法@parameterized.expand(get_data())def test_login(self,username,pwd,code,expect_result,success):# 调用登录方法self.login.page_login(username,pwd,code)# 登陆成功if success :try:# 判断 安全退出是否存在self.assertTrue(self.login.page_is_login_success())print("***登录成功")# 退出self.login.page_click_logout()try:self.assertTrue(self.login.page_is_logout_success())except AssertionError:# 截图self.login.page_get_screenshot()raiseexcept AssertionError:# 截图self.login.page_get_screenshot()raisefinally:self.login.page_click_login_link()else:# 获取登录提示信息result = self.login.page_get_error_info()print("result;",result)sleep(1)#断言try:self.assertIn(result,expect_result)sleep(1)except AssertionError:#截图self.login.page_get_screenshot()raisefinally:# 点击提示框确定按钮self.login.page_click_error_btn_ok()sleep(1)
- 数据文件(login.json)
{"login_01":{"username":"13099999999","pwd":"123456","code":"8888","msg":"账号不存在!","flag":false},"login_02":{"username":"17864307785","pwd":"error","code":"8888","msg":"密码错误!","flag":false},"login_03":{"username":"","pwd":"error","code":"8888","msg":"用户名不能为空!","flag":false},"login_04":{"username":"17864307785","pwd":"","code":"8888","msg":"密码不能为空!","flag":false},"login_05":{"username":"17864307785","pwd":"error","code":"","msg":"验证码不能为空!","flag":false},"login_06":{"username":"17864307785","pwd":"123456","code":"8888","msg":"安全退出","flag":true}
}
- 工具类(read_json.py)
import jsondef read_json(filename):filepath ="../data/"+ filenamewith open(filepath,"r",encoding="utf8") as f:return json.load(f)