Python学习笔记|python之pytest

系统 1538 0

Pytest

1.安装

  • 首先使用pip3 install pytest安装pytest
  • pytest --version查看版本

1.编写规则

  • 测试文件以 test_ 开头或以_test结尾也可以
  • 测试函数以 test_ 开头
  • 测试类以 Test 开头,并不能有 __init__ 方法

例如: test_pydemo.py 文件

            
              def  test_add():
    print("I am 1")
    assert add.add_test(1,3)==4
    print("I am 2")
    assert add.add_test(1, 2) == 6
    print("I am 3")
    assert add.add_test(1, 5) == 6


            
          

2.pytest用法

安装第三方插件,可以使用 pip install 安装或者 pycharm 中安装,使用的时候导入 import pytest

在pycharm中,files-》settings-》tools=》python integrated tools=》设定default test runner

2.1 pytest-参数化

使用 pip install pytest-parametrize 安装

  • pytest.mark.parametrize (参数名,参数化元组的数组)

代码如下:

            
              import pytest

@pytest.mark.parametrize("x,y",[
    (3+5, 8),
    (2+4, 6),
    (6*9, 42),
])

def test_add_by_para(x,y):
    assert add.add_test(x,y)==x+y

            
          

2.2 pytest-assume

  • 多个assert
            
              import pytest
def  test_add():
    print("I am 1")
    assert add.add_test(1,3)==4
    print("I am 2")
    assert add.add_test(1, 2) == 6
    print("I am 3")
    assert add.add_test(1, 5) == 6


            
          
  • pytest-assume

多个assert语句,当出现错误的时候,不会继续往下执行,如果继续执行,使用pytest-assume插件

            
              import pytest

def  test_add():
    print("I am 1")
    pytest.assume(add.add_test(1,3)==4)
    print("I am 2")
    pytest.assume(add.add_test(1, 2) == 5)
    print("I am 3")
    pytest.assume(add.add_test(1, 7) == 8)


            
          

2.3 pytest-rerunfails

当出错误时,会重复执行,run次数可以设置,pytest --reruns 5

2.4 pytest-ordering

按照order顺序执行

            
              import pytest

@pytest.mark.run(order=2)
def test_add_order():
    print("i am 2")
    assert add.add_test(4,4)==8

@pytest.mark.run(order=1)
def test_add_order1():
    print("i am 1")
    assert add.add_test(6,4)==10


            
          

2.5 pytest-sugar

pytest-sugar改变了pytest的默认外观,增加了一个进度条,并立即显示失败的测试

2.6 pytest-cov

pytest-cov增加了对pytest的覆盖支持,以显示哪些代码行已经测试,哪些没有。它还将包括项目的测试覆盖率。

3.pytest高级用法

测试用例的执行之前而初始化一些数据及方法,相当于Unittest中的setUp,tearDown

3.1 fixture参数

fixture默认参数为function级别的,function:每一个函数或方法都会调用

            
              import pytest

@pytest.fixture()
def loginlogout():
    print("Before")
    yield
    print("After")

class TestFixture():
    def test_fixture(self,loginlogout):
        assert add.add_test(2,3)==5
    def test_fixture2(self,loginlogout):
        assert add.add_test(5,3)==8

class TestFixture1():
    def test_fixture3(self,loginlogout):
        assert add.add_test(2,3)==5
    def test_fixture4(self,loginlogout):
        assert add.add_test(5,3)==8
        

            
          

以上结果执行4次loginlogout,默认为function级别,即:每个函数或方法执行一次

3.2 fixture的scope用法

使用scope设置级别,scope有以下级别:

  • function:每一个函数或方法都会调用

  • class:每一个类调用一次,一个类可以有多个方法

  • module:每一个.py文件调用一次,该文件内又有多个function和class

  • session:是多个文件调用一次,可以跨.py文件调用,每个.py文件就是module

3.2.1 funtion级别

作用范围是每个测试用例来之前运行一次

            
              test_confest.py

@pytest.fixture()
def conftest():
    print("conftest")

def test_confest1(conftest):
    print("conftest1")
    assert 1==1

def test_confest2(conftest):
    print("conftest2")
    assert 2==2

def test_confest3():
    assert 2 == 2

if __name__ == "__main__":
    pytest.main(["-s", "test_confest.py"])


            
          

以上结果,打印了两个conftest,原因是两个方法设置了fixture,默认为function

            
              test_confest.py conftest
.conftest1
conftest
.conftest2

            
          

3.2.2 class级别

如果一个class里面有多个用例,都调用了此fixture,那么此fixture只在该class里所有用例开始前执行一次

            
              test_confest.py

@pytest.fixture(scope="class")
def conftest():
    print("conftest")

class TestConftest():
    def test_confest1(self,conftest):
        print("conftest1")
        assert 1==1

    def test_confest2(self,conftest):
        print("conftest2")
        assert 2==2

    def test_confest3(self,conftest):
        assert 2==2

if __name__ == "__main__":
    pytest.main(["-s", "test_confest.py"])

            
          

以上结果为执行一次confest,原因是scope设置为class,而其中只有一个class,故只有一个confest

3.2.3 module级别

当前.py脚本里面所有用例开始前只执行一次

            
              @pytest.fixture(scope="module")
def conftest():
    print("conftest")

def test_confest1(conftest):
    print("conftest1")
    assert 1==1

class TestConftest():
    def test_confest2(self,conftest):
        print("conftest2")
        assert 1==1

if __name__ == "__main__":
    pytest.main(["-s", "test_confest.py"])


            
          

测试结果:

            
              test_confest.py conftest
.conftest1
.conftest2

            
          

3.2.4 session级别

fixture为session级别是可以跨.py模块调用的,也就是当我们有多个.py文件的用例时候,如果多个用例只需调用一次fixture,那就可以设置为scope=“session”,并且写到conftest.py文件里

            
              conftest.py

import pytest

@pytest.fixture(scope="session")
def first():
    print("session级别,每一个py文件执行一次")
    return 2



            
          
            
              test_conftest1.py

import pytest
def test_conftest1(first):
    '''用例传fixture'''
    print("test_conftest1=%d" % first)
    assert 1 == 1

if __name__ == "__main__":
    pytest.main(["-s", "test_conftest1.py"])


            
          
            
              test_conftest2.py

import pytest
def test_conftest_demo1(first):
    '''用例传fixture'''
    print("test_conftest_demo1=%d" % first)
    assert 1 == 1

def test_conftest_demo2(first):
    '''用例传fixture'''
    print("test_conftest2_demo2=%d" % first)
    assert 1 == 1

if __name__ == "__main__":
    pytest.main(["-s", "test_conftest2.py"])

            
          

结果如下:

            
              test_conftest1.py session级别,每一个py文件执行一次
.test_conftest1=2

            
          
            
              test_conftest2.py session级别,每一个py文件执行一次
.test_conftest_demo1=2
.test_conftest2_demo2=2

            
          

3.2.5 conftest

conftest.py文件名称是固定的,pytest会自动识别该文件。放到工程的根目录下,就可以全局调用了,如果放到某个package包下,那就只在该package内有效

3.3 fixture的usefixtures用法

将定义在函数里面的放在外面,使用usefixtures

            
              import pytest

@pytest.fixture(scope="class")
def loginlogout():
    print("Before")
    yield
    print("After")

class TestFixture():
    @pytest.mark.usefixtures("loginlogout")
    def test_fixture(self):
        assert add.add_test(2,3)==5

    @pytest.mark.usefixtures("loginlogout")
    def test_fixture2(self):
        assert add.add_test(5,3)==8

            
          

3.4 fixture的autouse用法

使用autouse设置是否自动使用fixtures

            
              import pytest

pytest.fixture(scope="class",autouse=True)
def loginlWogout():
    print("Before")
    yield
    print("After")

class TestFixture():
    def test_fixture(self):
        assert add.add_test(2,3)==5

    def test_fixture2(self):
        assert add.add_test(5,3)==8


            
          

更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论