python自動化測試

qq_34802511發表於2018-08-07

python自動化測試(3)

自動化框架及工具

1   概述

手續的關於測試的方法論,都是建立在之前的文章裡面提到的觀點:

  • 功能測試不建議做自動化
  • 介面測試價效比最高
  • 介面測試可以做自動化

後面所談到的 測試自動化 也將圍繞著 介面自動化 來介紹。

本系列選擇的測試語言是 python 指令碼語言。由於其官方文件已經對原理有了比較清楚的解釋,本文就不做一些多餘的翻譯工作了。偏向於實戰部分,而且為了偏向實戰,也會結合 IDE 工具和專案組織來進行講解。

理由如下:

  1. 指令碼語言,開發和迭代的效率極高
  2. 第三方的擴充套件庫極多,有很我現成的工具可以使用

在正式進入到 自動化測試 的領域之前,先要建立這樣的價值觀。在Google內部工程師釋出的軟體測試的出版物裡面提到:

“軟體的自動化測試是有成本的,而且成本不低,基本上相當於在原有的 功能開發工程 的基礎上再建立一個平行的 測試開發工程 ”。

也就是說,如果你對自動化測試有你的期望值,那麼就肯定是要付出相應的代價和精力的。好的東西也是需要優秀的人花大量的時間去完成的。

 

本文已經收入合集:《基於python的網際網路軟體測試開發(自動化測試)-全集合》,歡迎訪問的檢視:

基於Python的網際網路軟體測試開發

 

2   PyUnit測試框架

使用 python 作為自動化程式語言,那麼就自然的使用 pyunit 作為自動化測試框架了。

如下部分的內容主要來自於 pyunit 的官方文件,本文僅僅做了一些翻譯和結構上的簡單調整。這部分屬於測試框架的基本原理和概念部分,在進行程式碼編寫前,有必要進行了解。

python的單元測試框架 PyUnit,可以認為是 Java 語言下的單元測試框架 JUnit 的 Python 語言實現版本,甚至其作者之一 Kent Beck 就是 JUnit 的作者。

unittest要達到如下目標:

  • 支援自動化測試
  • 讓所有的測試指令碼共享 開啟(setup) 和 關閉(shutdown) 的程式碼
  • 可以通過集合(collections)的方式來組織測試用例指令碼
  • 將所有的測試指令碼從測試報告框架中獨立出來

為了達到以上目標,unittest支援如下幾個重要概念:

  • 測試裝置(test fixture)

    為一個或者多個測試用例做一些準備工作,例如:連線一個資料庫,建立一個目錄,或者開啟一個程式

  • 測試用例(test case)

    測試用例是測試行為的最小單元,通過對一些輸入輸出值的對比來進行測試檢查

  • 測試套件(test suite)

    將 測試用例 或者 測試用例集合 聚合組織起來的集合。可以批量執行一個測試套件內所有的測試用例

  • 測試執行器(test runner)

    組織安排測試指令碼執行活動的元件。測試執行器通過一些圖形介面,文字介面或者返回一些特殊的值來展示測試指令碼的測試結果。主要用於生成測試報告

3   基本示例

如下示例也來自於官方文件 basic_demo.py

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

# coding:utf-8

"""

基本的自動化測試指令碼 basic_demo.py

"""

__author__ = 'zheng'

 

import unittest

 

 

class TestStringMethods(unittest.TestCase):

 

    def setUp(self):

        print 'init by setUp...'

 

    def tearDown(self):

        print 'end by tearDown...'

 

    def test_upper(self):

        self.assertEqual('foo'.upper(), 'FOO')

 

    def test_isupper(self):

        self.assertTrue('FOO'.isupper())

        self.assertFalse('Foo'.isupper())

        self.assertTrue('Foo'.isupper())

 

    def test_split(self):

        = 'hello world'

        self.assertEqual(s.split(), ['hello''world'])

        # check that s.split fails when the separator is not a string

        with self.assertRaises(TypeError):

            s.split(2)

 

 

if __name__ == '__main__':

    unittest.main()

雖然官方文件裡面介紹了幾種組織測試用例指令碼的方式:

  1. 獨立測試函式
  2. 單用例測試類
  3. 多用例測試類

不同的編寫形態,會有不同的組織方式,具體的可以看官方文件。本文作者研究過官方文件後,最喜歡第三種方式 多用例測試類,也就是上面基本示例的方式,這種方式具有如下特點:

  • 測試類 繼承於 unittest.TestCase
  • 一個測試類可以管理多個 測試指令碼函式
  • 測試指令碼函式名稱需要以 test_ 開頭
  • 一個測試類裡面的所有的測試函式共享 setUp和tearDown函式

在控制檯中執行此程式:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

➜  src git:(master) ✗ python basic_demo.py

init by setUp...

Fend by tearDown...

init by setUp...

end by tearDown...

.init by setUp...

end by tearDown...

.

======================================================================

FAIL: test_isupper (__main__.TestStringMethods)

----------------------------------------------------------------------

Traceback (most recent call last):

  File "basic_demo.py", line 24, in test_isupper

    self.assertTrue('Foo'.isupper())

AssertionError: False is not true

 

----------------------------------------------------------------------

Ran 3 tests in 0.001s

 

FAILED (failures=1)

➜  src git:(master) ✗

前面的基本例子的 main 函式採用的最簡單的方式,直接執行所有的測試用例,並生成預設的文字報告。其實只需要對呼叫函式做一些簡單的修改,可以將這些測試用例進行合理組織,並獲取其實有用的資料資訊,以便和資訊系統進行整合,形成較好的擴充套件。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

if __name__ == '__main__':

    # unittest.main()

    # 裝載測試用例

    test_cases = unittest.TestLoader().loadTestsFromTestCase(TestStringMethods)

    # 使用測試套件並打包測試用例

    test_suit = unittest.TestSuite()

    test_suit.addTests(test_cases)

    # 執行測試套件,並返回測試結果

    test_result = unittest.TextTestRunner(verbosity=2).run(test_suit)

    #生成測試報告

    print("testsRun:%s" % test_result.testsRun)

    print("failures:%s" % len(test_result.failures))

    print("errors:%s" % len(test_result.errors))

    print("skipped:%s" % len(test_result.skipped))

執行後生成的輸出為:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

➜  src git:(master) ✗ python basic_demo.py

test_isupper (__main__.TestStringMethods) ... init by setUp...

FAIL

end by tearDown...

test_split (__main__.TestStringMethods) ... init by setUp...

end by tearDown...

ok

test_upper (__main__.TestStringMethods) ... init by setUp...

end by tearDown...

ok

 

======================================================================

FAIL: test_isupper (__main__.TestStringMethods)

----------------------------------------------------------------------

Traceback (most recent call last):

  File "basic_demo.py", line 23, in test_isupper

    self.assertTrue('Foo'.isupper())

AssertionError: False is not true

 

----------------------------------------------------------------------

Ran 3 tests in 0.001s

 

FAILED (failures=1)

testsRun:3

failures:1

errors:0

skipped:0

顯然上面的輸入結果已經將測試的結果進行了統計,這些資料都是一次測試活動中的重要指標,這些資料可以入庫,和測試資訊管理系統整合,後期生成儀表盤或者統計報表,形成穩定和產品測試線路圖,這些都是和開發相關的了,在此不再多敘述了。

結合上面的具體例子,我們也可以找到上一節的理論部分對應的具體實現物件:

  • 測試裝置(test fixture)

    由setUp函式來做初始化工作,由tearDown做銷燬工作

  • 測試用例(test case)

    對應TestCase類,或者更細化的對應裡面的測試指令碼函式

  • 測試套件(test suite)

    對應TestSuite類

  • 測試執行器(test runner)

    對應TextTestRunner類

4   IDE工具

既然需要開發程式碼的生產力,那麼就需要介紹一款IDE工具-- Pycharm。不可否認,它是目前最專注/專業的 Python 語言的 IDE 了。在對Pyunit 也有比較好的支援。

主要支援如下:

  • 視覺化的程式設計開發(這是IDE的基本特點)

  • 對測試結果進行視覺化的展示

  • 匯出生成HTML的測試報告

  • 視覺化控制用例執行(這個在開發除錯階段很方便,可以方便控制指定程式碼單元執行)

    • 讓一個目錄下的所有用命執行
    • 讓單個檔案內所有用例執行
    • 讓單個檔案內的單個用命執行

4.1   執行和除錯

Pycharm 對測試指令碼提供了靈活的執行和除錯支援。

通過pycharm,開發人員可以不用編寫main函式,就可以實現如下功能:

  • 執行一個檔案下所有的測試類
  • 執行一個測試類的所有測試指令碼
  • 執行一個測試類的某個測試指令碼

其中 "執行一個測試類的某個測試指令碼" 比較有用,適合在開發階段快速地對單個指令碼進行開發和執行除錯。

使用方法:

  1. 將游標移動到測試函式內部
  2. 按下執行快捷鍵 ctrl+shift+F10 (Eclipse快捷鍵方案)

如果要斷點除錯,則使用Debug模式,即可對單個函式執行和斷點除錯了。

當然,也可以不必借用IDE,而通過對testSuit操作,也可以實現以上功能,但是IDE卻提供了更靈活直接的選擇。這只是一些IDE使用技巧,也不多述了。

4.2   結果視覺化

對於前面提到的例子,如果選擇在IDE中執行此程式,會看到如下效果:

可以看到全部執行通過。如果刻意將其中一個弄成不通過的,則會顯示如下的結果:

4.3   生成測試報告

Pycharm也提供了測試結果報告的匯出功能,在測試結果顯示框上的一個功能按鈕上。

 

匯出結果如下:

 

當然,如果不考慮和資訊系統整合,不考慮後續的儀表盤和測試統計工作,僅僅只是要生成報告,這個功能已經足夠了。

一般情況下,做自動化測試和開發,上面的那些那些技能已經完全能夠滿足要求了,接下來要做的事情就是利用各種計算機基本知識,面對不斷增加的業務需求,而不斷地增加測試用例指令碼了。

功能開發專案,原理都很簡單,但是隨著量的增加,都會形成規模,測試開發工程也是一樣。

5   專案組織

之前對測試用例的 開發除錯態 的工具進行了介紹。但是如果真正的要納入到 持續整合 的自動化體系,就顯然不能依賴於 IDE 了。而是使用python 語言的組織和呼叫方式了,比如:要有 __main__ 函式來作為執行入口,等等。

詳細的技術實現細節,在後面有機會,將再會寫相應的文章進行介紹。

通過脫離IDE的專案組織方式,有如下優點:

  • 可以通過事件觸發來執行所有指令碼(能夠成為 持續整合 流水線的一環節)
  • 可以將資料全部提出並進行自定義加工和處理(和測試資訊系統整合,為質量分析系統提供資料來源)

6  測試平臺

關於如何自動化生成測試報告這個測試產物,現在有一些平臺能夠提供介面呼叫及報告展示和分享功能,詳情參考:

http://www.jianshu.com/p/c5fa76cf87db

 

7  小結

本小部分的內容,主要是講基於 python 語言的 自動化測試框架 pyunit的一些設計思想和基本使用示例。其實工具的使用方法很簡單,但是如何利用好這些工具來進行軟體生產,則需要其它的計算機技能了,在後續的文章中將會從工程方面和技術方面來對此框架的應用進行深入的擴充套件。

(未完,待續。。。。)

相關文章