暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

pytest系列——Fixture的使用

迅捷小莫 2021-09-02
604


Pytest

在pytest中,我们怎么去实现unittest中的 setUp,teardown呢?

首先我们要明确一下,这些是做什么用的。在unittest中我们通常分为几个部分,有测试用例(TestCase),测试套件(TestSuite),测试固件(Fixtures), 测试执行器(TestRunner)等。而setUp, tearDown这些方法,就属于Fixtures这部分,也就是测试固件。我们通常利用测试固件去做一些前后置操作 ,比如测试数据准备,登入,测试数据清洗等等。

那么我们pytest中有没有这个测试固件呢?强大的pytest,那必须有呀!本期为大家介绍的是pytest中的测试固件——Fixture,敲黑板,重点重点重点!必须掌握!

01

实现第一个Fixture

首先,定义一个Fixture非常简单,所谓的Fixture,无非就是python中的一个函数而已。但是这个函数必须要被pytest中的一个装饰器装饰,那它就会变成一个Fixture, 如下:

    @pytest.fixture()  # fixture装饰器
    def setup(): # 随意定义一个函数
       print("setup...") # 函数内容
    复制

    没什么问题,现在这个setup就是一个Fixture了。那我们怎么使用呢?通常我们只需要在测试函数中,传入这个setup也就是Fixture的这个函数名即可:

      import pytest  # 导入pytest




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




      def test_pytest(setup):  # 定义测试函数
         print("test_pytest run")




      if __name__ == '__main__':  # 定义主函数
         pytest.main()  # 调用pytest
      复制

      执行结果可以看到:

      在测试函数test_pytest执行前,执行了一次setup函数。这里test_pytest实际上是把setup这个函数传入,优先执行了,那么这里是不是就类似我们unittest中的setUp了呀 。但是,还差一点点。

      在unitttest中,我们所有的测试方法,都会去执行一遍setUp, 但是在上面可以看到,我们必须在测试函数中传入Fixture才行,那有什么办法可以每个测试函数都去自动执行setUp呢?

      那么就要用到fxiture中的autouse参数!

      02

      Fixture的自动执行

          @pytest.fixture中,我们可以传入一个叫autouse的参数并设置为True,这里代表每个测试函数会默认去执行fixture,并且我们测试函数不需要传入setup也可以执行:

        @pytest.fixture(autouse=True) # 传入autouse
        def setup():
           print("setup...")
        复制

        所以代码变成了下面这个样子:

          import pytest  # 导入pytest




          @pytest.fixture(autouse=True)
          def setup():
             print("setup...")




          def test_pytest():  # 定义测试函数
             print("test_pytest run")




          def test_pytest2():  # 定义测试函数2
             print("test_pytest2 run")




          if __name__ == '__main__':  # 定义主函数
             pytest.main()  # 调用pytest
          复制

          我们现在多定义了一个test_pytest2,方便 我们测试。执行结果如下:

          是不是每个测试函数都执行了一遍setup,那就已经满足了我们的需求了,非常的方便。但是现在又会有新的问题,我如果想实现每个测试类前执行一次,或者每个测试模块执行前执行一次,那怎么做呢?这就引申出了,Fixture中的作用域的问题,接着往下看。

          03

          Fixture的作用域

          在@pytest.fixture中有一个scope参数可以帮助我们修改Fixture的作用域,scope支持以下四种作用域,按从大到小依次是:

          1. session (会话)

          2. module (模块)

          3. class (类)

          4. function (函数)

              而fixture默认的scope为function,所以我们不传的时候,对测试函数依然生效。

              我们将scope指定为class,可以实现每个测试类前执行一次:

            import pytest  # 导入pytest




            @pytest.fixture(scope="class", autouse=True)
            def setup():
            print("class setup...")




            class TestPytest:


            def test_pytest(self): # 定义测试函数
            print("test_pytest run")


            def test_pytest2(self): # 定义测试函数
            print("test_pytest2 run")




            if __name__ == '__main__': # 定义主函数
            pytest.main() # 调用pytest
            复制

            执行结果如下:

            这时,我们的setup只在测试类执行前执行了一次,没得问题。

            那么可能有人想问,session和module是怎么用的呢?其实session的话是指pytest的会话,即所有的测试执行开始到结束,只会执行一次的操作。而module指的是,在某个py文件执行前,执行一次,因为在py中,module即py文件。

            04

            Fixture的全局注册

            在上面的讲解中,我们的Fixture都是和测试函数在同一py文件内,那如果我想在另外一个py文件中,也使用我们的Fixture怎么办,这时候就需要把Fixture注册为全局Fixture。

            那么如何把Fixture注册为全局的呢?这里要介绍一个新的pytest文件,叫做conftest.py,这个文件在pytest中被大量使用,用于定义一些Hook相关函数以及注册全局的Fixture函数。

            我们需要在根目录下,新建一个conftest.py:

            然后在这个文件中,我们可以把之前的Fixture代码放入这个文件内:

            只要定义在conftest.py中的Fixture,我们 即视为全局的Fixture,可以在多个py文件中去使用。

            05

            Fixture实现teardown

            在前面我们介绍的都是setup,那利用Fixture能不能实现我们的teardown呢?其实也是非常的简单,代码如下:

              @pytest.fixture(scope="class", autouse=True)
              def setup():
                 print("class setup...") # setup执行
                 yield  # 使用yield分割
                 print("class teardown") # teardown执行
              复制

              这里的yield可以帮助我们来做分割,在yield之前的属于setup,而之后的就是teardown,我们再来看一下执行效果:

              这里可以看到,最后也输出了我们teardown中的内容,非常的方便。

              那么本期的内容就到此结束,其实Fixture里面还有很多东西没有讲到,小提莫就给大家抛砖引玉一下,我们下期再见!

              个人微信号

              ya1kaikai



              文章转载自迅捷小莫,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

              评论