背景
在执行自动化测试用例时对于失败用例我们经常无法区别到底是开发的bug还是脚本编写的有问题,此时就需要开发通过日志进行确认,但自动化用例一般都会执行的很多条,再回去查找日志时,多数情况早就被冲掉了,本文以pytest框架为例实现Android日志的逐条抓取。
在实现此功能之前我们还要说明一个python 类,这个类的作用是实现类似java静态函数的作用,就是可以跨python模块进行变量的读取和保存,类名为
global_var.py
def init():
global _my_dict
_my_dict = {}
def set_value(my_key, my_value):
_my_dict[my_key] = my_value
def get_value(my_key, my_default_value=None):
try:
return _my_dict[my_key]
except KeyError:
return my_default_value
在方法类中添加如下方法命名为
utils.py:
import global_var
import subprocess
import threading
def get_android_log_in_thread(pk_name, save_file):
my_args_list = [(pk_name, save_file)]
threading_all(my_args_list, 1, get_android_log)
def threading_all(args_list: list, number: int, func):
print(len(args_list))
num = len(args_list) // number
soft_ids = [x for x in range(0, len(args_list), num)]
threads = []
len_ids = range(len(soft_ids))
num_th = len(soft_ids)
for i in len_ids:
t = threading.Thread(
target=run_main,
args=(
args_list,
soft_ids[i],
soft_ids[i] + num,
f'thread{i}',
func,
),
name=f'thread{i}')
# print(f'thread{i}')
threads.append(t)
for i in range(num_th):
threads[i].start()
time.sleep(0.5)
def get_android_log(*args):
pk_name = args[0][0]
file = args[0][1]
my_thread_num = args[1]
# 要执行的终端指令 -s 后面接过滤的tag
adb_cmd = 'adb logcat | find "' + pk_name + '"'
try:
# 创建管道
pi = subprocess.Popen(adb_cmd, shell=True, stdout=subprocess.PIPE)
global_var.set_value("pi_out", pi)
# t用来标记输出行数,每10行刷新到文件中一次
t = 0
# 遍历每行
for my_line in iter(pi.stdout.readline, 'b'):
# 将得到字节转码成utf-8,然后写入文件
# 第二个参数防止使用默认参数会报出转换异常, 'ignore'会过滤掉特殊符号
if not file.closed:
file.write(my_line.decode('utf-8', 'ignore').replace('\n', ''))
t = t + 1
# 当达到10行时,将数据刷到文件中
if t == 10:
t = 0
file.flush()
else:
return
except BaseException as e:
print(str(e))
return
def invoke(cmd):
output, errors = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
my_str = output.decode("utf-8")
# my_list = my_str.split('\r\n')
return my_str
def make_dir(my_dir_path):
if not os.path.exists(my_dir_path):
os.makedirs(my_dir_path)
在conftest.py文件中添加如下函数:
@pytest.fixture(scope="function", autouse=True)
def save_log(request):
global_var.init()
my_case_name = request.node.name
my_file_name = my_case_name+'_'+util.current_datetime("%Y_%m_%d_%H_%M_%S")+'.txt'
path = os.path.dirname(__file__)
make_dir(os.path.join(path, 'Log'))
my_log_file_path = os.path.join(path, 'Log', my_file_name)
my_pkg_name = "com.tencent.wework"
# 以append形式打开(创建)文件
my_file = open(my_log_file_path, 'a', encoding='utf-8')
my_list = invoke("adb devices")
if my_list[1] == '':
print('没有链接Android手机,无法获取Android切面日志,请确认!')
else:
get_android_log_in_thread(my_pkg_name, my_file)
yield
if my_file.closed:
pass
else:
my_file.close()
my_pi_value = global_var.get_value("pi_out")
if my_pi_value is None:
print('my_pi_value is None')
return
else:
my_pi_value.terminate()
print('执行terminate。。。。。。。。。。。。。。。。。。。。。')