自動化測試---被玩壞的數據驅動

最近在整理接口測試相關的資料,因此,看到有關資料就會多看兩眼。偶看到別人發的微信公衆號。html

Python接口測試框第一篇  --- python如何讀取txt文件。python

Python接口測試框第三篇  --- python如何讀取XML文件。web

Python接口測試框第四篇  --- python如何讀取CSV文件。數組

 

曾幾什麼時候,也許某大牛說,搞自動化必需要把測試數據放文件裏,而後經過程序讀取文件。因而,你們紛紛效仿。瀏覽器

什麼?你作自動化測試竟然不讀取測試數據文件,一看就是新手,沒逼格。微信

小王啊!咱們這個自動化框架必定得作數據與代碼分離,得讀取文件啊!app

在這個全民微信的年代,各位大牛開了公從號,傳授你們自動化測試技術,教點啥呢?那咱們就從讀取數據文件開始起吧!框架

 

 

什麼是數據驅動?工具

從它的本意來解釋,就是數據的改變從而驅動自動化測試的執行,最終引發測試結果的改變。說人話,其實就是參數化。post

 

數據驅動有什麼用?

對開發來講說,數據驅動無處不在,寫好了一個模塊,傳個參數調用一下,看結果是否是等於預期。

def add(a,b):
    return a + b


if __name__ == '__main__':
    result = add(3, 5)
    assert result == 8

對測試有來講就可厲害了,你知道早期的自動化測試(工具)都是流水式,第一步打開瀏覽器,第二步輸入abc,第三步點擊按鈕。假如我有一個登陸,登陸的步驟徹底同樣,就是每次登陸時用的帳號密碼不同。用數據驅動啊!

 

# 僞代碼
def login(username, password):
    driver.find_element_by_id("idInput").send_keys(username)
    driver.find_element_by_id("pwdInput").send_keys(password)
    driver.find_element_by_id("loginBtn").click()


if __name__ == '__main__':
    login("zhangsan","123")
    #...
    login("lisi","456")

看!是否是很厲害了個人數據驅動。我傳zhangsan,程序就會用zhangsan登陸,我傳lisi,就會用lisi登陸。

數據驅動的本質就是「測試數據」與「執行代碼」作分離。至於,「測試數據」放哪兒均可以,

定義成變量:

username = "zhangsan"

password = "123"

或放到數組裏

users =["zhangsan","123"]

或放到字典:

users = {"zhangsan":"123"}

或放到txt文件裏,XML文件裏,CSV文件裏,再讀取過出來,調用登陸方法時使用,這其實都是能夠的。

 

可是,咱們要作的是自動化測試,要分用例的,一種狀況一條用例。

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

用例1,用戶名密碼爲空。

用例2,用戶名爲空。

用例3,密碼爲空。

用例4,用戶名密碼正確。

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

相信身爲軟件測試人員的你,對這個用例沒有意見吧?

 

這裏以大家喜聞樂見的讀取csv文件爲例。

讀取數據文件,並獲得相應的數據,把這些數據用到具體的某個用例當中。

from selenium import webdriver
import unittest
import csv


# 讀取本地 CSV 文件
data = csv.reader(open('login_test.csv', 'r'))

# 讀取整個文件的數據放到users數組
users = []
for i in data:
    user = []
    for j in i:
        user.append(j)
    users.append(user)


class loginTest(unittest.TestCase):

    def setUp(self):
        self.driver = webdriver.Chrome()
        self.driver.get("http://xxx.login.page")

    # 封裝用戶登陸
    def user_login(self, username, password):
        self.driver.find_element_by_id("idInput").send_keys(username)
        self.driver.find_element_by_id("pwdInput").send_keys(password)
        self.driver.find_element_by_id("loginBtn").click()

    def test_login1(self):
        '''用戶名、密碼爲空登陸'''
        i = 0
        for user in users:
            print(user[0])
            if user[0] == 'user_pawd_null':
                print(i)
                username = users[i][1]
                password = users[i][2]
break; else: i +=1 self.user_login(username, password) def test_login2(self): '''用戶名正確,密碼爲空''' username = users[1][1] password = users[1][2] self.user_login(username, password) def test_login3(self): '''用戶名爲空,密碼正確''' username = users[2][1] password = users[2][2] self.user_login(username, password) def test_login4(self): '''用戶名密碼正確 ''' username = users[3][1] password = users[3][2] self.user_login(username, password) if __name__ == '__main__': unittest.main()

來看看你都幹了什麼高大上的事兒。

一、建立了一CSV文件,而後把登陸用的測試數據寫到了文件了。 --->建立了一個專門存放數據的文件,這多有逼格,自我感受良好。

二、讀取CSV文件,而且經過for循環,把全部數據組裝成一個二維數組,並放users數組中。--->這沒什麼呀,只是多寫了個for循環而已,繼續自我感受良好。

三、test_login1用例,爲用戶名密碼都爲空的用例,判斷users數組中某一行的第一列是否爲「user_pawd_null,是的話,說明這一行就是我想要的。取這一行的第2、第三列的測試數據,進行登陸測試。 --->這個取數據的方式有點。。。有點麻煩!

四、不要緊!不要緊!麻煩的話,咱們看test_login2 ,用users[1][1]和users[1][2]也能取到CSV表第二行的數據。  ---->這不就不那麼麻煩了!嗯,是不那麼麻煩了,不過,有點傻逼。你肯定你清楚的知道users[1][1]和users[1][2] 代表的啥?別急!別急!我打開CSV文件看看第2行對應是什麼數據。

 

這就是你玩的高大上的「數據驅動」,再下實在是佩服佩服!什麼你還有更高大上,簡潔的玩法?真心請賜教。。。。

 

爲何不按照下面的方式寫用例?

from selenium import webdriver
import unittest


class loginTest(unittest.TestCase):

    def setUp(self):
        self.driver = webdriver.Chrome()
        self.driver.get("http://xxx.login.page")

    # 封裝用戶登陸
    def user_login(self, username, password):
        self.driver.find_element_by_id("idInput").send_keys(username)
        self.driver.find_element_by_id("pwdInput").send_keys(password)
        self.driver.find_element_by_id("loginBtn").click()

    def test_login1(self):
        '''用戶名、密碼爲空登陸'''
        self.user_login("", "")
    
    def test_login2(self):
        '''用戶名正確,密碼爲空'''
        self.user_login("", "123")

    def test_login3(self):
        '''用戶名爲空,密碼正確'''
        self.user_login("zhangsan", "")

    def test_login4(self):
        '''用戶名密碼正確 '''
        self.user_login("zhangsan", "123")


if __name__ == '__main__':
    unittest.main()

我相信,正常人必定看出來了這比上面讀CSV文件簡單多了。但是,用讀取數據文件的話,不懂代碼也能寫用例!你是在自我YY這種需求吧??不懂自動化測試的同窗差點就信了!

「都已經開始寫代碼作自動化的你告訴我,不想懂開發,你肯定這不是任性?」

我在CSV文件中改測試數和在代碼中改測試數據有什麼區別? 在代碼中改測試數據,我是知道對應哪一個用例的,在CSV文件中改你肯定一會兒就知道對應的哪一個用例?

 

那什麼狀況下才要用到讀取測試數據文件呢?

關於自動化測試的誤區(二)

已經說明了本身的觀點。這裏就再也不重複,總之,用到要讀取文件的狀況並很少。不論是UI自動化測試,仍是接口自動化測試。

 

咱們還能夠藉助單元測試框架的功能進行參數化:

unittest單元測試框架實現參數化

 

 

堅持我原來的見解,不接受反駁!

 

@蟲師 
我理解自動化和手工的區別點只是執行方式上的區別,自動化是由代碼來執行用例,手工是由人來執行用例。這裏的test_login方法,只是用來執行用例的代碼,它並非真正意義上的用例。本質上說,那個csv文件纔是用例,「一種狀況一個用例」,而做爲用例,這個csv文件中缺乏了預期結果。是否能夠考慮將預期結果的內容按照必定格式也補充到csv中,而後作一個專門解析csv中結果的方法,加入到test_login中,這樣即便是遠超過4組數據的狀況,也只須要用一個方法就能夠進行測試,而不是每組數據寫一個方法,失敗與否也是針對每組數據而言。
至於用例數量,一樣,實際上是拿數據組的數量來計算,而後體如今最後生成的測試報告中

 

@ nuist_kevin
你說的我很同意,我以前作音樂搜索排序的效果測試時就是使用數據+指望結果組成一條case,並保存在excel中的一行數據,而後用method去一行一行使用數據,並把每條case的實際結果寫到對應case的後面,用例跑完以後,再對比便可知道測試報告。

 

這兩段留言,我看了!也明白是什麼意思。

我上面的觀點是創建在unittest 單元測試框架的基礎上面的,在unittest 中一個以「test」開頭的方式被計算爲一條用例,按照上面的兩哥們的觀點 excel 文件裏面的一條數據計算爲一個用例。

我很想弄明白,用例不一樣,步驟不同,數據字段不同(登陸須要「用戶名」和「密碼」, 搜索須要「搜索關鍵字」, 添加用戶須要"id", "name", "age"....),因此,一個方法只能涵蓋一組測試,對吧!?  那是否是須要建立多個測試數據文件?,同時也須要多個方法?

這些數據文件中的結果是否是最終還要匯合到一塊兒統計。用例運行失敗的錯誤提示信息是否是也要 寫到 excel 文件裏? 」方便「查看報錯嘛。

總結: 

* 維護不便,多個方法 和 多個數據文件,不一樣的方法還要找對應的數據文件。

* 測試結果統計,測試結果是分散在不一樣的數據文件中的。 

 

這個須要本身靈活點。數據量越大,數據驅動的優點越明顯。還有,數據文件裏須要包含:
一、用例名字
二、輸入值一、輸入值2.。。。
三、指望值
這樣腳本里只須要一直一個測試方法就能夠了

 

數據量越大,「數據驅動」越有優點? 你是拿登陸或搜索之類的功能測試一萬遍麼? 那確實挺有優點的,畢竟字段都是同樣的。一個方法就能夠搞定了。

 

咱們知道UI自動化測試是模擬用戶行爲,用戶確定不肯意傻逼的重複作某事,能讓用戶選擇的就不要讓用戶輸入,須要用戶輸入的大數據是不存在的。除了,我如今寫博客是在輸入大量數據。

你還能再給我舉兩個例子是讓用戶輸入不少數據的例子麼? 談到數據驅動,大家立刻跳出來個想法。若是須要不少數據的話就須要數據驅動了。別YY這個僞需求了!我就問啥功能須要?

再說了,就算數據驅動就必定要讀文件麼?

相關文章
相關標籤/搜索