1.conftest.py解釋
conftest.py是pytest框架里面一個很重要的東西,它可以在這個文件里面編寫fixture,而這個fixture的作用就相當於我們unittest框架里面的setup()和teardown(),雖然pytest框架也有setup()和teardown()但是沒必要寫在用例里面,直接寫在conftests.py里面就好了,這樣更靈活,然后pytest框架會自動去找conftest.py這個文件里面的東西。
conftest.py
1 import pytest 2 @pytest.fixture() 3 def login(): 4 print("用例開始執行") 5 yield #如果有返回值,可以在yield后面直接寫返回值就好了,如果有多個直接用(返回值1,返回值2) 6 print("用例執行完成")
2.目錄結構
調用fixture有兩種寫法: 1.裝飾器@pytest.mark.usefixtures("start") ; 2.直接在用例里面調用fixture裝飾的方法當作參數輸入def test_demo(self,start);3.設置fixture參數autouse=True
3.用例傳fixture參數
1.項目跟目錄下面的全局conftest.py
1 import pytest 2 @pytest.fixture() 3 def start(): 4 print("\n全局conftest")
2.test_case_demo/conftest.py 和 test_demo.py
conftest.py 代碼
1 import pytest 2 @pytest.fixture() 3 def start_1(): 4 print("\n局部test_case_demo")
test_demo.py 代碼
1 import pytest
2 class Test_demo(): 3 def test_demo(self,start,start_1): #標記代碼 4 assert 1==1 5 6 if __name__ == '__main__': 7 pytest.main(["-s","-v","test_demo.py"])
運行結果:
3.test_case_demo_2/conftest.py 和 test_demo_2.py
conftest.py 代碼
1 import pytest 2 @pytest.fixture() 3 def start_2(): 4 print("\n局部test_case_demo_2")
test_demo_2.py 代碼
1 import pytest
2 class Test_demo_2(): 3 def test_demo_2(self,start,start_1): #標記代碼 4 assert 1==1
5
6 if __name__ == '__main__': 7 pytest.main(["-s","test_demo_2.py","-v"])
運行結果可以看出,start起到全局作用,test_case_demo目錄下的start_1不管它的運行級別是什么,也只能在test_case_demo下面被調用。
test_demo_2用例不能跨模塊調用test_case_demo模塊下的start_1,所以test_demo_2用例會運行失敗
4.裝飾器usefixtures
fixture有 function(默認選),class,module,session,四個級別
一.只有一個.py用例文件
1)定義為@pytest.fixture(scope="function")
跟目錄下的conftest.py 代碼
1 import pytest 2 @pytest.fixture(scope="function") 3 def start(): 4 print("\n全局conftest") 5
6 @pytest.fixture() 7 def iniv(): 8 print("\n全局iniv")
test_demo.py 代碼
1 import pytest 2 @pytest.mark.usefixtures("start") # 因為他們級別都是function,所以先運行iniv在運行start
3 @pytest.mark.usefixtures("iniv")
4 class Test_demo(): 5 def test_demo(self): 6 assert 1==1
7 def test_demo_1(self): 8 assert 1==1
9
10 if __name__ == '__main__': 11 pytest.main(["-s","-v","test_demo.py"])
運行結果:start和iniv兩個fixture都打印了
2)定義為@pytest.fixture(scope="class")
1 #跟目錄下的conftest.py 代碼
2 import pytest 3 @pytest.fixture(scope="class") #這個是裝飾類 4 def start(): 5 print("\n我是一個裝飾class的start") 6
7 @pytest.fixture(scope="function") #這個是裝飾用例 8 def iniv(): 9 print("\n我是一個裝飾function的iniv")
1 import pytest 2 @pytest.mark.usefixtures("start") 3 @pytest.mark.usefixtures("iniv") 4 class Test_demo(): 5 def test_demo(self): 6 assert 1==1
7 def test_demo_1(self): 8 assert 1==1
9
10 if __name__ == '__main__': 11 pytest.main(["-s","-v","test_demo.py"])
運行結果:他會先運行start的在運行iniv的。因為start只是作用於class級別,而iniv是作用於function級別,所以start只需要執行一次,而iniv會有多少用例就運行多少次
3)定義為@pytest.fixture(scope="module")
1 #跟目錄下的conftest.py 代碼
2 import pytest 3 @pytest.fixture(scope="module") 4 def start(): 5 print("\n我是一個裝飾module的start") 6
7 @pytest.fixture(scope="function") 8 def iniv(): 9 print("\n我是一個裝飾function的iniv")
1 #test_demo.py代碼 2 import pytest 3 @pytest.mark.usefixtures("start") 4 @pytest.mark.usefixtures("iniv") 5 class Test_demo(): 6 def test_demo(self): 7 assert 1==1 8 def test_demo_1(self): 9 assert 1==1
10 @pytest.mark.usefixtures("start") 11 @pytest.mark.usefixtures("iniv") 12 class Test_demo_1(): 13 def test_demo(self): 14 assert 1==1 15 def test_demo_1(self): 16 assert 1==1 17 18 if __name__ == '__main__': 19 pytest.main(["-s","-v","test_demo.py"])
運行結果:他會先運行start的在運行iniv的。因為start只是作用於module級別,而iniv是作用於function級別,雖然我們在test_demo.py里面裝飾了兩次start,但是因為它是裝飾模塊的,並且也只有test_demo.py這個一個模塊,所以start只需要執行一次,而iniv會有多少用例就運行多少次
4)定義為@pytest.fixture(scope="session")
1 #跟目錄下的conftest.py 代碼
2 import pytest 3 @pytest.fixture(scope="session",autouse=True) #居然你是會話級別了,那么直接默認autouse=True就行了,不用調用就自動執行,或者不寫autouse=True,直接在隨便的,py用例文件里面調用以下就行了
4 def start(): 5 print("\n我是一個裝飾session的start") 6
7 @pytest.fixture(scope="function") 8 def iniv(): 9 print("\n我是一個裝飾function的iniv")
1 #test_demo.py代碼
2 import pytest 3 @pytest.mark.usefixtures("iniv") 4 class Test_demo(): 5 def test_demo(self): 6 assert 1==1
7 def test_demo_1(self): 8 assert 1==1
9
10 if __name__ == '__main__': 11 pytest.main(["-s","-v","test_demo.py"])
運行結果:他會先運行start的在運行iniv的。因為start只是作用於session級別,而iniv是作用於function級別,而且我們直接autouse=True,所以不用調用也會執行,而且start只需要執行一次,而iniv會有多少用例就運行多少次
二.多個.py用例文件(這里不展示代碼,自己去實踐吧)
多個.py用例文件,其實運行結果:
1)function級別:有多少用例就運行多少次。
2)class級別:裝飾多少個類上面的,那么一個就運行多少次,例如一個.py用例里面有兩個類,都裝飾了class級別的,那么就運行兩次,如果有兩個.py用例文件都有兩個類,都裝飾了class級別,那么就運行四次。
3)module級別:如果有一個.py用例文件,那么就運行一次module級別,如果有兩個.py用例文件,那么就運行兩次。
4)session級別:不管有多少個.py用例文件,始終就運行一次
5.設置autouse=True (這種不建議,因為你不調用它,它始終就會運行)
fixture默認autouse=False
跟目錄下的conftest.py 代碼
1 import pytest 2 @pytest.fixture(autouse=True) #啟用 3 def start(): 4 print("\n全局conftest") 5
6 @pytest.fixture(autouse=False) #不啟用 7 def iniv(): 8 print("\n全局iniv")
1 import pytest 2 #@pytest.mark.usefixtures("start") 這里注釋掉了
3 class Test_demo(): 4 def test_demo(self): 5 assert 1==1
6 def test_demo_1(self): 7 assert 1==1
8 if __name__ == '__main__': 9 pytest.main(["-s","-v","test_demo.py"])
運行結果:結果還是調用了start