關於面試總結12-介面自動化面試題
前言
前面總結了一篇關於介面測試的常規面試題,現在介面自動化測試用的比較多,也是被很多公司看好。那麼想做介面自動化測試需要具備哪些能力呢?
也就是面試的過程中,面試官會考哪些問題,知道你是不是真的做過介面自動化測試?總的來說問的比較多的就是以下幾個問題:
1.json和字典的區別? -對基礎資料型別的考察
2.測試的資料你放在哪? -資料與指令碼分離
3.引數化 - 資料驅動模式
4.下個介面請求引數依賴上個介面的返回資料 - 引數關聯
5.依賴於登入的介面如何處理 -token和session的管理
6.依賴第三方的介面如何處理 -mock模擬資料返回
7.不可逆的操作,如何處理,比如刪除一個訂單這種介面如何測試 -造資料
8.介面產生的垃圾資料如何清理 - 資料清理
9.一個訂單的幾種狀態如何全部測到,如:未處理,處理中,處理失敗,處理成功 - 造資料,改資料庫訂單狀態
10.python如何連線資料庫操作?
11.其它的就是執行出報告、程式碼管理(git)、執行策略和持續整合jenkins相關了
1.json和字典dict的區別?
現在自動化培訓爛大街,是個人都能說的上幾個框架,面試如果問框架相關問題,求職者只需一瓶82年的雪碧,會吹的讓你懷疑人生!
所以面試官為了更清楚的知道你是停留在表面上的花拳繡腿還是有紮實的基礎,就不會問框架這種東西了。基本上問幾個資料型別的基礎就知道有沒貨了。
那麼json和字典到底有什麼區別呢?初學者連python的基礎資料型別都沒搞清楚,直接擼框架,有的人學了幾個月可能都迷迷糊糊的,以為json就是字典。這個是肯定不對的。
首先python裡面的基礎資料型別有:int、str、 float、list、bool、tuple、dict、set這幾種型別,裡面沒json這種資料型別。
JSON(JavaScript Object Notation, JS 物件簡譜) 是一種輕量級的資料交換格式。它基於 ECMAScript (歐洲計算機協會制定的js規範)的一個子集,採用完全獨立於程式語言的文字格式來儲存和表示資料。簡潔和清晰的層次結構使得 JSON 成為理想的資料交換語言。 易於人閱讀和編寫,同時也易於機器解析和生成,並有效地提升網路傳輸效率。
由於你的程式碼是python寫的(也有可能是php,java,c,ruby等語言),但是後端介面是java寫的(也有可能是其它語言),不同的語言資料型別是不一樣的(就好比中國的語言和美國的語言資料型別也不一樣,中國的一般說一隻羊,一頭牛,美國都是 a /an這種單位),所以就導致你提交的資料,別的開發語言無法識別,這就需要規範傳輸的資料(傳輸的資料都是一個字串),大家都遵循一個規範,按一個標準的格式去傳輸,於是就有就json這種國際化規範的資料型別。
json本質上還是字串,只是按key:value這種鍵值對的格式來的字串
import json
# a是字典dict
a = {"a": 1, "b": 2, "c": True}
# b是json
b = '{"a": 1, "b": 2, "c": true}'
print(type(a))
print(json.dumps(a)) # a轉json
執行結果
<class 'dict'>
{"a": 1, "b": 2, "c": true}
<class 'str'>
{'a': 1, 'b': 2, 'c': True}
2.測試的資料你放在哪?
測試資料到底該怎麼放,這個是面試官最喜歡問的一個題了,似乎仁者見仁智者見智,沒有標準的答案,有的人說放excel,也有的說放.py指令碼,也有的說放ini配置檔案,
還有放到json,yaml檔案,txt檔案,甚至有的放資料庫,五花八門,一百個做自動化的小夥伴有100個放的地方。
這裡總結下測試的資料到底該怎麼放?
首先測試的資料是分很多種的,有登入的賬戶資料,也有註冊的賬戶資料,還有介面的引數,還有郵箱配置的資料等等等等,所以這個題不能一概而論給答死了。要不然就是給自己挖坑。
以下兩個大忌不能回答:
- 測試的資料是不能寫死到程式碼裡面的,這個是原則問題,也是寫程式碼的大忌(你要是回答寫在程式碼裡面,估計就是回去等通知了)
- 測試資料放到.py的開頭,這種其實很方便,對於少量的,固定不變的資料其實是可以放的,但是面試時候,千萬不能這樣說,面試官喜歡裝逼的方法
測試資料存放總結:
1.對於賬號密碼,這種管全域性的引數,可以用命令列引數,單獨抽出來,寫的配置檔案裡(如ini)
2.對於一些一次性消耗的資料,比如註冊,每次註冊不一樣的數,可以用隨機函式生成
3.對於一個介面有多組測試的引數,可以引數化,資料放yaml,text,json,excel都可以
4.對於可以反覆使用的資料,比如訂單的各種狀態需要造資料的情況,可以放到資料庫,每次資料初始化,用完後再清理
5.對於郵箱配置的一些引數,可以用ini配置檔案
6.對於全部是獨立的介面專案,可以用資料驅動方式,用excel/csv管理測試的介面資料
7.對於少量的靜態資料,比如一個介面的測試資料,也就2-3組,可以寫到py指令碼的開頭,十年八年都不會變更的
總之不同的測試資料,可以用不同的檔案管理
3.什麼是資料驅動,如何引數化?
引數化和資料驅動的概念這個肯定要知道的,引數化的思想是程式碼用例寫好了後,不需要改程式碼,只需維護測試資料就可以了,並且根據不同的測試資料生成多個用例
python裡面用unittest框架
import unittest
import ddt
# 測試資料
datas = [ {"user": "admin", "psw": "123", "result": "true"},
{"user": "admin1", "psw": "1234", "result": "true"},
{"user": "admin2", "psw": "1234", "result": "true"},
{"user": "admin3", "psw": "1234", "result": "true"},
{"user": "admin4", "psw": "1234", "result": "true"},
{"user": "admin5", "psw": "1234", "result": "true"},
{"user": "admin6", "psw": "1234", "result": "true"},
{"user": "admin7", "psw": "1234", "result": "true"},
{"user": "admin8", "psw": "1234", "result": "true"},
{"user": "admin9", "psw": "1234", "result": "true"},
{"user": "admin10", "psw": "1234", "result": "true"},
{"user": "admin11", "psw": "1234", "result": "true"}]
@ddt.ddt
class Test(unittest.TestCase):
@ddt.data(*datas)
def test_(self, d):
"""上海-悠悠:{0}"""
print("測試資料:%s" % d)
if __name__ == "__main__":
unittest.main()
unittest框架還有一個paramunittest也可以實現
import unittest
import paramunittest
import time
# python3.6
# 作者:上海-悠悠
@paramunittest.parametrized(
{"user": "admin", "psw": "123", "result": "true"},
{"user": "admin1", "psw": "1234", "result": "true"},
{"user": "admin2", "psw": "1234", "result": "true"},
{"user": "admin3", "psw": "1234", "result": "true"},
{"user": "admin4", "psw": "1234", "result": "true"},
{"user": "admin5", "psw": "1234", "result": "true"},
{"user": "admin6", "psw": "1234", "result": "true"},
{"user": "admin7", "psw": "1234", "result": "true"},
{"user": "admin8", "psw": "1234", "result": "true"},
{"user": "admin9", "psw": "1234", "result": "true"},
{"user": "admin10", "psw": "1234", "result": "true"},
{"user": "admin11", "psw": "1234", "result": "true"},
)
class TestDemo(unittest.TestCase):
def setParameters(self, user, psw, result):
'''這裡注意了,user, psw, result三個引數和前面定義的字典一一對應'''
self.user = user
self.user = psw
self.result = result
def testcase(self):
print("開始執行用例:--------------")
time.sleep(0.5)
print("輸入使用者名稱:%s" % self.user)
print("輸入密碼:%s" % self.user)
print("期望結果:%s " % self.result)
time.sleep(0.5)
self.assertTrue(self.result == "true")
if __name__ == "__main__":
unittest.main(verbosity=2)
如果用的是pytest框架,也能實現引數化
# content of test_canshu1.py
# coding:utf-8
import pytest
@pytest.mark.parametrize("test_input,expected",
[ ("3+5", 8),
("2+4", 6),
("6 * 9", 42),
])
def test_eval(test_input, expected):
assert eval(test_input) == expected
if __name__ == "__main__":
pytest.main(["-s", "test_canshu1.py"])
pytest裡面還有一個更加強大的功能,獲得多個引數化引數的所有組合,可以堆疊引數化裝飾器
import pytest
@pytest.mark.parametrize("x", [0, 1])
@pytest.mark.parametrize("y", [2, 3])
def test_foo(x, y):
print("測試資料組合:x->%s, y->%s" % (x, y))
if __name__ == "__main__":
pytest.main(["-s", "test_canshu1.py"])
4.下個介面請求引數依賴上個介面的返回資料
這個很容易,不同的介面封裝成不同的函式或方法,需要的資料return出來,用一箇中間變數a去接受,後面的介面傳a就可以了
參考這篇【python介面自動化26-引數關聯和JSESSIONID(上個介面返回資料作為下個介面請求引數)】
5.依賴於登入的介面如何處理
登入介面依賴token的,可以先登入後,token存到一個yaml或者json,或者ini的配置檔案裡面,後面所有的請求去拿這個資料就可以全域性使用了
參考之前分享的一篇python介面自動化24-有token的介面專案使用unittest框架設計
如果是cookies的引數,可以用session自動關聯
s=requests.session()
後面請求用s.get()和s.post()就可以自動關聯cookies了
6.依賴第三方的介面如何處理
這個需要自己去搭建一個mock服務,模擬介面返回資料,參考【python筆記25-mock-server之moco】(https://www.cnblogs.com/yoyoketang/p/9348552.html)
moco是一個開源的框架,在github上可以下載到https://github.com/dreamhead/moco
moco服務搭建需要自己能夠熟練掌握,面試會問你具體如何搭建 ,如何模擬返回的資料,是用的什麼格式,如何請求的
7.不可逆的操作,如何處理,比如刪除一個訂單這種介面如何測試
此題考的是造資料的能力,介面的請求資料,很多都是需要依賴前面一個狀態的
比如工作流這種,流向不同的人狀態不一樣,操作許可權不一樣,測試的時候,每種狀態都要測到,就需要自己會造資料了。
平常手工測試造資料,直接在資料庫改欄位狀態。那麼自動化也是一樣,造資料可以用python連資料庫了,做增刪改查的操作
測試用例前置操作,setUp做資料準備
後置操作,tearDown做資料清理
8.介面產生的垃圾資料如何清理
跟上面一樣,造資料和資料清理,需用python連資料庫了,做增刪改查的操作
測試用例前置操作,setUp做資料準備
後置操作,tearDown做資料清理
9.一個訂單的幾種狀態如何全部測到,如:未處理,處理中,處理失敗,處理成功
跟上面一樣,也是考察造資料,修改資料的狀態
10.python如何連線資料庫操作?
這個就是詳細的考察你是如何用python連資料庫的,並且最好能現場寫程式碼那種(有的筆試題就是python連資料庫)
具體問你用到哪個模組,查詢的資料是什麼型別?如何刪除資料?如何新增資料?如何修改資料?
PyMySQL 是在 Python3.x 版本中用於連線 MySQL 伺服器的一個庫,Python2中則使用mysqldb。
詳情參考教程http://www.runoob.com/python3/python3-mysql.html
#!/usr/bin/python3
# 查詢EMPLOYEE表中salary(工資)欄位大於1000的所有資料:
import pymysql
# 開啟資料庫連線
db = pymysql.connect("localhost","testuser","test123","TESTDB" )
# 使用cursor()方法獲取操作遊標
cursor = db.cursor()
# SQL 查詢語句
sql = "SELECT * FROM EMPLOYEE \
WHERE INCOME > %s" % (1000)
try:
# 執行SQL語句
cursor.execute(sql)
# 獲取所有記錄列表
results = cursor.fetchall()
for row in results:
fname = row[0]
lname = row[1]
age = row[2]
sex = row[3]
income = row[4]
# 列印結果
print ("fname=%s,lname=%s,age=%s,sex=%s,income=%s" % \
(fname, lname, age, sex, income ))
except:
print ("Error: unable to fetch data")
# 關閉資料庫連線
db.close()
其它的就是執行出報告、程式碼管理(git)、執行策略和持續整合jenkins相關了,這個所以的自動化但是一樣的,後面會單獨講一篇jenkins持續整合相關