1. 程式人生 > >pycharm中指令碼執行的3種模式(unittest框架、pytest框架、普通模式)

pycharm中指令碼執行的3種模式(unittest框架、pytest框架、普通模式)

背景知識,某次使用HTMLTestRunner的時候,發現一直都無法匯出報告,後來查詢資料發現了一些坑,現在整理一下來龍去脈。

一:pycharm預設的是pytest框架去執行unittest框架的測試用例
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()函式,更不會匯出報告
這裡寫圖片描述

最終通過建立普通模式的執行模式,然後按照如下方式可以執行
這裡寫圖片描述

最終測試報告如下:
這裡寫圖片描述