pycharm中指令碼執行的3種模式(unittest框架、pytest框架、普通模式)
一:pycharm預設的是pytest框架去執行unittest框架的測試用例背景知識,某次使用HTMLTestRunner的時候,發現一直都無法匯出報告,後來查詢資料發現了一些坑,現在整理一下來龍去脈。
import unittest
class AlienTest(unittest.TestCase):
@classmethod
def setUpClass(cls):
print("TestCase start running ")
def test_1_run(self):
print("hello world_1" )
def test_2_run(self):
print("hello world_2")
def test_3_run(self):
print("hello world_3")
如上的程式碼,如果第一次執行,是不會列印任何資料的,最終輸出框的程式碼如下:
============================= test session starts ==============================
platform darwin -- Python 3.6.3, pytest-3.3.1, py-1.5.2, pluggy-0.6 .0
rootdir: /Users/test/The_Order_Of_TestCase/TestCase, inifile:
collected 3 items
Alien_Test.py TestCase start running
.hello world_1
.hello world_2
.hello world_3 [100%]
=========================== 3 passed in 0.13 seconds ===========================
通過以上資訊,正常列印了,但是通過pytest-3.3.1這個框架去執行的測試用例
現在我們新增3行程式碼,新增main函式試試
import unittest
class AlienTest(unittest.TestCase):
@classmethod
def setUpClass(cls):
print("TestCase start running ")
def test_1_run(self):
print("hello world_1")
def test_2_run(self):
print("hello world_2")
def test_3_run(self):
print("hello world_3")
if __name__ == '__main__':
print("hello world")
unittest.main()
如上程式碼,我們點選main函式這一行去執行指令碼,執行過程如下
最終我們會發現,結果和第一個步驟是一樣的,由此我們得出結論:
- (1)使用pytest測試框架時候,不需要main()函式,系統可以自動識別測試用例並執行。
- (2)即使包含main()函式,點選它去執行,也不會去執行main()函式。
- (3)具體是使用哪個測試框架執行,不是通過main()函式設定的,在別的地方。
而此時,pycharm右上角的執行框如下所示:
二:python執行指令碼的三種模式
通過查閱資料才發現,原來python的執行指令碼的方式有多種:
- 例如普通模式執行,不會自動去載入測試用例執行
- unittest 測試框架執行模式,可以自動去發現testcase並執行
- pytest 測試框架執行模式,就是我們上面2個步驟都是使用pytest測試框架執行的
- 重要原則:第一次按照何種模式執行測試用例,後續都會按照這種方式去執行
因為如上2步,我們都是按照pytest模式去執行的,即使新增的main()函式,最終預設的執行方式都是pytest模式。
三:如何修改指令碼執行的模式呢?
方法一:修改pycharm預設的測試框架
具體步驟如下:
- (1)這種方式修改完之後,如果某個檔案是第一次執行,那預設執行的測試框架是系統預設的框架
- (2)如果某個檔案已經通過其他模式運行了,即使更改了系統預設測試框架,也還是按照第一次執行的模式去執行。
方法二:設定運動指令碼時候的預設框架
入口一:選單欄Run—->Run—->Edit Configuration
入口二:右上角執行按鈕旁邊—>Edit Configurations
通過以上2種入口,進入設定頁面如下所示:
上圖中,左邊的方框執行的內容在Python tests欄目下面,說明指令碼已經使用pytest測試框架運行了,但我們系統TestCase是通過Unittest框架執行的
我們需要新增unittest框架的執行模式去執行指令碼,具體步驟如下:
最終效果如下:
此時,我們再去執行指令碼(點選main()執行或者點選右上角按鈕執行結果是一樣的)
結果如下:
TestCase start running hello world_1
hello world_2
hello world_3
- 如上的結果說明呼叫的unittest框架去執行,但是沒有呼叫main()函式。
- 如果單純為了執行測試用例,不用寫main()函式也可以
四:main()函式有啥作用,難道就沒點價值嗎?
場景一:執行單個測試用例(刪除下圖右上角指令碼執行的記錄了)
結果如下:
TestCase start running
hello world_2
說明只執行了一個測試用例,test_2_run
場景二:執行所有測試用例(刪除下圖右上角指令碼執行的記錄了)
最終結果如下:
TestCase start running
hello world_1
hello world_2
hello world_3
執行所有測試用例的方法:
其實只要不點選單個測試用例的定義函式的行,無論點選哪一行,即使點選main()函式一行,或者空白行,都可以執行所有測試用例
如果程式碼比較多的情況加,我們又想盡快執行所有的測試用例,點選main()函式可以執行所以的測試用例,不會出錯,目前能想到的就這些……
五:普通模式執行測試用例(刪除下圖右上角指令碼執行的記錄了)
結果:
hello world
TestCase start running
hello world_1
hello world_2
hello world_3
- 使用普通模式執行,系統會執行main()函式裡面所有的函式,包括非TestCase的函式,當main()函式中有測試報告的需要匯出的時候,需要使用普通模式執行。
- 使用pytest或unittest測試框架,在main函式中只執行TestCase函式,其他函式不執行。
六:普通執行模式,匯出測試報告
import unittest
import time,HTMLTestRunner
class AlienTest(unittest.TestCase):
@classmethod
def setUpClass(cls):
print("TestCase start running ")
def test_1_run(self):
print("hello world_1")
def test_2_run(self):
print("hello world_2")
def test_3_run(self):
print("hello world_3")
if __name__ == '__main__':
print('hello world')
suite = unittest.makeSuite(AlienTest)
now = time.strftime("%Y-%m-%d %H_%M_%S", time.localtime())
filename = "/Users/test/The_Order_Of_TestCase/Report/" + now + "_result.html"
fp = open(filename, 'wb')
runner = HTMLTestRunner.HTMLTestRunner(
stream=fp,
title=u'ALIEN測試報告',
description=u'ALIEN用例執行情況:')
runner.run(suite)
# 關閉檔案流,不關的話生成的報告是空的
fp.close()
預設是使用unittest模式執行的,結果如下,其實這樣不會執行main()函式,更不會匯出報告
最終通過建立普通模式的執行模式,然後按照如下方式可以執行
最終測試報告如下: