关于pytest的一些问题

1|0一. 测试模块内部使用fixture和测试模块调用外部公共的fixture


1|11. unittest框架下的测试用例模块


from selenium import webdriver import unittest from PageObjects.login_page import LoginPage from PageObjects.index_page import IndexPage from TestDatas.login_testdatas import * from TestDatas.CommonData import * import time class TestLogin(unittest.TestCase): def setUp(self): self.driver = webdriver.Chrome() self.driver.get(common_url) self.driver.maximize_window() #用户名密码正确 def test_login_success(self): LoginPage(self.driver).login(login_success_data["username"], login_success_data["passwd"]) nickName = IndexPage(self.driver).get_nickName() self.assertEqual("我的帐户[小蜜蜂96027]", nickName) def tearDown(self): time.sleep(2) self.driver.quit()

1|22. 测试用例模块内部使用fixture


fixture:即测试用例执行的环境准备和清理,在unittest中即指setup()、teardown()

from selenium import webdriver import unittest from PageObjects.login_page import LoginPage from PageObjects.index_page import IndexPage from TestDatas.login_testdatas import * from TestDatas.CommonData import * import time import pytest class TestLogin: @pytest.fixture def init_driver(self): self.driver = webdriver.Chrome() self.driver.get(common_url) self.driver.maximize_window() yield self.driver time.sleep(2) self.driver.quit() #用户名密码正确 def test_login_success(self, init_driver): LoginPage(init_driver).login(login_success_data["username"], login_success_data["passwd"]) nickName = IndexPage(init_driver).get_nickName() assert "我的帐户[小蜜蜂96027]" == nickName

1|33. 测试用例模块调用外部公共的fixture


有时,多个测试用例模块要使用同一fixture,如果在每个模块内部都定义一遍fixture则略显麻烦,pytest提供了conftest.py文件,用来定义公共的fixture,多个测试模块都可以调用,运行测试用例时,不需要导入这个文件,它会自动查找conftest.py文件,然后去找到对应的fixture

在测试用例模块的同级目录下创建一个conftest.py文件

from selenium import webdriver from TestDatas.CommonData import * import pytest import time @pytest.fixture def init_driver(): driver = webdriver.Chrome() driver.get(common_url) driver.maximize_window() yield driver time.sleep(2) driver.quit()

测试用例模块test_login.py调用外部公共的fixture

from selenium import webdriver import unittest from PageObjects.login_page import LoginPage from PageObjects.index_page import IndexPage from TestDatas.login_testdatas import * from TestDatas.CommonData import * import time import pytest class TestLogin: #用户名密码正确 @pytest.mark.usefixtures("init_driver") def test_login_success(self, init_driver): LoginPage(init_driver).login(login_success_data["username"], login_success_data["passwd"]) nickName = IndexPage(init_driver).get_nickName() assert "我的帐户[小蜜蜂96027]" == nickName

1|44. 比较


pytest和unittest相比:

1. 需要import pytest

2. 不再需要unittest.TestCase

3. 如果在内部使用fixture,则函数只需要传参,参数为被@pytest.fixture装饰的函数名init_driver(init_driver=init_driver());如果调用外部公共的fixture,除了传参之外,还要在测试用例类或函数前面加上一句:@pytest.mark.usefixtures("init_driver")

4. fixture函数中以yield分割环境准备和环境清理,且需要返回self.driver或driver

5. 断言方式有所改变,unittest采用self.assertEqual或其他,pytest采用assert 表达式

2|0二. 装饰器函数fixture的作用域默认是function,且autouse=False


@pytest.fixture中的fixture函数源码如下

四大作用域:

function:每个test都运行,默认是function的scope,即unittest中的setUp和tearDown

class:每个class的所有test只运行一次。即unittest中的setUpClass和tearDownClass

module:每个module的所有test只运行一次(分类里和类外)

session:每个session只运行一次(如连接数据库操作)

值得注意的是默认的autouse=False,所以函数需要使用对应的fixture时,需要添加@pytest.mark.usefixtures("init_driver"),并且将被fixture装饰的函数名init_driver作为参数,传给测试用例函数,如果autouse=True,那么会自动给每个测试用例添加fixture,而init_driver这样的环境准备和清理工作并非每个测试用例都需要,所以autouse一般采用默认值False

3|0三. pytest收集测试用例的规则


1. 默认从当前目录中搜集测试用例,即在哪个目录下运行pytest命令,则从哪个目录当中搜索

2. 搜索规则:

  1) 符合命令规则test_*.py 或者 *_test.py 的文件

  2) 以test_开头的函数名

  3) 以Test开头的测试类 (没有__init__函数) 当中,以test_开头的函数

当前目录下(D:\python_workshop\WEB_framework)有两个测试用例模块,test_login.py和test_invest.py,前者测试用例类TestLogin中有四个测试用例,另外还在测试用例类外添加了一个test_demo函数,后者有四个测试用例,这九个测试用例中我只在用户名为空的用例上打了smoke标记

在调用pytest -m smoke运行时,发现9条用例被找到了,但8条没有被选择,只选择了打了标记的

 

 

 

 

4|0参考文章


http://www.cnblogs.com/cnhkzyy/p/9270830.html

 


__EOF__

本文作者cnhkzyy
本文链接https://www.cnblogs.com/my_captain/p/9384839.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   cnhkzyy  阅读(1262)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示