python实现测试工具(二)——简单的ui测试工具

当我们需要测试一个应用程序的 UI 时,我们需要手工点击每个 UI 元素,并提供相应的输入,观察应用程序的反应并验证应用程序是否正确。

然而,人工测试非常耗费精力和时间,因此我们需要自动化 UI 测试,以便减轻测试工程师的负担。在这篇文章中,我们将学习如何使用 Python 实现一个基本的 UI 测试工具。

前置条件

在开始这个教程之前,我们需要确保以下软件已经安装在我们的计算机上:

  • Python 2.7 或 Python 3.x
  • PyAutoGUI:一个可以控制鼠标和键盘的 Python 库
  • Pillow:一个可以操作图像文件的 Python 库

我们可以使用以下命令安装 PyAutoGUI 和 Pillow:

pip install pyautogui
pip install pillow

步骤 1:安装 PyAutoGUI 和 Pillow

如前所述,我们需要安装 PyAutoGUI 和 Pillow 来实现我们的 UI 测试工具。请在终端或命令提示符窗口中输入以下命令来安装这些库:

pip install pyautogui
pip install pillow

步骤 2:创建测试用例

在我们开始使用 UI 测试工具之前,我们需要先创建一组测试用例。测试用例应该包括测试的 UI 元素,例如输入框,按钮和标签,以及我们希望测试的预期行为。我们可以使用以下示例测试用例:

test_cases = [
    {
        "name": "Test login with valid credentials",
        "steps": [
            {
                "action": "move_to",
                "element": "username_input",
                "x_offset": 10,
                "y_offset": 10
            },
            {
                "action": "click"
            },
            {
                "action": "type_text",
                "value": "testuser"
            },
            {
                "action": "move_to",
                "element": "password_input",
                "x_offset": 10,
                "y_offset": 10
            },
            {
                "action": "click"
            },
            {
                "action": "type_text",
                "value": "testpassword"
            },
            {
                "action": "move_to",
                "element": "submit_button",
                "x_offset": 10,
                "y_offset": 10
            },
            {
                "action": "click"
            },
            {
                "action": "wait_for_element_to_appear",
                "element": "welcome_label",
                "timeout": 10
            },
            {
                "action": "verify_text",
                "element": "welcome_label",
                "expected_text": "Welcome, testuser!"
            },
        ]
    },
    {
        "name": "Test login with invalid credentials",
        "steps": [
            {
                "action": "move_to",
                "element": "username_input",
                "x_offset": 10,
                "y_offset": 10
            },
            {
                "action": "click"
            },
            {
                "action": "type_text",
                "value": "testuser"
            },
            {
                "action": "move_to",
                "element": "password_input",
                "x_offset": 10,
                "y_offset": 10
            },
            {
                "action": "click"
            },
            {
                "action": "type_text",
                "value": "incorrectpassword"
            },
            {
                "action": "move_to",
                "element": "submit_button",
                "x_offset": 10,
                "y_offset": 10
            },
            {
                "action": "click"
            },
            {
                "action": "wait_for_element_to_appear",
                "element": "error_message",
                "timeout": 10
            },
            {
                "action": "verify_text",
                "element": "error_message",
                "expected_text": "Incorrect password."
            }
        ]
    }
]

在这个示例中,我们创建了两个测试用例:一个使用有效凭据登录,另一个使用无效凭据登录。在每个测试用例中,我们添加了一组步骤,用于指定 UI 元素和执行操作,例如点击输入框,键入文本和点击按钮。我们还为每个测试用例添加了名称,以便更好地识别和管理测试用例。

步骤 3:创建 UI 测试工具类

现在我们已经准备好开始创建我们的 UI 测试工具了。我们将使用 Python 类来组织和封装我们的代码,并提高可读性和可重用性。以下是 UI 测试工具类的示例代码:

import time
import pyautogui
from PIL import ImageGrab

class UiTestTool:
    def __init__(self, resolution=None):
        if resolution is None:
            resolution = pyautogui.size()
        self.resolution = resolution

    def run_test(self, test_case):
        print("Running test: {}".format(test_case["name"]))

        for step in test_case["steps"]:
            action = step["action"]
            if action == "move_to":
                element = step["element"]
                x_offset = step["x_offset"]
                y_offset = step["y_offset"]
                position = self.get_element_position(element)
                pyautogui.moveTo(
                    position[0] + x_offset,
                    position[1] + y_offset
                )
                time.sleep(1)
            elif action == "click":
                pyautogui.click()
                time.sleep(1)
            elif action == "type_text":
                value = step["value"]
                pyautogui.typewrite(value)
                time.sleep(1)
            elif action == "wait_for_element_to_appear":
                element = step["element"]
                timeout = step["timeout"]
                start_time = time.time()
                while time.time() - start_time < timeout:
                    if self.does_element_exist(element):
                        return True
                    time.sleep(1)
                return False
            elif action == "verify_text":
                element = step["element"]
                expected_text = step["expected_text"]
                actual_text = self.get_text_for_element(element)
                if actual_text != expected_text:
                    return False
                return True

    def run_all_tests(self, test_cases):
        for test_case in test_cases:
            result = self.run_test(test_case)
            print("Test case: {}. Result: {}".format(
                test_case["name"],
                "Passed" if result else "Failed"
            ))

    def get_element_position(self, element):
        image = ImageGrab.grab()
        image.save("test.png")
        with open("test.txt", "w") as f:
            f.write(pytesseract.image_to_string(image))
        # TODO: Implement element detection using OpenCV
        return (0, 0)

    def does_element_exist(self, element):
        # TODO: Implement element detection using OpenCV
        return True

    def get_text_for_element(self, element):
        # TODO: Implement text detection using OpenCV
        return ""

在这里,我们创建了一个名为 UiTestTool 的类,用于执行 UI 测试用例。我们构造函数接受一个可选参数 resolution,用于指定屏幕的分辨率。如果没有传入分辨率,则默认使用电脑屏幕的分辨率。在 run_test 方法中,我们遍历测试用例中的每个步骤,并根据步骤指定的操作来执行操作。目前,我们支持以下操作:

  • move_to:将鼠标移动到指定的 UI 元素上。
  • click:单击当前鼠标位置。
  • type_text:使用键盘输入指定的文本。
  • wait_for_element_to_appear:等待 UI 元素出现,如果超时则返回 False。
  • verify_text:检查 UI 元素中的文本是否与预期相同。

在需要调用输入文本时,我们使用 PyAutoGUI 的 typewrite 函数模拟人手输入的文本,以便我们可以键入用户名和密码。我们使用 sleep 函数添加一秒钟的延迟,以便 UI 可以加载并响应我们的操作。

我们还实现了三个辅助方法:get_element_positiondoes_element_existget_text_for_element。目前,这些方法仍然是空的,因此它们需要实现。

步骤 4:实现辅助方法

我们现在需要实现三个辅助方法,以使我们的 UI 测试工具能够识别 UI 元素和执行复杂的操作。

get_element_position

该方法用于找到 UI 元素在屏幕上的位置。我们可以使用 PyAutoGUI 的 screenshot 函数捕捉整个屏幕的屏幕截图,并使用 Pillow 的 ImageGrab 模块保存图像。我们可以使用 OpenCV 的模板匹配技术来找到 UI 元素在屏幕截图中的位置。

def get_element_position(self, element):
    image = pyautogui.screenshot()
    image.save("screenshot.png")
    template = cv2.imread(element, 0)
    w, h = template.shape[::-1]
    res = cv2.matchTemplate(image,template,cv2.TM_CCOEFF_NORMED)
    threshold = 0.8
    loc = np.where(res >= threshold)
    if len(loc[0]) == 0 or len(loc[1]) == 0:
        return (0, 0)
    x = int(loc[1][0] + w/2)
    y = int(loc[0][0] + h/2)
    return (x, y)

在上面的代码中,我们首先使用 PyAutoGUI 的 screenshot 函数捕捉屏幕截图,并使用 Pillow 的 ImageGrab 模块保存屏幕截图。然后,我们使用 OpenCV 的 imread 函数加载 UI 元素的图像文件,并使用 matchTemplate 函数在屏幕截图中找到元素的位置。我们使用 where 函数查找元素匹配的像素坐标,并计算目标元素的位置。

does_element_exist

该方法用于检查 UI 元素是否存在。我们可以使用 get_element_position 方法找到元素的位置,并检查是否返回了有效的坐标。

def does_element_exist(self, element):
    position = self.get_element_position(element)
    return position[0] + position[1] > 0

get_text_for_element

该方法用于检索 UI 元素中的文本。我们需要首先使用 PyAutoGUI 的 screenshot 函数捕捉整个屏幕截图,并使用 Pillow 的 ImageGrab 模块保存屏幕截图。我们可以使用 OpenCV 的模板匹配技术来定位元素的位置,并使用 Pytesseract 模块识别屏幕截图中的文本。

def get_text_for_element(self, element):
    position = self.get_element_position(element)
    if position[0] + position[1] == 0:
        return ""
    x = position[0]
    y = position[1]
    w = 100
    h = 100
    image = ImageGrab.grab(bbox=(x, y, x+w, y+h))
    image.save("element.png")
    text = pytesseract.image_to_string(image)
    return text.strip()

在上面的代码中,我们首先使用 get_element_position 方法找到 UI 元素在屏幕上的位置。如果 UI 元素不存在,则返回空字符串。否则,我们使用 ImageGrab 模块捕捉相应区域的屏幕截图,并将其保存为 image.png 文件。然后,我们使用 Pytesseract 模块对图像进行 OCR,并将识别出的文本返回。

步骤 5:运行测试用例

我们已经创建了测试用例,添加了测试代码,并实现了辅助方法,现在我们可以运行我们的测试用例了。我们可以使用以下代码运行测试:

test_tool = UiTestTool()
test_tool.run_all_tests(test_cases)

示例说明

这里提供两个示例说明:

示例 1

假设我们正在测试一个基于 Web 的应用程序,我们需要测试登录功能。我们将创建以下两个测试用例:

test_cases = [
    {
        "name": "Test login with valid credentials",
        "steps": [
            {
                "action": "move_to",
                "element": "username_input.png",
                "x_offset": 10,
                "y_offset": 10
            },
            {
                "action": "click"
            },
            {
                "action": "type_text",
                "value": "testuser"
            },
            {
                "action": "move_to",
                "element": "password_input.png",
                "x_offset": 10,
                "y_offset": 10
            },
            {
                "action": "click"
            },
            {
                "action": "type_text",
                "value": "testpassword"
            },
            {
                "action": "move_to",
                "element": "submit_button.png",
                "x_offset": 10,
                "y_offset": 10
            },
            {
                "action": "click"
            },
            {
                "action": "wait_for_element_to_appear",
                "element": "welcome_label.png",
                "timeout": 10
            },
            {
                "action": "verify_text",
                "element": "welcome_label.png",
                "expected_text": "Welcome, testuser!"
            }
        ]
    },
    {
        "name": "Test login with invalid credentials",
        "steps": [
            {
                "action": "move_to",
                "element": "username_input.png",
                "x_offset": 10,
                "y_offset": 10
            },
            {
                "action": "click"
            },
            {
                "action": "type_text",
                "value": "testuser"
            },
            {
                "action": "move_to",
                "element": "password_input.png",
                "x_offset": 10,
                "y_offset": 10
            },
            {
                "action": "click"
            },
            {
                "action": "type_text",
                "value": "incorrectpassword"
            },
            {
                "action": "move_to",
                "element": "submit_button.png",
                "x_offset": 10,
                "y_offset": 10
            },
            {
                "action": "click"
            },
            {
                "action": "wait_for_element_to_appear",
                "element": "error_message.png",
                "timeout": 10
            },
            {
                "action": "verify_text",
                "element": "error_message.png",
                "expected_text": "Incorrect password."
            }
        ]
    }
]

test_tool = UiTestTool()
test_tool.run_all_tests(test_cases)

在这个示例中,我们测试的 Web 应用程序包括一个登录表单,其中包含用户名和密码输入框以及登录按钮。我们使用图像文件(例如 username_input.pngpassword_input.png)来识别 UI 元素。

在第一个测试用例中,我们使用有效凭据登录,期望应用程序返回欢迎消息并显示用户名。在第二个测试用例中,我们使用无效凭据登录,期望应用程序返回错误消息。

示例 2

假设我们正在测试一个桌面应用程序,我们需要测试创建新文件功能。我们将创建以下测试用例:

test_cases = [
    {
        "name": "Test creating a new file",
        "steps": [
            {
                "action": "move_to",
                "element": "file_menu.png",
                "x_offset": 10,
                "y_offset": 10
            },
            {
                "action": "click"
            },
            {
                "action": "move_to",
                "element": "new_file_menu_item.png",
                "x_offset": 10,
                "y_offset": 10
            },
            {
                "action": "click"
            },
            {
                "action": "wait_for_element_to_appear",
                "element": "untitled_file_name.png",
                "timeout": 10
            }
        ]
    }
]

test_tool = UiTestTool()
test_tool.run_all_tests(test_cases)

在这个示例中,我们测试的桌面应用程序包含一个 “文件” 菜单,其中包含一个 “新建” 菜单项。我们使用图像文件(例如

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:python实现测试工具(二)——简单的ui测试工具 - Python技术站

(0)
上一篇 2023年6月10日
下一篇 2023年6月10日

相关文章

  • js与css实现弹出层覆盖整个页面的方法

    JS和CSS实现弹出层覆盖整个页面的方法主要有两种,分别是使用绝对定位和fixed定位。 使用绝对定位实现弹出层覆盖整个页面 在HTML文件中创建一个div元素,用于存放弹出层内容: <div id="overlay"> <div id="popup"> <h2>弹出层标题</…

    css 2023年6月10日
    00
  • 创建图片对比slider滑块示例详解

    创建图片对比 slider 滑块示例的详细攻略如下: 1. 准备工作 首先,创建一个带有图片的 HTML 元素(通常是 或 ),设置它们的宽度、高度、背景和位置等样式属性。具体来说,需要创建两个元素(比如说A和B),它们的位置要重叠在一起,并且其中一个的 opacity 设置为0,如下所示: <div class="image-contain…

    css 2023年6月10日
    00
  • CSS变量实现主题切换的方法

    下面我来为你详细讲解CSS变量实现主题切换的方法。 什么是CSS变量 CSS变量(Custom Properties)是CSS3的新特性,可以使用 — 标志来定义,并通过 var() 函数来使用。例如: :root { –color-primary: #007bff; } .header { background-color: var(–color-p…

    css 2023年6月9日
    00
  • excel表格如何制作导航栏效果 制作导航栏切换效果的方法

    关于“excel表格如何制作导航栏效果 制作导航栏切换效果的方法”的完整攻略,我将为您提供以下的详细说明: 制作导航栏效果 首先,打开需要添加导航栏的excel表格,在第一行创建一个导航栏区域,例如B1:F1。 在导航栏区域中输入需要添加的导航链接名称,例如“首页”、“联系我们”等等。 选中导航栏区域,使用鼠标右键或者点击“开始”选项卡中的“格式为表格”按钮…

    css 2023年6月11日
    00
  • Vue 实现轮播图功能的示例代码

    下面我将为你详细讲解Vue实现轮播图功能的完整攻略。 1. 准备工作 在开始编写轮播图功能的示例代码之前,首先需要准备的是 Vue 的基本开发环境。确保你已经完成了以下几个环节: 安装了 Node.js 安装了 Vue-CLI 创建了 Vue 项目 2. 组件设计 在 Vue 中,轮播图功能通常需要采用组件的形式进行封装。因此,示例代码中的第一个关键步骤就是…

    css 2023年6月10日
    00
  • css3弹性盒子flex实现三栏布局的实现

    首先,我们需要了解什么是CSS3弹性盒子布局(flexbox)。它是一种新的布局方式,可以更方便、快速地实现复杂的布局效果,尤其适用于响应式布局和移动端开发。 下面是实现三栏布局的步骤: 设置容器的display为flex 将三个元素(左栏、中栏、右栏)包裹在一个容器中,并将容器的display设置为flex,这样它们就成为了flex布局下的一组弹性盒子。 …

    css 2023年6月11日
    00
  • 使用css实现三角符号效果

    下面是使用CSS实现三角符号效果的完整攻略: 1.使用border实现三角形 我们可以利用CSS的border属性来实现三角形。以右三角形(实例1)为例,代码如下: .triangle { width: 0; height: 0; border-top: 20px solid transparent; border-right: 20px solid red…

    css 2023年6月10日
    00
  • html5 分层屏幕适配的方法

    HTML5分层屏幕适配是指根据设备的不同屏幕分辨率和尺寸制作适合不同屏幕的网页。下面是HTML5分层屏幕适配的完整攻略: 1. 使用meta viewport标签 使用meta viewport标签可以控制网页在移动设备上的显示方式和缩放等级。以下是基本的meta viewport标签设置: <head> <meta name="…

    css 2023年6月10日
    00
合作推广
合作推广
分享本页
返回顶部