【使用pytest重构项目】使用pytest重构unittest项目:解决函数依赖
2023-09-11 14:17:00 时间
前言
一直想学习自动化测试,但是都没行动,业余时间学习零零碎碎并记录20210420。
6、使用pytest重构项目
- pytest框架介绍
- pytest标记
- pytest参数处理
- pytest Fixtrue
- pytest allure生成测试报告
- 使用pytest重构项目
使用pytest重构unittest项目
1、用户登录重构代码
from time import sleep
import pytest
from selenium import webdriver
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
# class TestUserLogin(unittest.TestCase):
class TestUserLogin(object):
@classmethod
# def setUp(cls) -> None:
# 改成setup
def setup(cls):
cls.driver = webdriver.Chrome()
cls.driver.get('http://localhost:8080/jpress/user/login')
cls.driver.maximize_window()
# def __init__(self):
# self.driver = webdriver.Chrome()
# self.driver.get('http://localhost:8080/jpress/user/login')
# # self.driver.maximize_window()
# 测试用户登录,用户名错误
@pytest.mark.skip # 跳过执行
def test1_user_login_userError(self):
# 用户名为空
user = '' #实际正确的是amdin
pwd = 'admin'
expected = '账号不能为空'
# 输入用户名
self.driver.find_element_by_name('user').send_keys(user)
# 输入密码
self.driver.find_element_by_name('pwd').send_keys(pwd)
# 点击登录
self.driver.find_element_by_xpath('/html/body/div/div/div/form/div[3]/div/button').click() #千万别忘记click
# 因为有弹窗所以需要切换到弹窗上,并等待弹窗
WebDriverWait(self.driver, 5).until(EC.alert_is_present())
alert = self.driver.switch_to.alert
# python 的断言
# 获取弹窗上的文字来比较
assert alert.text == expected
sleep(2)
alert.accept()
sleep(2)
# 测试用户登录成功
def test2_user_login_ok(self):
# 用户名为空
user = 'admin'
pwd = 'admin'
expected = '用户中心'
# 输入用户名
self.driver.find_element_by_name('user').clear() # 为了把上面案例输入的值清空
self.driver.find_element_by_name('user').send_keys(user)
# 输入密码
self.driver.find_element_by_name('pwd').clear()
self.driver.find_element_by_name('pwd').send_keys(pwd)
# 点击登录
# self.driver.find_element_by_xpath('/html/body/div/div/div/form/div[3]/div/button').click()
self.driver.find_element_by_css_selector('body > div > div > div > form > div.row > div > button').click()
# 等待标题
WebDriverWait(self.driver, 5).until(EC.title_is(expected))
sleep(3)
#验证 因为没有错误弹窗 所以用到了title断言判断
assert self.driver.title == expected
if __name__ == '__main__':
# unittest.main()
pytest.main(['-sv', 'test_user_login.py'])
运行结果
2、管理员登录重构代码
import os
import unittest
from time import sleep, strftime, localtime
import pytest
from PIL import Image
from selenium import webdriver
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from lib.ShowapiRequest import ShowapiRequest
class TestAdminLogin(object):
@classmethod
def setup(self):
self.driver = webdriver.Chrome()
self.driver.get('http://localhost:8080/jpress/admin/login')
print('尝试管理员登录')
# @pytest.mark.skip() # 跳过执行
# 测试管理员用户登录,验证码错误
# @pytest.mark.skip # 跳过执行
def test1_admin_login_Error(self):
# 用户名为空
user = 'admin' #实际正确的是amdin
pwd = 'admin'
captcha = '123456'
expected = '验证码不正确,请重新输入'
# 输入用户名
self.driver.find_element_by_name('user').send_keys(user)
# 输入密码
self.driver.find_element_by_name('pwd').send_keys(pwd)
# 输入验证码
self.driver.find_element_by_name('captcha').send_keys(captcha)
# 点击登录
self.driver.find_element_by_xpath('//*[@id="form"]/div[4]/div/button').click() #千万别忘记click
# 因为有弹窗所以需要切换到弹窗上,并等待弹窗
WebDriverWait(self.driver, 5).until(EC.alert_is_present())
alert = self.driver.switch_to.alert
# python 的断言
# 获取弹窗上的文字来比较
assert alert.text == expected
sleep(2)
alert.accept()
sleep(2)
# 测试用户登录成功
def test2_admin_login_ok(self):
# 用户名为空
user = 'admin'
pwd = 'admin'
expected = 'Jpress后台'
# 输入用户名
self.driver.find_element_by_name('user').clear() # 为了把上面案例输入的值清空
self.driver.find_element_by_name('user').send_keys(user)
# 输入密码
self.driver.find_element_by_name('pwd').clear()
self.driver.find_element_by_name('pwd').send_keys(pwd)
# 自动识别验证码test_yzmPro
# captcha = util.test_yzmPro() # 不知道为啥直接调用参数还是什么问题,直接把原来写的调用AI库识别复杂验证码拷贝过来调试了
path = '/Users/zhengxiaofang/PycharmProjects_py3/Selenium_project/'
path = os.path.join(path, 'screenshots')
if not os.path.exists(path): # 如果找不到/Users/zhengxiaofang/PycharmProjects_py3/Selenium_project/screenshots就创建
os.mkdir(path)
# 设置要截图的文件名:自定义名称+系统时间命名+后缀.png
picture_name1 = '验证码未切' + strftime('%Y_%m_%d_%H_%M_%S', localtime()) + '.png'
path = os.path.join(path, picture_name1) # 截图1的路径+名称
self.driver.get_screenshot_as_file(path) # 截图保存
print(path)
# 找到验证码坐标,利用pil模块中的抠图方法crop,把图片抠出来,保存为picture_name2
# yzm_img = browser.find_element_by_xpath('//*[@id="captchaimg"]')
yzm_img = self.driver.find_element_by_id("captchaImg")
print(yzm_img.location) # 打印左上角坐标{'x': 547, 'y': 447}
left = yzm_img.location['x']
top = yzm_img.location['y']
width = yzm_img.size['width'] + left
height = yzm_img.size['height'] + top
dpr = self.driver.execute_script(
'return window.devicePixelRatio') # execute_script():执行js,使devicePixelRatio 能够返回当前显示设备的物理像素分辨率与 CSS 像素分辨率的比率
print(dpr)
# # 打开截图1
im = Image.open(path)
# 把图片抠出来,保存为picture_name2
img = im.crop((left * dpr, top * dpr, width * dpr, height * dpr))
picture_name2 = '验证码切图' + strftime('%Y_%m_%d_%H_%M_%S', localtime()) + '.png'
print(picture_name2)
img.save(picture_name2) # 这种方式图片默认是保存到main.py当前路径下
# 这里是复杂验证码获取
r = ShowapiRequest("http://route.showapi.com/184-4", "602469", "cff386bf98294645ab8c1acf2fc2c385") # 密钥和密码用自己的
r.addFilePara("image", picture_name2)
r.addBodyPara("typeId", "34")
r.addBodyPara("convert_to_jpg", "0")
r.addBodyPara("needMorePrecise", "0")
res = r.post()
print(res.text) # 返回信息
# 取showapi_res_body中的result
body = res.json()['showapi_res_body']
print(body)
# 取出验证码
print(body['Result'])
# 完成验证码识别,取出后,进去输入
# 输入验证码
self.driver.find_element_by_name('captcha').clear()
self.driver.find_element_by_name('captcha').send_keys(captcha)
# 点击登录
self.driver.find_element_by_xpath('//*[@id="form"]/div[4]/div/button').click() #千万别忘记click
# 等待标题
WebDriverWait(self.driver, 5).until(EC.title_is(expected))
sleep(3)
#验证 因为没有错误弹窗 所以用到了title断言判断
assert self.driver.title == expected
sleep(2)
if __name__ == '__main__':
pytest.main(['-sv', 'test_admin_login.py'])
命令行,运行结果
3、增加文章和删除文章重构代码
#增加文章和删除文章重构
#增加文章和删除文章,重点是iframe的切入和切出以及弹窗的定位
import unittest
import pytest
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from time import sleep
from testcases.pytest.test_admin_login import TestAdminLogin
class TestArticle(object):
# 先初始化登录
def setup_class(self):
self.login = TestAdminLogin()
# 测试文章分类成功 因为需要依赖登录
@pytest.mark.dependency(depends=['admin_login'], scope="module")
# 测试添加文章
def test_add_ok(self):
title = '我的文章'
content = '我的文章内容'
expected = '保存成功!'
# 点击文章
self.login.driver.find_element_by_xpath('//*[@id="sidebar-menu"]/li[4]/a/span[1]').click()
sleep(1)
# 点击写文章
self.login.driver.find_element_by_xpath('//*[@id="sidebar-menu"]/li[4]/ul/li[2]/a').click()
sleep(1)
# 填写文章标题
self.login.driver.find_element_by_id('article-title').send_keys(title)
frame1 = self.login.driver.find_element_by_xpath('//*[@id="cke_1_contents"]/iframe')
# 切入iframe!!!
self.login.driver.switch_to.frame(frame1)
sleep(1)
self.login.driver.find_element_by_xpath('/html/body').send_keys(content)
# 切出(为了定位发布按钮)!!!
self.login.driver.switch_to.default_content()
# 点击发布按钮
self.login.driver.find_element_by_xpath('//*[@id="form"]/div/div[2]/div[1]/div/button[1]').click()
# 这个是浮窗的定位
loc = (By.CLASS_NAME, 'toast-message')
# 当浮窗出现,取出文本进行比较,
WebDriverWait(self.login.driver, 5).until(EC.visibility_of_element_located(loc))
msg = self.login.driver.find_element(*loc).text
assert msg == expected
# 测试删除单个文章
@pytest.mark.skip
def test_delete_one_article_ok(self):
# 点击文章
self.login.driver.find_element_by_xpath('//*[@id="sidebar-menu"]/li[4]/a/span[1]').click()
sleep(1)
# 点击文章管理
self.login.driver.find_element_by_xpath('//*[@id="sidebar-menu"]/li[4]/ul/li[1]/a]').click()
sleep(1)
# 找到第一个文章的链接。/html/body/div/div/section[3]/div/div/div/div[2]/table/tbody/tr[2]/td[2]/strong/a
link = self.login.driver.find_element_by_xpath(
'/html/body/div/div/section[3]/div/div/div/div[2]/table/tbody/tr[2]/td[2]/strong/a')
# 鼠标移动到这个位置 鼠标键盘的操作
ActionChains(self.login.driver).move_to_element(link).perform()
sleep(1)
# 如何判断删除文章成功:删除后的条数+1等于删除前的条数
# 删除前文章数 统计复选框
article_num = len(self.login.driver.find_elements_by_class_name('jp-actiontr'))
# 删除,鼠标移动到垃圾箱,点击,即回收
del_elem = self.login.driver.find_element_by_xpath(
'/html/body/div/div/section[3]/div/div/div/div[2]/table/tbody/tr[2]/td[2]/div/div/a[3')
del_elem.click()
# 删除后文章数
article_num2 = len(self.login.driver.find_elements_by_class_name('jp-actiontr'))
# 断言删除后的条数+1等于删除前的条数
assert article_num == article_num2 + 1
# 测试删除所有文章
@pytest.mark.skip
def test_delete_all_article_ok(self):
# 点击文章
self.login.driver.find_element_by_xpath('//*[@id="sidebar-menu"]/li[4]/a/span[1]').click()
sleep(1)
# 点击文章管理
self.login.driver.find_element_by_xpath('//*[@id="sidebar-menu"]/li[4]/ul/li[1]/a]').click()
sleep(1)
# 找到全选按钮。
checkbox = self.login.driver.find_element_by_xpath(
'/html/body/div/div/section[3]/div/div/div/div[2]/table/tbody/tr[1]/th[1]/input')
# 点击全选按钮
checkbox.click()
# 点击所有文章,查看为0
self.login.driver.find_element_by_id('batchDel').click()
WebDriverWait(self.login.driver, 5).until(EC.alert_is_present())
alert = self.login.driver.switch_to.alert
alert.accept()
sleep(1)
运行结果:
“永不放弃,总有希望在前面等待!”送给自己,也送给正在阅读文章的博友们~
相关文章
- pytest + allure + jenkins 生成漂亮的测试报告
- Python单元测试框架之pytest -- fixtures
- pytest
- pytest接口自动化测试框架 | 自定义@pytest.mark.skip()标签
- pytest接口自动化测试框架 | 跳过测试函数
- pytest接口自动化测试框架 | fixture之params参数化
- pytest接口自动化测试框架 | pytest配置文件
- pytest接口自动化测试框架 | 基于Pytest的Web UI自动化测试框架介绍
- Python+Pytest+Allure+Git+Jenkins接口自动化框架
- python自动化测试学习-Python测试框架之unittest和pytest
- Pytest自动化测试使用pytest.ini实现环境变量控制
- Pytest自动化测试框架-教程23-不稳定测试用例
- Pytest自动化测试框架-权威教程09-捕获标准输出及标准错误输出
- Pytest测试框架基本使用方法详解
- 5分钟快速上手 pytest 测试框架
- pytest 参数化
- Pytest----通过fixture实现参数化时如何对指定某个参数使用skip标记
- Pytest----如何跳过导入模块失败的情况
- Pytest----如何执行未安装的本地包中的测试脚本
- pytest用例跳过