Selenium之-数据驱动框架
什么是数据驱动呢?就是,数据的改变从而驱动自动化测试的执行,最终引起测试结果的改变,也就是参数的应用化。
这里对于数据驱动测试,总结起来就是,数据驱动绝非读取文件(excel、csv、xml)中数据进行参数的赋值测试,因为采用的这种方式的测试,工作重心反而变成了如何读写文件,而对于自动化测试中关心的执行结果统计、断言结果反而不是那么容易去实现。尤其是测试页面结构发生大的调整时,文件类的字段调整获取也要发生较大的修改,所以文件数据驱动测试也是可以的,但是并不是最优解。
那么什么才是最优的数据驱动测试呢?是的,用单元测试 unittest
结合ddt
库或者pytest
结合@pytest.mark.parametrize
。使用单元测试可以很方便的解决两个问题:
断言。利用单元测试的断言机制,我们可以方便的进行预期结果和实际结果的对比;
数据统计。执行完测试用例后,一共执行了多少条用例,执行成功多少,失败多少,失败的用例错误在哪里?单元测试框架会帮我们统计展示。
目录结构
# 目录结构
│ conftest.py
│ run.py
│ setting.py
│ test_login.py
│
├─common
│ __init__.py
│
├─data
│ login_data.py
│ __init__.py
│
├─pages
│ │ home_page.py
│ │ login_page.py
│ │ __init__.py
│ │
│ └─__pycache__
│ login_page.cpython-39.pyc
│ __init__.cpython-39.pyc
│
├─report
│ 16ece934-b466-44f8-8027-adada24e33fc-container.json
│ 1ad67988-183b-4a12-a221-c73c62dbe91a-container.json
│ 259a4110-af52-49b9-8aaf-fe58c83412dc-container.json
└─
测试数据
login_data.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2022/1/21 20:58
# @Author : shisuiyi
# @File : login_data.py
# @Software: win10 Tensorflow1.13.1 python3.9
data_error = [['123', 'abc', '密码有效长度是6到30个字符'],
['123', '12345678', '用户名或密码无效'],
['188****463', '1234568', '密码错误']]
data_success = [('188****63', '*****205f', '师语'), ]
page类
登录页:login_page.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2022/1/20 20:34
# @Author : shisuiyi
# @File : login_page.py
# @Software: win10 Tensorflow1.13.1 python3.9
from selenium.webdriver.common.by import By
import setting
class LoginPage:
"""登录页面"""
url = setting.host + '/User/login.html'
def __init__(self, driver):
self.driver = driver
def reload(self):
"""刷新"""
self.driver.refresh()
def load(self):
self.driver.get(self.url)
def login(self, *args):
"""登录"""
# 输入用户户名
self.driver.find_element(By.XPATH, '//input[@name="account"]').send_keys(args[0])
# 输入密码
self.driver.find_element(By.XPATH, '//input[@name="pass"]').send_keys(args[1])
# 点击登录
self.driver.find_element(By.XPATH, '//a[@class="btn-btn" and text()="登录"]').click()
def logout(self):
"""退出登录"""
pass
def forget_password(self):
"""忘记密码"""
pass
def get_error_msg(self):
"""获取登录失败的错误信息"""
return self.driver.find_element(By.XPATH, '//p[@class="error-tips"]').text
首页:home_page.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2022/1/21 20:43
# @Author : shisuiyi
# @File : home_page.py
# @Software: win10 Tensorflow1.13.1 python3.9
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.support.wait import WebDriverWait
class HomePage:
def __init__(self, driver):
self.driver = driver
def get_username(self):
"""获取用户名称"""
wait = WebDriverWait(self.driver, timeout=8)
mark = ('xpath', "//img[@class='avatar']")
when = expected_conditions.presence_of_element_located(mark)
el = wait.until(when)
actual = el.get_attribute('alt')
return actual
脚手架conftest
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2022/1/15 14:14
# @Author : shisuiyi
# @File : conftest.py
# @Software: win10 Tensorflow1.13.1 python3.9
import pytest
from selenium import webdriver
def pytest_collection_modifyitems(items):
"""
测试用例收集完成时,将收集到的item的name和nodeid的中文显示在控制台上,
为解决使用 pytest.mark.parametrize 参数化的时候,加 ids 参数用例描述有中文时,
在控制台输出会显示unicode编码,中文不能正常显示。
:return:
"""
for item in items:
item.name = item.name.encode("utf-8").decode("unicode_escape")
print(item.nodeid)
item._nodeid = item.nodeid.encode("utf-8").decode("unicode_escape")
@pytest.fixture(scope='session')
def driver():
# 养成设置隐性
driver = webdriver.Chrome()
driver.implicitly_wait(8)
driver.maximize_window()
yield driver
driver.quit()
测试用例
test_login.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2022/1/13 19:46
# @Author : shisuiyi
# @File : test_login.py
# @Software: win10 Tensorflow1.13.1 python3.9
import pytest
from data.login_data import data_error, data_success
from pages.login_page import LoginPage
from pages.home_page import HomePage
class TestLogin(object):
"""测试登录功能"""
@pytest.mark.parametrize('username,password,expected', data_error, ids=['密码过短', '用户名或密码无效', '密码错误'])
def test_login_error(self, username, password, expected, driver):
login_page = LoginPage(driver)
login_page.load()
login_page.login(username, password)
actual = login_page.get_error_msg()
assert expected in actual
@pytest.mark.parametrize('username,password,expected', data_success, ids=['登录成功'])
def test_login_success(self, username, password, expected, driver):
login_page = LoginPage(driver)
login_page.load()
login_page.login(username, password)
actual = HomePage(driver).get_username()
assert expected == actual
测试结果
============================= test session starts =============================
collecting ... test_login.py::TestLogin::test_login_error[\u5bc6\u7801\u8fc7\u77ed]
test_login.py::TestLogin::test_login_error[\u7528\u6237\u540d\u6216\u5bc6\u7801\u65e0\u6548]
test_login.py::TestLogin::test_login_error[\u5bc6\u7801\u9519\u8bef]
test_login.py::TestLogin::test_login_success[\u767b\u5f55\u6210\u529f]
collected 4 items
test_login.py::TestLogin::test_login_error[密码过短]
test_login.py::TestLogin::test_login_error[用户名或密码无效]
test_login.py::TestLogin::test_login_error[密码错误]
test_login.py::TestLogin::test_login_success[登录成功]
============================== 4 passed in 8.81s ==============================
Process finished with exit code 0
PASSED [ 25%]PASSED [ 50%]PASSED [ 75%]PASSED [100%]
评论