冒烟测试自动化

Python笔记 无标签 2020-03-25 阅读:346

我现在是一个软件测试实习生,平时挤点时间学习Python。Python语法简单,入门快,学习成本相对较低,很适合像我这样时间不多,又想速成的人学。在学Python之前我有一些C、C#语言基础,所以理解Python并不难。在学习Python的过程中,偶尔用Python做点自动化的东西,当然了,这些东西都是学着前人造轮子,自己没多少创意,觉得方便就拿来用了。在CTRL+C--CTRL+V的过程中,偶尔看到很优秀的代码,自己很是羡慕,同时也感到幸运,他们总结的经验对于初学者的我来说,帮助很大。

最近在用Python写一个冒烟测试的自动化,思路可能不太好,毕竟第一次做这个,期间改过很多次,这是最近的一次修改。

代码规范上还存在些问题,慢慢来吧。

# -*- coding: utf-8 -*-
# @Time    : 2020/3/25 10:38
# @Author  : H
# @File    : run.py
# @Software: PyCharm
import os
import win32api
import win32gui
import win32con
import time
import glob
import cv2

"""
  >>>
  【控制BSSim软件】----Start
"""


def check_app_status():  # 判断BSSim是否已经启动
    main_form_all = dict()  # 所有正在运行的程序--句柄、标题
    '''获取主窗体句柄'''

    def get_all(hwnd, mouse):
        if win32gui.IsWindow(hwnd) and win32gui.IsWindowEnabled(hwnd) and win32gui.IsWindowVisible(hwnd):
            main_form_all.update({hwnd: win32gui.GetWindowText(hwnd)})

    win32gui.EnumWindows(get_all, 0)  # 执行获取所有程序窗体
    keys = [x[0] for x in main_form_all.items() if 'Base Station Simulator' in x[1]]  # 查找BSSim
    return keys


def get_main_handle():  # 获取主窗体句柄
    main_form_all = dict()  # 所有正在运行的程序--句柄、标题
    main_handle = None

    def get_all_hwnd(hwnd, mouse):
        if win32gui.IsWindow(hwnd) and win32gui.IsWindowEnabled(hwnd) and win32gui.IsWindowVisible(hwnd):
            main_form_all.update({hwnd: win32gui.GetWindowText(hwnd)})

    win32gui.EnumWindows(get_all_hwnd, 0)  # 执行获取所有程序窗体
    keys = [x[0] for x in main_form_all.items() if 'Base Station Simulator' in x[1]]  # 查找BSSim
    for i in keys:
        main_handle = i  # BSSim主窗体句柄
    return main_handle


def get_toolbar_handle(main_handle):  # 获取子窗体句柄
    child_handle_all = []  # 子窗体的句柄
    child_title_all = []  # 子窗体的标题
    toolbar_handle = None
    win32gui.EnumChildWindows(main_handle, lambda hwnd, param: param.append(hwnd), child_handle_all)
    for i in child_handle_all:
        child_title_all.append(win32gui.GetClassName(i))
    child_form_all = dict(zip(child_handle_all, child_title_all))
    # 从 childFormList 中查找值为“ToolbarWindow32”的键,即为 ToolbarWindow32 的句柄
    keys = [x[0] for x in child_form_all.items() if 'ToolbarWindow32' in x[1]]
    for i in keys:
        toolbar_handle = i
    return toolbar_handle


def run_and_stop_btn(main_handle, toolbar_handle):  # 单击"运行/停止"按钮'
    # 置顶窗口后,获取坐标
    win32gui.ShowWindow(main_handle, win32con.SW_SHOWNORMAL)
    # ctypes.windll.user32.ShowWindow(mainHandle, 3)  # 窗口最大化
    win32gui.SetForegroundWindow(main_handle)
    time.sleep(0.5)  # 等待窗口置顶
    left, top, right, bottom = win32gui.GetWindowRect(toolbar_handle)
    # 根据'ToolbarWindow32'窗体的大小,计算出按钮所在位置
    button_x = left + 266
    button_y = top + 13
    # 鼠标定位到开始按钮的坐标
    win32api.SetCursorPos((button_x, button_y))
    # 执行鼠标左键单击
    win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN | win32con.MOUSEEVENTF_LEFTUP, 0, 0, 0, 0)
    # print(button_x, button_y)


def repeat_btn(main_handle, toolbar_handle):  # 单击"循环运行"按钮
    # 置顶窗口后,获取坐标
    win32gui.ShowWindow(main_handle, win32con.SW_SHOWNORMAL)
    # ctypes.windll.user32.ShowWindow(mainHandle, 3)  # 窗口最大化
    win32gui.SetForegroundWindow(main_handle)
    # time.sleep(0.2) # 等待窗口置顶
    left, top, right, bottom = win32gui.GetWindowRect(toolbar_handle)
    # 根据'ToolbarWindow32'窗体的大小,计算出按钮所在位置
    button_x = left + 266 + 26
    button_y = top + 13
    # 鼠标定位到循环按钮的坐标
    win32api.SetCursorPos((button_x, button_y))
    # 执行鼠标左键单击
    win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN | win32con.MOUSEEVENTF_LEFTUP, 0, 0, 0, 0)
    # print("-------------------------")
    # print("检查是否点击了 循环 按钮!")


"""
  【控制BSSim软件】----End
  <<<
"""

"""
  >>>
  【获取VBS建立的文件】----Start     缺少识别TXT文本内容部分的代码,因需求不明确,所以未编写
"""


def get_files(folder_path):
    files_path = glob.glob(os.path.join(folder_path, '*.*'))  # 获取指定路径下所有文件的绝对路径
    return files_path


def file_size(files_path):
    file_size = None
    # print('检查VBS建立的TXT文件:', end='')
    if len(files_path):
        # print("已识别到TXT文件!")
        file_size = os.path.getsize(files_path[0])  # 取出文件路径下,第一个文件
        # print("TXT文件的大小为:", file_size)
    else:
        print("TXT File Not Found!")
    return file_size  # 返回文件大小


def read_txt():
    file_update_log = [0]  # 记录txt文本内容变更
    while True:
        print("-" * 30)
        print("[%s]" % time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())))
        folder = r'C:\Users\30346\Desktop\temp'  # 目标文件夹的绝对路径
        files = get_files(folder)
        size_data = file_size(files)
        # print("size_data:", size_data)
        '''判断 file_updata_log 列表中txt大小数据是否已经存在'''
        end_log = file_update_log[len(file_update_log) - 1]  # 提取列表末尾的值,与当前得到的TXT文本大小数据进行对比
        # print("end_log:", end_log)
        if size_data == end_log:
            # print("当前获取的TXT文本大小为:%r,log记录列表中最后的值为:%r,相等"%(size_data, end_log), end = '')
            print("×【TXT内容没有更新】")
            print("直接进行下一次的数据获取。")
        else:
            # print("当前获取的TXT文本大小为:%r"%(size_data), end = '')
            print("√【TXT内容有更新】")
            print("-------------【识别TXT文件中……】-------------")
            time.sleep(5)  # 假装在识别txt内容,后续会删掉
            '''
                这里缺少识别TXT文本内容代码--需求未明确,待定
            '''
            '''调用摄像头,并拍照'''
            print("-------------【5秒后对调用摄像头拍照】-------------")
            time.sleep(5)
            try:
                take_a_picture()
            except:
                print("拍照后发生了错误,但不要惊慌,并没有不好的事情发生。")
            print("-------------【拍照结束/可以进入指定文件夹查看】程序将在5秒后继续运行-------------")
            time.sleep(5)
            # print("-->执行添加新记录到log记录列表-->然后进行下一次的数据获取")
            file_update_log.append(size_data)  # 添加新记录到 file_updata_log 列表
            # print("file_updata_log 列表已更新:", file_updata_log)
        time.sleep(1)  # 识别TXT文件的频率
        # if 按下某个按钮:
        #     break
    # print("*"*50) # break后,执行这里的代码


"""
  【获取VBS建立的文件】----End
  <<<
"""

"""
  >>>
  【摄像头拍照】----Start
"""


def take_a_picture():
    output_dir = r'C:\Users\30346\Desktop\Camera Test\photo'  # 照片存储路径
    if os.path.exists(output_dir) is False:  # 没找到文件,就创建一个
        os.mkdir(output_dir)
    output_dir = r'C:\Users\30346\Desktop\Camera Test\photo'
    index = time.strftime('%Y%m%d %H%M%S',time.localtime(time.time()))  # 图片以当前时间命名
    cap = cv2.VideoCapture(0)
    cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1920)
    cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 1080)
    ret, frame = cap.read()
    cv2.imshow("test", frame)
    cv2.imwrite("%s/%s.jpg" % (output_dir, index), cv2.resize(frame, (1920, 1080), interpolation=cv2.INTER_AREA))
    cap.release()
    cv2.destroyAllWindows()  # 销毁窗口


# """  按键拍摄,先注释了,以后可能用得着
#     while True:
#         ret, frame = cap.read()
#         cv2.imshow("test", frame)
#         if cv2.waitKey(1) & 0xFF == ord('q'):
#             cv2.imwrite("%s/%d.jpg" % (output_dir, index), cv2.resize(frame, (1920, 1080), interpolation=cv2.INTER_AREA))
#             break
#     cap.release()
#     cv2.destroyAllWindows()
# """


"""
  【摄像头拍照】----End
  <<<
"""


def run():
    a = check_app_status()
    if len(a) == 0:
        print("-------------【先打开BSSim软件】-------------\n[%s]\n10秒后Python自动进行下一次检测,请提前打开BSSim软件!" % time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time())))
        time.sleep(10)
        run()
    else:
        print("-------------【已检测到BSSim软件】-------------")
        print("【提示1】需手动选择需要跑的VBS脚本!:-------------------------------------------------------------【是否需要Python控制BSSim运行不同的VBS?待定!】")
        print("\n【已完成的功能1】Python控制BSSim运行/暂停:--------------------------------------------------------【如何使用该功能?方案还需明确!】")
        print("【已完成的功能2】Python读取VBS是否建立了TXT文本")
        print("【已完成的功能3】Python控制摄像头进行拍照,并保存:--------------------------------------------------【图片已拍照时间命名,可自定义格式】")
        print("【已完成的功能4】Python循环读取VBS建立的TXT文本变更情况,并做出识别TXT文本内容、控制摄像头拍照等响应:----【功能根据需求做变更】")
        print("\n【未添加的功能1】Python读取VBS建立的文本内容:------------------------------------------------------【VBS建立的TXT文本[内容格式规范]未定,Python代码暂时不加,代码的编写难度较低】")
        print("【未添加的功能2】Python图片对比:------------------------------------------------------------------【因方案变更未摄像头拍照,之前的代码还需调试】")
        print("-------------60秒后程序自动运行!-------------")
        time.sleep(60)
        app_main = get_main_handle()  # 主窗体句柄
        app_toolbar = get_toolbar_handle(app_main)  # 子窗体句柄--工具栏窗体句柄
        # repeat_btn(app_main, app_toolbar)  # 点击BSSim循环运行按钮
        '''点击运行/停止按钮'''
        # run_and_stop_btn(app_main, app_toolbar)
        '''读取VBS建立的txt文件'''
        read_txt()  # 一直就在识别TXT着里循环运行


run()
版权声明

本文基于《署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)》许可协议授权
文章链接:https://tooler.club/archives/python-automation-study-notes.html (转载时请注明本文出处及文章链接)

如果觉得我的文章对你有用,请随意赞赏

2条评论

    Tooler

    最近代码重写了,上传到 http://git.hangsir.com:3000/hang/Smoke

    作者 Windows10 169 天前回复

    在程序的循环执行上还存在很大的问题,不清楚怎么做好它,现在只能保证有结果,却保证不了代码质量。

    游客 Windows7 173 天前回复