Python 與遊戲測試 (小工具篇)
阿新 • • 發佈:2019-02-12
例子2:adb命令的封裝
做安卓手遊測試的時候,adb是常用工具,我們可以通過它,進行apk的安裝,解除安裝,截圖,獲取APK資訊,效能資料,獲取手機資訊等等操作。
比如獲取當前執行在前臺的apk的package和activity名稱
def run_cmd(cmd):
"""執行CMD命令"""
p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
return [i.decode() for i in p.communicate()[0].splitlines()]
def get_apk_info():
"""獲取apk的package,activity名稱
:return: list eg ['com.android.calendar', 'com.meizu.flyme.calendar.AllInOneActivity']
"""
result = run_cmd("adb shell dumpsys activity top")
for line in result:
if line.strip().startswith('ACTIVITY'):
return line.split()[1].split('/')
print(get_apk_info())
output: ['com.android.calendar', 'com.meizu.flyme.calendar.AllInOneActivity']
比如檢視當前apk的記憶體佔用
def get_mem_using(package_name=None):
"""檢視apk的記憶體佔用
:param package_name:
:return: 單位KB
"""
if not package_name:
package_name = get_apk_info()[0]
result = run_cmd("adb shell dumpsys meminfo {}".format(package_name))
info = re.search('TOTAL\W+\d+', str(result)).group()
mem = ''
try:
mem = info.split()
except Exception as e:
print(info)
print(e)
return mem[-1]
output: 37769
比如備份當前apk到桌面
def backup_current_apk(path=r"C:\Users\jianbing\Desktop\apks"):
package = get_apk_info()[0]
result = run_cmd("adb shell pm path {}".format(package))
cmd = "adb pull {} {}".format(result[0].split(":")[-1], os.path.join(path, "{}.apk".format(package)))
print(cmd)
run_cmd(cmd)
再進一步,將常用的adb操作封裝為一個ADB工具類。社群裡也有童鞋之前分享過,傳送門。
處理文字
例子:在整個資料夾中搜索關鍵字
某天策劃說,這個版本他刪掉了某個道具,讓我檢查下有沒有刪漏的地方,這個道具產出的地方不少,最佳的檢查方式是各個相關配置表看下還有沒有配置這個道具。
那就寫個指令碼遍歷整個資料夾來搜尋指定關鍵字吧。
import os
def get_files_by_suffix(path, suffixes=("txt", "xml"), traverse=True):
"""從path路徑下,找出全部指定字尾名的檔案
:param path: 根目錄
:param suffixes: 指定查詢的檔案字尾名
:param traverse: 如果為False,只遍歷一層目錄
:return:
"""
file_list = []
for root, dirs, files in os.walk(path):
for file in files:
file_suffix = os.path.splitext(file)[1][1:].lower() # 字尾名
if file_suffix in suffixes:
file_list.append(os.path.join(root, file))
if not traverse:
return file_list
return file_list
if __name__ == '__main__':
keyword = "XXX寶箱"
files = get_files_by_suffix(r"C:\project\config")
for file in files:
with open(file, 'r', encoding='utf-8', errors='ignore') as f:
content = f.read().lower()
position = content.find(keyword.lower())
if position != -1:
print("Find in {0}".format(file))
start = position - 100 if position - 100 > 0 else 0
end = position + 100 if position + 100 < len(content) else len(content)
print(content[start:end])
print("_" * 100)
操作遠端伺服器
例子1:檢視內網發版時間
有時候問開發,最近一次內網服務端發版是什麼時候?開發回答:有點忘記了。。那就得自力更生了~
手動方式:使用FTP軟體連入內網伺服器,檢視檔案的更新日期,從而知道發版時間。
懶人方式:Py大法好~
paramiko是Python很有名的第三方庫,遵循SSH2協議,支援以加密和認證的方式,進行遠端伺服器的連線。
import paramiko
import time
_transport = paramiko.Transport("192.168.1.10:22")
_transport.connect(username="root", password="XXXXXX")
sftp = paramiko.SFTPClient.from_transport(_transport)
result = sftp.listdir_attr("/data/www/sg/sg_dev/socket/conf/config/treasure")
print("發版時間是:{}".format(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(result[0].st_mtime))))
sftp.close()
例子2:檢視內網報錯資訊
在進行測試的時候,需要多留意服務端是否有新的報錯資訊,有些報錯在客戶端並沒有什麼表現,比如資料進庫失敗,手動方式:通過SecureCRT連入內網伺服器,CD到Log目錄下,然後tail -n 200 sg_error.log 檢視最新的報錯資訊。
於是萌生了寫一個小工具來定時檢測,發現報錯資訊就儲存起來的想法。
import datetime
import paramiko
import time
import os
class ScanError(object):
def __init__(self):
self._ssh = paramiko.SSHClient()
self.last_error_log = None
self._init()
def _init(self):
os.chdir("data") # 打算將報錯資訊儲存到data目錄下
self._ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
self._ssh.connect("192.168.1.10", username="root", password="XXXXXX")
error_log = self.get_error_log(500)
self.last_error_log = error_log
# 檢測最近三天有沒有報錯資訊
today = datetime.date.today()
yesterday = today - datetime.timedelta(days=1)
the_day_before_yesterday = today - datetime.timedelta(days=2)
error_log_str = "\n".join(error_log)
if error_log_str.find(str(today)) > -1 or error_log_str.find(str(yesterday)) > -1 or error_log_str.find(str(the_day_before_yesterday)) > -1:
self.save_error_log("error.txt", error_log)
print('內網最近三天有錯誤資訊,請檢視')
os.popen('error.txt')
def get_error_log(self, num=200):
cmd = 'cd /data/www/sg/sg_dev/socket/log&&tail -n {} sg_error.log'.format(num)
stdin, stdout, stderr = self._ssh.exec_command(cmd)
error_log = [i.decode("utf-8") for i in stdout.read().splitlines() if i]
return error_log
做安卓手遊測試的時候,adb是常用工具,我們可以通過它,進行apk的安裝,解除安裝,截圖,獲取APK資訊,效能資料,獲取手機資訊等等操作。
比如獲取當前執行在前臺的apk的package和activity名稱
def run_cmd(cmd):
"""執行CMD命令"""
p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
return [i.decode() for i in p.communicate()[0].splitlines()]
def get_apk_info():
"""獲取apk的package,activity名稱
:return: list eg ['com.android.calendar', 'com.meizu.flyme.calendar.AllInOneActivity']
"""
result = run_cmd("adb shell dumpsys activity top")
for line in result:
if line.strip().startswith('ACTIVITY'):
return line.split()[1].split('/')
print(get_apk_info())
output: ['com.android.calendar', 'com.meizu.flyme.calendar.AllInOneActivity']
比如檢視當前apk的記憶體佔用
def get_mem_using(package_name=None):
"""檢視apk的記憶體佔用
:param package_name:
:return: 單位KB
"""
if not package_name:
package_name = get_apk_info()[0]
result = run_cmd("adb shell dumpsys meminfo {}".format(package_name))
info = re.search('TOTAL\W+\d+', str(result)).group()
mem = ''
try:
mem = info.split()
except Exception as e:
print(info)
print(e)
return mem[-1]
output: 37769
比如備份當前apk到桌面
def backup_current_apk(path=r"C:\Users\jianbing\Desktop\apks"):
package = get_apk_info()[0]
result = run_cmd("adb shell pm path {}".format(package))
cmd = "adb pull {} {}".format(result[0].split(":")[-1], os.path.join(path, "{}.apk".format(package)))
print(cmd)
run_cmd(cmd)
再進一步,將常用的adb操作封裝為一個ADB工具類。社群裡也有童鞋之前分享過,傳送門。
處理文字
例子:在整個資料夾中搜索關鍵字
某天策劃說,這個版本他刪掉了某個道具,讓我檢查下有沒有刪漏的地方,這個道具產出的地方不少,最佳的檢查方式是各個相關配置表看下還有沒有配置這個道具。
那就寫個指令碼遍歷整個資料夾來搜尋指定關鍵字吧。
import os
def get_files_by_suffix(path, suffixes=("txt", "xml"), traverse=True):
"""從path路徑下,找出全部指定字尾名的檔案
:param path: 根目錄
:param suffixes: 指定查詢的檔案字尾名
:param traverse: 如果為False,只遍歷一層目錄
:return:
"""
file_list = []
for root, dirs, files in os.walk(path):
for file in files:
file_suffix = os.path.splitext(file)[1][1:].lower() # 字尾名
if file_suffix in suffixes:
file_list.append(os.path.join(root, file))
if not traverse:
return file_list
return file_list
if __name__ == '__main__':
keyword = "XXX寶箱"
files = get_files_by_suffix(r"C:\project\config")
for file in files:
with open(file, 'r', encoding='utf-8', errors='ignore') as f:
content = f.read().lower()
position = content.find(keyword.lower())
if position != -1:
print("Find in {0}".format(file))
start = position - 100 if position - 100 > 0 else 0
end = position + 100 if position + 100 < len(content) else len(content)
print(content[start:end])
print("_" * 100)
操作遠端伺服器
例子1:檢視內網發版時間
有時候問開發,最近一次內網服務端發版是什麼時候?開發回答:有點忘記了。。那就得自力更生了~
手動方式:使用FTP軟體連入內網伺服器,檢視檔案的更新日期,從而知道發版時間。
懶人方式:Py大法好~
paramiko是Python很有名的第三方庫,遵循SSH2協議,支援以加密和認證的方式,進行遠端伺服器的連線。
import paramiko
import time
_transport = paramiko.Transport("192.168.1.10:22")
_transport.connect(username="root", password="XXXXXX")
sftp = paramiko.SFTPClient.from_transport(_transport)
result = sftp.listdir_attr("/data/www/sg/sg_dev/socket/conf/config/treasure")
print("發版時間是:{}".format(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(result[0].st_mtime))))
sftp.close()
例子2:檢視內網報錯資訊
在進行測試的時候,需要多留意服務端是否有新的報錯資訊,有些報錯在客戶端並沒有什麼表現,比如資料進庫失敗,手動方式:通過SecureCRT連入內網伺服器,CD到Log目錄下,然後tail -n 200 sg_error.log 檢視最新的報錯資訊。
於是萌生了寫一個小工具來定時檢測,發現報錯資訊就儲存起來的想法。
import datetime
import paramiko
import time
import os
class ScanError(object):
def __init__(self):
self._ssh = paramiko.SSHClient()
self.last_error_log = None
self._init()
def _init(self):
os.chdir("data") # 打算將報錯資訊儲存到data目錄下
self._ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
self._ssh.connect("192.168.1.10", username="root", password="XXXXXX")
error_log = self.get_error_log(500)
self.last_error_log = error_log
# 檢測最近三天有沒有報錯資訊
today = datetime.date.today()
yesterday = today - datetime.timedelta(days=1)
the_day_before_yesterday = today - datetime.timedelta(days=2)
error_log_str = "\n".join(error_log)
if error_log_str.find(str(today)) > -1 or error_log_str.find(str(yesterday)) > -1 or error_log_str.find(str(the_day_before_yesterday)) > -1:
self.save_error_log("error.txt", error_log)
print('內網最近三天有錯誤資訊,請檢視')
os.popen('error.txt')
def get_error_log(self, num=200):
cmd = 'cd /data/www/sg/sg_dev/socket/log&&tail -n {} sg_error.log'.format(num)
stdin, stdout, stderr = self._ssh.exec_command(cmd)
error_log = [i.decode("utf-8") for i in stdout.read().splitlines() if i]
return error_log