pytest+selenium+allure
#selenium 虚拟环境的名称,python=3.8:python的版本 conda create -n selenium python=3.8 #激活虚拟环境 conda activate selenium
pip install selenium
from selenium import webdriver # Chrome浏览器 driver = webdriver.Chrome()
二、基础用法
1. 对网页进行操作
1.1 访问网页:
from selenium import webdriver # 初始化浏览器为chrome浏览器 browser = webdriver.Chrome() # 访问百度首页 browser.get(r'https://www.baidu.com/') # 关闭浏览器 browser.close()
1.2 设置浏览器的大小:
from selenium import webdriver import time browser = webdriver.Chrome() # 设置浏览器大小:全屏 browser.maximize_window() browser.get('https://www.baidu.com') time.sleep(2) # 设置分辨率 500*500 browser.set_window_size(500,500) time.sleep(2) # 关闭浏览器 browser.close()
2. 页面元素定位
| 属性 | 函数 |
| CLASS | find_element(by=By.CLASS_NAME, value=‘’) |
| XPATH | find_element(by=By.XPATH, value=‘’) |
| LINK_TEXT | find_element(by=By.LINK_TEXT, value=‘’) |
| PARTIAL_LINK_TEXT | find_element(by=By.PARTIAL_LINK_TEXT, value=‘’) |
| TAG | find_element(by=By.TAG_NAME, value=‘’) |
| CSS | find_element(by=By.CSS_SELECTOR, value=‘’) |
| ID | find_element(by=By.ID, value=‘’) |
from selenium import webdriver from selenium.webdriver.common.by import By driver = webdriver.Chrome() driver.get('https://www.baidu.com') element=browser.find_element(by=By.CLASS_NAME,value='s_ipt') element=browser.find_element(by=By.ID,value='kw')
3. 等待
3.1 强制等待:
time.sleep(n)
3.2 隐式等待: 设置等待时间,如果到时间有元素节点没有加载出来,就会抛出异常
implicitly_wait(n)
3.3 显示等待
WebDriverWait(driver,timeout,poll_frequency=0.5,ignored_exceptions=None)
pip install pytest
2. 安装pytest-xdist :pytest-xdist是一个pytest插件,用于并行运行测试。您可以使用以下命令安装:
pip install pytest-xdist
pip install pytest-rerunfailures
pip install pytest-html
pip install allure-pytest
例子: 1. 创建一个名为test_example.py的文件,并编写测试用例。以下是一个示例:
import allure
import pytest
from selenium import webdriver
import time
@allure.testcase("http://www.github.com")
@allure.feature("百度搜索")
@pytest.mark.parametrize('test_data1', ['allure', 'pytest', 'unittest'])
def test_steps_demo(test_data1):
with allure.step("打开百度网页"):
driver = webdriver.Chrome("D:/testing_tools/chromedriver85/chromedriver.exe")
driver.get("http://www.baidu.com")
with allure.step("搜索关键词"):
driver.find_element_by_id("kw").send_keys(test_data1)
time.sleep(2)
driver.find_element_by_id("su").click()
time.sleep(2)
with allure.step("保存图片"):
driver.save_screenshot("./result/b.png")
allure.attach.file("./result/b.png", attachment_type=allure.attachment_type.PNG)
allure.attach('<head></head><body>首页</body>', 'Attach with HTML type', allure.attachment_type.HTML)
with allure.step("退出浏览器"):
driver.quit()
在这个例子中,我们编写了一个名为test_search的测试用例,并使用pytest.mark.parametrize装饰器实现了数据驱动。 2. 运行测试用例 使用以下命令运行测试用例: ``` pytest -n 3 --reruns 2 --html=report.html --alluredir=allure-results ``` 上述命令将运行测试用例,并使用3个进程并行运行测试。如果测试失败,它将重试2次。它还将生成一个HTML测试报告,并将Allure测试报告输出到allure-results目录中。 3. 生成Allure测试报告 使用以下命令生成Allure测试报告: ``` allure serve allure-results
3. allure特性:
3.1 feature, storry, step
在报告中添加用例描述信息,比如测试功能,子功能或场景,测试步骤以及测试附加信息: @allure.feature(‘功能名称’):相当于 testsuite @allure.story(’子功能名称‘):对应这个功能或者模块下的不同场景,相当于 testcase @allure.step('步骤'):测试过程中的每个步骤,放在具体逻辑方法中 allure.step('步骤') 只能以装饰器的形式放在类或者方法上面 with allure.step:可以放在测试用例方法里面 @allure.attach('具体文本信息'):附加信息:数据,文本,图片,视频,网页
import pytest import allure @allure.feature("登录") class TestLogin(): @allure.story("登录成功") def test_login_success(self): print("登录成功") pass @allure.story("密码错误") def test_login_failure(self): with allure.step("输入用户名"): print("输入用户名") with allure.step("输入密码"): print("输入密码") print("点击登录") with allure.step("登录失败"): assert '1' == 1 print("登录失败") pass @allure.story("用户名密码错误") def test_login_failure_a(self): print("用户名或者密码错误,登录失败") pass @allure.feature("注册") class TestRegister(): @allure.story("注册成功") def test_register_success(self): print("测试用例:注册成功") pass @allure.story("注册失败") def test_register_failure(self): with allure.step("输入用户名"): print("输入用户名") with allure.step("输入密码"): print("输入密码") with allure.step("再次输入密码"): print("再次输入密码") print("点击注册") with allure.step("注册失败"): assert 1 + 1 == 2 print("注册失败") pass
3.2 link, issue, testcase
在测试报告中添加链接、bug地址、测试用例地址。 关联bug需要在用例执行时添加参数: --allure-link-pattern=issue:[bug地址]{} 例如:--allure-link-pattern=issue:http://www.bugfree.com/issue/{}
import allure @allure.link("http://www.baidu.com", name="baidu link") def test_with_link(): pass @allure.issue("140","this is a issue") def test_with_issue_link(): pass TEST_CASE_LINK = 'https://github.com' @allure.testcase(TEST_CASE_LINK, 'Test case title') def test_with_testcase_link(): pass
3.3 severity
有时候在上线前,由于时间关系,我们只需要把重要模块测试一遍,在这样的场景下我们怎么实现呢?主要有三种方法: 1.可以使用pytest.mark来标记用例. @pytest.mark.webtest # 添加标签 @pytest.mark.sec pytest -m "webtest and not sec" 2. 通过 allure.feature, allure.story来实现 pytest test_feature_story_step.py --allure-features "登录" //只运行登录模块 pytest test_feature_story_step.py --allure-stories "登录成功" //只运行登录成功子模块 3. 通过 allure.severity按重要性级别来标记,有5种级别: 3.1 Blocker级别:阻塞 3.2 Critical级别:严重 3.3 Normal级别:正常 3.4 Minor级别:不太重要 3.5 Trivial级别:不重要
import allure import pytest def test_with_no_severity_label(): pass @allure.severity(allure.severity_level.TRIVIAL) def test_with_trivial_severity(): pass @allure.severity(allure.severity_level.NORMAL) def test_with_normal_severity(): pass @allure.severity(allure.severity_level.NORMAL) class TestclassWithNormalSeverity(object): def test_inside_the_normalseverity_test_class(self): pass @allure.severity(allure.severity_level.CRITICAL) def test_inside_the_normal_severity_test_class_with_overriding_critical_severity(self): pass
3.4 allure.attach()
在报告中附加文本、图片以及html网页,用来补充测试步骤或测试结果,比如错误截图或者关键步骤的截图。
import allure import pytest def test_attach_text(): allure.attach("纯文本", attachment_type=allure.attachment_type.TEXT) def test_attach_html(): allure.attach("<body>这是一段htmlbody块</body>", "html页面", attachment_type=allure.attachment_type.HTML) def test_attach_photo(): allure.attach.file("test.jpg", name="图片", attachment_tye=allure.attachment_type.JPG)
五、配置文件:conftest.py
conftest.py 的文件名称是固定的, pytest 会自动识别该文件,我们可以理解成一个专门存放 fixture 的配置文件。 一个工程下可以建多个 conftest.py 文件,一般我们都是在工程根目录下设置的 conftest 文件,这样会起到一个全局的作用。 我们也可以在不同的子目录下放 conftest.py ,这样作用范围只能在该层级的子目录下生效。 配置 fixture 注意事项: 1. pytest 会默认读取 conftest.py 里面的所有 fixture。 2. conftest.py 文件名称是固定的,不能改动。 3. conftest.py 只对同一个 package 下的所有测试用例生效。 4. 不同目录可以有自己的 conftest.py,一个项目中可以有多个 conftest.py。 5. 测试用例文件中不需要手动 import conftest.py,pytest 会自动查找。
conftest.py:
import pytest from selenium import webdriver driver = None @pytest.fixture(scope='session', autouse=True) def drivers(request): global driver if driver is None: driver = webdriver.Chrome() driver.maximize_window() def fn(): driver.quit() request.addfinalizer(fn) return driver
test_conftest.py
import pytest def test_steps_demo(drivers): drivers.get("https://www.baidu.com") if __name__ == '__main__': pytest.main(['test_demo.py', '-s'])
六、实现多线程
# -*- coding:utf-8 -*- import allure import pytest from selenium import webdriver import time from selenium.webdriver.chrome.service import Service as ChromeService from webdriver_manager.chrome import ChromeDriverManager from selenium.webdriver.common.by import By service = ChromeService(ChromeDriverManager().install()) MAX_WORKERS = 3 @pytest.fixture(scope="function") def driver(request): service = ChromeService(ChromeDriverManager().install()) d = webdriver.Chrome(service=service) d.implicitly_wait(10) # 隐式等待,让元素有时间加载 yield d d.quit() @pytest.mark.parametrize('test_data1', ['allure', 'pytest', 'unittest']) def test_baidu(test_data1): driver = webdriver.Chrome(service=service) driver.maximize_window() with allure.step("打开百度网页"): driver.get("http://www.baidu.com") with allure.step("搜索关键词"): driver.find_element(by=By.ID,value="kw").send_keys(test_data1) time.sleep(2) driver.find_element(by=By.ID,value="su").click() time.sleep(2) with allure.step("退出浏览器"): driver.quit() def test_qq(): driver = webdriver.Chrome(service=service) driver.maximize_window() driver.get("https://www.qq.com/") time.sleep(2) driver.quit() def test_csdn(): driver = webdriver.Chrome(service=service) driver.maximize_window() driver.get("https://www.csdn.net/") time.sleep(2) driver.quit() def test_163(): driver = webdriver.Chrome(service=service) driver.maximize_window() driver.get("https://music.163.com/") time.sleep(2) driver.quit() def test_vuejs(): driver = webdriver.Chrome(service=service) driver.maximize_window() driver.get("https://cn.vuejs.org/") time.sleep(2) driver.quit() # if __name__ == "__main__": # pytest.main(['-n', str(MAX_WORKERS), '--dist=loadfile']) 在命令行中运行测试: pytest -n 3 test_your_script.py # 这将启动3个并行进程来运行测试
七、使用Selenium Gid实现多线程:
1.下载Selenium Gid,官网地址:https://www.selenium.dev/downloads/
2. 启动hub:java -jar E:/scripts/seagull/selenium-server-4.23.0.jar hub
3. 启动node: java -jar E:/selenium-server-4.23.0.jar node --hub http://192.168.193.160:4444
注:http://192.168.193.160:4444为 hub服务器地址

浙公网安备 33010602011771号