测试用例的参数化

我们之前学到过fixture可以作为参数传入测试用例。除了这种传参方式,我们还有其他的向测试用例传参的方式。

@pytest.mark.parametrize()

我们可以通过@pytest.mark.parametrize() 这个标签向测试用例中传入参数,如果传入的不只是一组参数而是参数列表,那么该测试用例会根据参数的不同执行多次

吃个荔枝:我们在第一个测试方法中定义两个参数,在测试方法上面添加@pytest.mark.parametrize()标签;标签里第一个参数是测试方法定义的参数的字符串,用逗号隔开;第二个参数是由要传入参数组成的元组的列表,即使你只想传入一组参数也需要以元组列表的形式(如果你只想对一个参数进行参数化,那你标签的第二个参数是列表即可)

#test_Pytest.py文件
#coding=utf-8

import pytest

class Test_Pytest():

        @pytest.mark.parametrize("message1,message2",[("我","I"),("你","you"),("他","he")])
        def test_one(self,message1,message2):
                print("test_one方法执行---%s---%s" % (message1,message2) )
                assert 1==1

        def test_two(self):
                print("test_two方法执行" )
                assert "o" in "love"

        def test_three(self):
                print("test_three方法执行" )
                assert 3-2==1

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

运行结果如下图:我们可以看到参数化的测试方法根据不同的参数执行了多次。

pytest一个用例一个脚本吗 pytest用例之间值传递_pytest一个用例一个脚本吗


我们也可以先定义个参数元组的列表,再传入pytest.mark.parametrize标签中,这样使数据分离。

小荔枝:运行结果和上图一样,便不再展示。

#文件名是test_firstFile.py
#coding=utf-8
import pytest
params=[(("我","I")),("你","you"),("他","he")]
class Test_Pytest():

        @pytest.mark.parametrize("message1,message2",params)
        def test_one(self,message1,message2):
                print("test_one方法执行---%s---%s" % (message1,message2) )
                assert 1==1

        def test_two(self):
                print("test_two方法执行" )
                assert "o" in "love"

        def test_three(self):
                print("test_three方法执行" )
                assert 3-2==1

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

在此之上,我们还可以将参数写在文件里,从文件中读取后形成参数元组的列表;再传入标签中。这里不再展示了。

参数组合

我们可以通过分别对每个参数进行参数化看,来实现参数的排列组合。

吃个小荔枝:在第一个测试方法中定义两个参数,先用一个标签对第一个参数进行参数化,再用一个标签对第二个参数进行参数化,以此类推。正如我们刚刚提到的,如果你只想对一个参数进行参数化,那你标签的第二个参数是列表即可。

#文件名是test_firstFile.py
#coding=utf-8

import pytest

class Test_Pytest():

        @pytest.mark.parametrize("message1",["love","hate"])
        @pytest.mark.parametrize("message2",["you","him"])
        def test_one(self,message1,message2):
                print("test_one方法执行---%s---%s" % (message1,message2) )
                assert 1==1

        def test_two(self):
                print("test_two方法执行" )
                assert "o" in "love"

        def test_three(self):
                print("test_three方法执行" )
                assert 3-2==1

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

运行结果如下图:我们可以看到我们的第一个测试方法经过排列组合2*2执行了四次。

pytest一个用例一个脚本吗 pytest用例之间值传递_pytest一个用例一个脚本吗_02

fixtrue参数化的另外一种方式:indirect=True

我们之前学习过,可以通过@pytest.fixture()中的params对固件进行参数化。现在我们来看另一种方式,也是用上面提到的@pytest.mark.parametrize()标签。

看下面的荔枝:固件的定义和之前的一样,记得传request参数,用request.param代替参数;然后在调用固件的测试方法上添加@pytest.mark.parametrize()标签,第一个参数是固件名的字符串,第二个参数是参数列表或参数元组的列表,第三参数是indirect=True:他是标志我们传参对象 是固件而不是测试方法的参数,也就是区别给测试用例参数化

#文件名是test_firstFile.py
#coding=utf-8

import pytest

@pytest.fixture()
def myfixture(request):
    print("执行myfixture固件--%s" % request.param)
    return "你好"

class Test_Pytest():

        @pytest.mark.parametrize("myfixture",["1","2"],indirect=True)
        def test_one(self,myfixture):
                print("test_one方法执行" )
                print (myfixture)
                assert 1==1

        def test_two(self):
                print("test_two方法执行" )
                assert "o" in "love"

        def test_three(self):
                print("test_three方法执行" )
                assert 3-2==1

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

运行结果如下图:我们可以看到我们的测试用例因为固件的参数执行多次,并且打印出来固件的返回值。

pytest一个用例一个脚本吗 pytest用例之间值传递_固件_03


如果你在测试方法中传入多个固件,然后分别对每个固件参数化,这样可以实现固件的排列组合。从而实现测试方法的多次执行。如果你将固件传入方法中作为参数,也就实现了上面提到的参数排列组合。

小荔枝:

#文件名是test_firstFile.py
#coding=utf-8

import pytest

@pytest.fixture()
def myfixture1(request):
    print("执行myfixture固件--%s" % request.param)
    return request.param
@pytest.fixture()
def myfixture2(request):
    print("执行myfixture固件--%s" % request.param)
    return request.param

class Test_Pytest():

        @pytest.mark.parametrize("myfixture1",["1","2"],indirect=True)
        @pytest.mark.parametrize("myfixture2",["一","二"], indirect=True)
        def test_one(self,myfixture1,myfixture2):
                print("test_one方法执行" )
                print (myfixture1,"---",myfixture2)
                assert 1==1

        def test_two(self):
                print("test_two方法执行" )
                assert "o" in "love"

        def test_three(self):
                print("test_three方法执行" )
                assert 3-2==1

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

运行结果图:

pytest一个用例一个脚本吗 pytest用例之间值传递_单元测试_04