python自動化測試面試題「python測試代碼怎麼寫」

Python 對於測試非常看重,例如測試中最常見的操作——斷言 assert,其在 Python 中就是一個關鍵字而不是一個函數。而在 C 語言中,assert 只是一個普通的函數。從這點也可以看出,Python 將測試當作最基礎的部分。
可以通過使用下面的代碼來查看 Python 語言定義的關鍵字:

>>> import keyword                                     # 引入模塊keyword
>>> keyword.kwlist                                     # 得到所有的關鍵字
# 關鍵字列表
['False', 'None', 'True', 'and', 'as', 'assert', 'async', 'await',
'break', 'class', 'continue', 'def', 'del', 'elif', 'else',
'except', 'finally', 'for', 'from', 'global', 'if', 'import',
'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass',
'raise', 'return', 'try', 'while', 'with', 'yield']

可以直接是使用 assert 在源代碼中對其進行測試,常用的做法如圖 1 所示。Python assert實現軟件測試

圖 1 將測試代碼和實現功能放入同一個文件

下面看一個簡單的例子,假定自定義了一個模塊 sampleAssert,其代碼如下:

def int_list_sort(input_list):          # 被測對象,完成對輸入的整數列表排序
    input_list.sort()                   # 完成排序
if __name__ == "__main__":                      # 判斷條件,裏面的內容是用來測試的
    def test_normal_positive_input():                   # 定義一個測試用例
        input_list = [3, 5, 9, 1, 8]
        int_list_sort(input_list)
        assert input_list == [1, 3, 5, 8, 9]
        print("test_normal_positive_input: PASS")
    test_normal_positive_input()                         # 執行測試用例

如果我們是 import(引入)該模塊,case 是不會執行的,即第 3 行開始的塊是不會執行的,所以包含在該塊內的測試用例定義不會被看到,測試用例也不會被執行。

$ python                                       # 啟動解釋器,Python 3
Python 3.7.3 (default, Mar 27 2019, 16:54:48)
[Clang 4.0.1 (tags/RELEASE_401/final)] :: Anaconda, Inc. on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import sampleAssert                        # 引入我們剛才定義的模塊
>>> sampleAssert.test_normal_positive_input()  # 測試函數是不可見的
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: module 'sampleAssert' has no attribute 'test_normal_
        positive_input'
>>> list_obj = [3, 1, 6, 100, 98, 9]
>>> sampleAssert.int_list_sort(list_obj)         # 被測對象是可見的
>>> list_obj
[1, 3, 6, 9, 98, 100]                            # 排序後的結果

如果是直接運行該腳本,則測試用例就會被觸發。

$ python sampleAssert.py
test_normal_positive_input: PASS

下面我們來實現一個冒泡排序法,其僅對整數列表有效。冒泡排序法是最簡單的排序法,其通過交換相鄰的元素來實現排序。下面以對包含 4 個元素 3、1、5、2 的列表進行排序為例來解釋這個過程,如圖 2 所示。Python assert實現軟件測試

圖 2 冒泡排序

首先從尾部,也就是下部依次查找不符合排列要求的相鄰兩個數,第一次找到的是 5 和 2,交換它們,然後繼續查找得到 3 和 1 這兩個不符合要求的相鄰數,交換它們。通過這一輪的交換,最小的數交換到了第一個元素。然後繼續其他記錄的排序,第二輪可以保證第二小的數排到第二個位置上。以此類推,最多經過 n-1 輪就可以完成所有數據的排序。

在這個例子中,經過了兩輪就完成了所有數據的排序。

下面是完整的實現代碼和相關測試代碼:

def bubble_sort(input_list):                    # 被測函數,冒泡排序
    if type(input_list) is not type([]):        # 如果輸入參數不符合要求
        print("Invalid Input Type")
        return None
    for x in input_list:                                # 有元素不是整數,返回None
        if type(x) != int:
            return None
    input_len = len(input_list)
    print()
    print("Origin:", input_list)
    if input_len <= 1:                               # 沒有元素或者僅包含一個元素
        return input_list
    for x in range(input_len-1):                # 如果順序不對,和旁邊的元素交換
        swap_happens = False
        for y in range(input_len-1, x, -1):
            if input_list[y-1] > input_list[y]:
                input_list[y-1], input_list[y] = input_list[y], input_
                        list[y-1]
                swap_happens = True
        if swap_happens == False:               # 上一輪沒有交換數據,已經排序完畢
            break
        print("Temp %d:" % x, input_list)
    return input_list                                   # 返回排序完畢的列表
if __name__ == "__main__":                              # 如果是運行該腳本而不是引入該腳本
    import random                                               # 測試代碼開始
    def test_empty_input():                             # 如果輸入的列表為空
        input = []
        output = bubble_sort(input)
        assert type(output) == type([])
        assert len(output) == 0
    def test_invalid_input():                   # 如果輸入的不是列表
        output = bubble_sort(1)
        assert output is None
    def test_one_element():                     # 如果列表僅包含一個元素
        input = [1, ]
        output = bubble_sort(input)
      assert type(output) == type([])
      assert len(output) == 1
      assert output[0] == 1
    def test_neg_one_element():         # 如果列表僅包含一個元素,而且不是整數
      input = ["name", ]
       output = bubble_sort(input)
       assert output is None
    def test_two_element():                     # 如果列表僅包含兩個元素
       input = [18, 8]
        output = bubble_sort(input)
        assert type(output) == type([])
        assert len(output) == 2
        assert output[0] == 8
        assert output[1] == 18
    def test_neg_two_element():         # 如果列表包含兩個元素,但並不都是整數
        input = [1, "name"]
        output = bubble_sort(input)
        assert output is None
    def test_normal_pos():                              # 正常輸入
        input = [88, 1, 20, 8, 9, 21, 98, 76]
        output = bubble_sort(input)
        expected_output = [1, 8, 9, 20, 21, 76, 88, 98]
        assert output == expected_output
    def test_dup_elements():                    # 如果有重複的元素
        input = [88, 1, 20, 8, 9, 21, 98, 8, 76]        # 兩個8
        print("input:", input)
        output = bubble_sort(input)
        print("outpout:", output)
        expected_output = [1, 8, 8, 9, 20, 21, 76, 88, 98]
        assert output == expected_output
    def test_all_same():                                # 如果所有元素都相等
        input = [8, 8, 8, 8, 8, 8]              # 所有的輸入元素相同
        output = bubble_sort(input)
        expected_output = [8, 8, 8, 8, 8, 8]
        assert output == expected_output
    def random_test():                                  # 隨機生成測試數據
        # 生成隨機的輸入數據
        expected_list_len = random.randint(10, 100)
        input_list = []
        for x in range(expected_list_len):
            input_list.append(random.randint(-100, 100))
        input_len = len(input_list)
        org_input = input_list.copy()           # 備份一下元素數據
        output = bubble_sort(input_list)
        print("org_input", org_input)
        #input_len = len(org_input)
        assert len(output) == expected_list_len
        for pos in range(input_len-1):
            val = output[pos]
            # 該數據在原始列表中存在
            # 這樣可以確保所有結果列表中的數據都是來自輸入列表
            assert val in org_input
            # 而且其出現的次數和元素列表中出現的次數一致
            # 這可保證輸入列表中的數據不會丟失
            assert output.count(val) == org_input.count(val)
            # 保證有序,從小到大
            assert val <= output[pos+1]
    def test_random_data():                             # 隨機輸入測試
        # 進行100輪隨機輸入的測試
        for x in range(100):
            random_test()
    # 執行所有的測試
    test_empty_input()
    test_invalid_input()
    test_one_element()
    test_neg_one_element()
    test_two_element()
    test_neg_two_element()
    test_normal_pos()
    test_dup_elements()
    test_all_same()
    test_random_data()

可以發現測試代碼的長度比被測代碼的長度還要長,這是軟件測試中,尤其是功能測試部分常見的現象。另外一個現象是對於針對特殊使用場景的測試用例數量比較大。多數情況下,問題不會隱藏在常用的使用場景,而多隱藏在這些不常見的使用場景中,所以針對這些特殊使用場景的測試用例的設計需要多下功夫。

原創文章,作者:投稿專員,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/201884.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
投稿專員的頭像投稿專員
上一篇 2024-12-06 14:01
下一篇 2024-12-06 14:01

相關推薦

發表回復

登錄後才能評論