接口自動化測試面試題
前言
前面總結了一篇關於接口測試的常規面試題,現在接口自動化測試用的比較多,也是被很多公司看好。那么想做接口自動化測試需要具備哪些能力呢?也就是面試的過程中,面試官會考哪些問題,知道你是不是真的做過接口自動化測試?總的來說問的比較多的就是以下幾個問題:
1. 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. 測試的數據你放在哪? -數據與腳本分離
首先測試的數據是分很多種的,有登錄的賬戶數據,也有注冊的賬戶數據,還有接口的參數,還有郵箱配置的數據等等等等,
所以這個題不能一概而論給答死了。要不然就是給自己挖坑。
以下兩個大忌不能回答:
- 測試的數據是不能寫死到代碼里面的,這個是原則問題,也是寫代碼的大忌(你要是回答寫在代碼里面,估計就是回去等通知了)
- 測試數據放到.py 的開頭,這種其實很方便,對於少量的,固定不變的數據其實是可以放的,但是面試時候,千萬不能這樣說,面試官喜歡裝逼的方法
測試數據存放總結:
- 對於賬號密碼,這種管全局的參數,可以用命令行參數,單獨抽出來,寫的配置文件里(如 ini)
- 對於一些一次性消耗的數據,比如注冊,每次注冊不一樣的數,可以用隨機函數生成
- 對於一個接口有多組測試的參數,可以參數化,數據放 yaml,text,json,excel都可以
- 對於可以反復使用的數據,比如訂單的各種狀態需要造數據的情況,可以放到數據庫,每次數據初始化,用完后再清理
- 對於郵箱配置的一些參數,可以用 ini 配置文件
- 對於全部是獨立的接口項目,可以用數據驅動方式,用 excel/csv 管理測試的接口數據
- 對於少量的靜態數據,比如一個接口的測試數據,也就 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 和 session 的管理
登錄接口依賴 token 的,可以先登錄后,token 存到一個 yaml 或者 json,或者ini 的配置文件里面,后面所有的請求去拿這個數據就可以全局使用了
參考之前分享的一篇 python 接口自動化 24-有 token 的接口項目使用 unittest框架設計
如果是 cookies 的參數,可以用 session 自動關聯s=requests.session()后面請求用 s.get()和 s.post()就可以自動關聯 cookies 了
6. 依賴第三方的接口如何處理 -mock 模擬數據返回
這個需要自己去搭建一個 mock 服務,模擬接口返回數據,參考python 筆記25-mock-server 之 moco
moco 是一個開源的框架,在 github 上可以下載到傳送
moco 服務搭建需要自己能夠熟練掌握,面試會問你具體如何搭建 ,如何模擬返回的數據,是用的什么格式,如何請求的
7. 不可逆的操作,如何處理,比如刪除一個訂單這種接口如何測試 -造數據
此題考的是造數據的能力,接口的請求數據,很多都是需要依賴前面一個狀態的
比如工作流這種,流向不同的人狀態不一樣,操作權限不一樣,測試的時候,每種狀態都要測到,就需要自己會造數據了。
平常手工測試造數據,直接在數據庫改字段狀態。
那么自動化也是一樣,造數據可以用 python 連數據庫了,做增刪改查的操作,
測試用例前置操作,setUp 做數據准備后置操作,tearDown 做數據清理
8. 接口產生的垃圾數據如何清理 - 數據清理
跟上面一樣,造數據和數據清理,需用 python 連數據庫了,做增刪改查的操作
測試用例前置操作,setUp 做數據准備
后置操作,tearDown 做數據清理
9. 一個訂單的幾種狀態如何全部測到,如:未處理,處理中,處理失敗,處理成功 - 造數據,改數據庫訂單狀態
如:未處理,處理中,處理失敗,處理成功
跟上面一樣,也是考察造數據,修改數據的狀態
10. python 如何連接數據庫操作?
這個就是詳細的考察你是如何用 python 連數據庫的,並且最好能現場寫代碼那種(有的筆試題就是 python 連數據庫)
具體問你用到哪個模塊,查詢的數據是什么類型?如何刪除數據?如何新增數據?如何修改數據?
PyMySQL 是在 Python3.x 版本中用於連接 MySQL 服務器的一個庫,Python2 中則使用 mysqldb。
詳情參考教程 傳送
#!/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 持續集成相關
注:此文參考上海悠悠-測試面試相關