Skip to content

自动化测试用例

自动化测试用例

这里根据手工测试用例从 P0,P1,P2 级别的用例中选择一部分实现自动化测试。

目标

  1. 提升测试效率:自动化测试可以显著加快测试进程,尤其在大量重复测试和回归测试的情况下。

  2. 增强测试可靠性:自动化测试可以避免人为疏忽和错误,一旦设定测试脚本,测试过程和结果会变得可预测和一致。

  3. 扩大测试覆盖范围:自动化测试引擎可以在有限的时间内执行大量的测试,包括一些人工测试难以完成的大规模和复杂场景的测试,大大增强了测试的广度和深度。

  4. 灵活的测试时机:自动化测试可以在任何合适的时间,如休息时间、夜间进行,而非只能在人力资源允许的时间框内进行测试。

步骤

  1. 确定测试范围:明确需要自动化的测试内容和目标,通常是频繁进行的重复性测试、时间消耗大的测试、需要大量数据输入的测试。

  2. 选择合适的自动化测试工具:根据测试需求、应用特性、团队技能等因素,选择适合的测试框架和工具。

  3. 设计并编写测试脚本:根据测试需求为应用编写自动化测试脚本,需要考虑测试的完整性和扩展性,编写完成后需要对脚本进行调试和验证。

  4. 运行与调整测试:运行测试脚本,获取测试结果,根据结果调整和优化测试脚本,形成测试与优化的循环。

  5. 报告和分析测试结果:通过自动化测试工具产生详细的测试报告,分析测试结果,提供优化应用的方向和依据。

  6. 持续优化和维护测试脚本:随着应用的更新和迭代,测试脚本也需要持续优化和维护,以适应新的测试需求。

参考示例

import os
import sys

import allure
import pytest
from appium import webdriver
from appium.webdriver.common.appiumby import AppiumBy
from appium.webdriver.common.touch_action import TouchAction

dir_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(dir_path)
from log_utils import logger


@allure.epic("ApiDemo")
class TestAppDemo:
    def setup(self):
        # 创建一个字典,desirecapbility
        caps = {}
        caps["platformName"] = "Android"
        # Android 包名和页面名,获取命令:
        # mac/linux: adb logcat ActivityManager:I | grep "cmp"
        # windows: adb logcat ActivityManager:I | findstr "cmp"
        caps["appPackage"] = "io.appium.android.apis"
        caps["appActivity"] = ".ApiDemos"
        caps["deviceName"] = "emulator-5554"
        caps["noReset"] = "true"

        # 创建driver ,与appium server建立连接,返回一个 session
        # driver 变成self.driver 由局部变量变成实例变量,就可以在其它的方法中引用这个实例变量了
        self.driver = webdriver.Remote("http://localhost:4723/wd/hub", caps)
        self.driver.implicitly_wait(5)
        logger.info(f"启动包名:{caps['appPackage']},启动页面:{caps['appActivity']}")

    def teardown(self):
        logger.info("保存当面页面截图tmp.png")
        self.driver.save_screenshot("tmp.png")
        logger.info("将截图添加到报告中")
        allure.attach.file("tmp.png", name="页面截图",
                           attachment_type=allure.attachment_type.PNG)
        self.driver.quit()

    @pytest.mark.P0
    @allure.feature("滑动验证")
    def test_seeking(self):
        """
        打开 demo.apk
        1. 点击 Animation 进入下个页面
        2. 点击 Seeking 进入下个页面
        3. 查看【RUN】按钮是否显示/是否可点击
        4. 查看【滑动条】是否显示/是否可用/是否可点击
        5. 获取【滑动条】长度
        6. 点击【滑动条】中心位置
        :return:
        """
        with allure.step("1.点击 Animation 进入下个页面"):
            logger.info("点击 Animation")
            self.driver.find_element(AppiumBy.ACCESSIBILITY_ID, "Animation").click()
        with allure.step("2.点击 Seeking 进入下个页面"):
            logger.info("点击 Seeking")
            self.driver.find_element(AppiumBy.ACCESSIBILITY_ID, "Seeking").click()
        with allure.step("3. 查看【RUN】按钮是否显示/是否可点击"):
            run_element = self.driver.find_element(AppiumBy.ACCESSIBILITY_ID, "Run")
            run_is_displayed = run_element.is_displayed()
            run_is_clickable = run_element.get_attribute("clickable")
            logger.info(f"【run】按钮是否可见:{run_is_displayed},是否可点击:{run_is_clickable}")
        with allure.step("4. 查看【滑动条】是否显示/是否可用/是否可点击"):
            seekbar_element = self.driver.find_element(AppiumBy.ID, "io.appium.android.apis:id/seekBar")
            seekbar_displayed = seekbar_element.is_displayed()
            seekbar_enabled = seekbar_element.is_enabled()
            seekbar_clickable = seekbar_element.get_attribute("clickable")
            logger.info(f"seekbar 滑动条 是否可见:{seekbar_displayed},"
                        f"是否可用:{seekbar_enabled},"
                        f"是否可点击:{seekbar_clickable}")
        with allure.step("5.获取【滑动条】长度"):
            seekbar_size = seekbar_element.size
            width = seekbar_size.get("width")
            logger.info(f"seekbar 的长度:{width}")
        seekbar_location = seekbar_element.location
        x = seekbar_location.get("x")
        y = seekbar_location.get("y")
        with allure.step("6.点击【滑动条】中心位置 移动到滑动条中心位置,y轴坐标不变,x轴坐标变化"):
            seekbar_centerx = x + width / 2
            seekbar_centery = y
            # driver.tap 用于在特定的位置进行点击操作。它可以模拟用户在屏幕上进行的轻触动作。
            # 使用 driver.tap 方法需要提供被点击的坐标位置。可以通过传递 x 和 y 坐标参数给 driver.tap 方法来指定点击的位置。
            self.driver.tap([(seekbar_centerx, seekbar_centery)])
        assert seekbar_clickable
        assert run_is_clickable

    @pytest.mark.P0
    @allure.feature("toast弹窗验证")
    @pytest.mark.parametrize('operate', ['Search', 'Add'])
    def test_toast(self, operate):
        with allure.step("点击 Views 进入下个页面"):
            logger.info("点击 Views")
            self.driver.find_element(AppiumBy.ACCESSIBILITY_ID, "Views").click()
        with allure.step("从页面的五分之三处滑动到五分之一处,即向上滑动"):
            action = TouchAction(self.driver)
            window_rect = self.driver.get_window_rect()  # 获取当前窗口的x,y轴信息。高度以及宽度
            width = window_rect['width']
            height = window_rect['height']
            x = int(width / 2)
            y_end = int(height * 1 / 5)
            y_start = int(height * 3 / 5)
            # press点击     wait设置等待时长,单位mm  move_to滑动的最终位置  release释放  perform执行
            action.press(x=x, y=y_start).wait(2000).move_to(x=x, y=y_end).release().perform()
            logger.info(f"滑动距离从{y_start}-{y_end}")
        with allure.step("点击 Popup Menu 进入下个页面"):
            logger.info("点击 Popup Menu")
            self.driver.find_element(AppiumBy.ACCESSIBILITY_ID, "Popup Menu").click()
        with allure.step("定位到Make a Popup!按钮并点击"):
            self.driver.find_element(AppiumBy.ACCESSIBILITY_ID, "Make a Popup!").click()
        with allure.step("消息框类型选择search"):
            self.driver.find_element(AppiumBy.XPATH, f"//*[@text='{operate}']").click()
        with allure.step("定位toast消息框"):
            toast = self.driver.find_element(AppiumBy.XPATH, "//*[contains(@text, 'Clicked popup')]").text
            logger.info(f"提示信息为:{toast}")
        assert operate in toast

    def test_search(self):
        with allure.step("点击 OS 进入下个页面"):
            logger.info("点击 OS")
            self.driver.find_element(AppiumBy.ACCESSIBILITY_ID, "OS").click()
        with allure.step("点击 Morse Code 进入下个页面"):
            logger.info("点击 Morse Code")
            self.driver.find_element(AppiumBy.ACCESSIBILITY_ID, "Morse Code").click()
        with allure.step("点击输入框,输入内容"):
            logger.info("输入搜索内容")
            self.driver.find_element(AppiumBy.ID, "io.appium.android.apis:id/text").send_keys("aaaa")
        result = self.driver.find_element(AppiumBy.ID, "io.appium.android.apis:id/text").text
        assert result == "aaaa"

    def test_check(self):
        with allure.step("点击 Preference 进入下个页面"):
            logger.info("点击 Preference")
            self.driver.find_element(AppiumBy.ACCESSIBILITY_ID, "Preference").click()
        with allure.step("点击 9. Switch 进入下个页面"):
            logger.info("点击 9. Switch")
            self.driver.find_element(AppiumBy.ACCESSIBILITY_ID, "9. Switch").click()
        with allure.step("点击复选框"):
            logger.info("点击复选框")
            self.driver.find_element(AppiumBy.ID, "android:id/checkbox").click()
        result = self.driver.find_element(AppiumBy.ID, "android:id/checkbox").get_attribute('checked')
        assert result