app自动化测试(Android)-- 参数化用例

简介: app自动化测试(Android)-- 参数化用例

参数化是自动化测试的一种常用技巧,可以将测试代码中的某些输入使用参数来代替。以百度搜索功能为例,每次测试搜索场景,都需要测试不同的搜索内容,在这个过程里面,除了数据在变化,测试步骤都是重复的,这时就可以使用参数化的方式来解决测试数据变化,测试步骤不变的问题。

参数化就是把测试需要用到的参数写到数据集合里,让程序自动去这个集合里面取值,每条数据都生成一条对应的测试用例,直到集合里的值全部取完。

使用方法

使用 Appium 测试框架编写测试用例时,通常会结合单元测试框架一起使用。使用测试框架的参

  • Python 版本
@pytest.mark.parametrize("argvnames",argvalues)
  • Java 版本
@ParameterizedTest
@ValueSource(strings = argvalues)

不同语言的单测框架支持的参数传递方式也不一样。一般情况,会在测试用例上添加一个装饰器,以python语言的 pytest 为例,在测试用例上添加参数化需要的装饰器 @pytest.mark.parametrize() ,这里需要传入两个参数 “argnamest” 与 “argvalues”,第一个参数需要一个或者多个变量来接收列表中的每组数据,第二个参数传递存储数据的列表。测试用例需要使用同名的字符串接收测试数据(与“argvnames”里面的名字一致),且列表有多少个元素就会生成并执行多个测试用例。下面示例使用使用参数化定义三组数据,每组数据都存放在一个元组中,分别将元组中的数据传入(test_input,expected)参数中,示例代码如下:

  • Python 版本
# content of test_expectation.py
import pytest

@pytest.mark.parametrize("test_input,expected", [("3+5", 8), ("2+4", 6), ("6*9", 42)])
def test_eval(test_input, expected):
    assert eval(test_input) == expected

运行结果如下:

...
test_expectation.py ..F

test_input = '6*9', expected = 42

    @pytest.mark.parametrize("test_input,expected",
    [("3+5", 8), ("2+4", 6), ("6*9", 42)])

    def test_eval(test_input, expected):
>       assert eval(test_input) == expected
E       AssertionError: assert 54 == 42
E        +  where 54 = eval('6*9')

test_expectation.py:6: AssertionError
  • Java 版本
public class BookParamTest {
    @ParameterizedTest
    @MethodSource("intProvider")
    void testWithExplicitLocalMethodSource(int first,int second,int sum) {
        assertEquals(first + second , sum);
    }
    static Stream<Arguments> intProvider() {
        return Stream.of(
                arguments( 3 , 5 , 8),
                arguments( 3 , 5 , 6),
                arguments( 6 , 9 , 42)
                );
    }
}

运行结果如下:

...
org.opentest4j.AssertionFailedError: 
Expected :8
Actual   :6
<Click to see difference>


 at org.junit.jupiter.api.AssertionUtils.fail(AssertionUtils.java:55)
 at org.junit.jupiter.api.AssertionUtils.failNotEqual(AssertionUtils.java:62)
 at org.junit.jupiter.api.AssertEquals.assertEquals(AssertEquals.java:150)
 at org.junit.jupiter.api.AssertEquals.assertEquals(AssertEquals.java:145)
 at org.junit.jupiter.api.Assertions.assertEquals(Assertions.java:527)
 ...

上面的运行结果可以看出,执行的三条测试用例分别对应三组数据,测试步骤完全相同,只是传入的测试数据发生了变化。

案例

使用“雪球”应用,打开雪球 APP,点击页面上的搜索输入框输入“alibaba”,然后在搜索联想出来的列表里面点击“阿里巴巴”,选择股票分类,获取股票类型为“BABA”的股票价格,最后验证价格在预期价格的 10%范围浮动,另一个搜索“小米”的结果数据测试步骤类似。

这个案例使用了参数化机制和 Hamcrest 断言机制,示例代码片断如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7sTgcSM7-1656519504956)(upload://6aFFnW8pQdXPxo9SZoipkstoqrN.png)]

参数化核心示例代码:

Python 版本

from appium import webdriver
import pytest
from hamcrest import *

class TestXueqiu:
    # 省略...
    # 参数化
    @pytest.mark.parametrize("keyword, stock_type, expect_price", [
        ('alibaba', 'BABA', 170),
        ('xiaomi', '01810', 8.5)
    ])
    def test_search(self, keyword, stock_type, expect_price):
        # 点击搜索
        self.driver.find_element_by_id("home_search").click()
        # 向搜索框中输入keyword
        self.driver.find_element_by_id(
            "com.xueqiu.android:id/search_input_text"
            ).send_keys(keyword)

        # 点击搜索结果
        self.driver.find_element_by_id("name").click()
        # 获取价格
        price = float(self.driver.find_element_by_xpath(
            "//*[contains(@resource-id, 'stockCode')\
            and @text='%s']/../../..\
            //*[contains(@resource-id, 'current_price')]"
            % stock_type
        ).text)
        # 断言
        assert_that(price, close_to(expect_price, expect_price * 0.1))
    ...

Java 版本

import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import java.util.stream.Stream;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.closeTo;
import static org.junit.jupiter.params.provider.Arguments.arguments;


public class XueqiuTest {
    // 省略...

    @ParameterizedTest
    @MethodSource
    void testSearch(String keyword, String stockType, float expectPrice) {
        //点击搜索
        driver.findElement(By.id("home_search")).click();
        //向搜索框中输入keyword
        driver.findElement(By.id("com.xueqiu.android:id/search_input_text"\
        )).sendKeys(keyword);
        //点击搜索结果
        driver.findElement(By.id("name")).click();
        //获取价格
        String format = String.format("//*[contains(@resource-id, \
        'stockCode') and @text='%s']/../../..//*[contains(@resource-id,\
         'current_price')]", stockType);
        String text = driver.findElement(By.xpath(format)).getText();
        double price = Double.parseDouble(text);
        assertThat(price , closeTo(expectPrice,expectPrice * 0.1));

    }
    static Stream<Arguments> testSearch() {
        return Stream.of(
                arguments("alibaba", "BABA", 170),
                arguments("xiaomi", "01810", 8.5)
        );
    }

}

上面的代码,传入了两组测试数据,每组有三个数据分别为搜索关键词,股票类型,及股票价格。在执行测试用例时,分别将两组数据传入测试步骤中执行,对应搜索不同的关键词,使用 Hamcrest 来实现股票价格的断言。

相关文章
|
2月前
|
XML Java 数据库
安卓项目:app注册/登录界面设计
本文介绍了如何设计一个Android应用的注册/登录界面,包括布局文件的创建、登录和注册逻辑的实现,以及运行效果的展示。
197 0
安卓项目:app注册/登录界面设计
|
3月前
|
Java 数据库 Android开发
一个Android App最少有几个线程?实现多线程的方式有哪些?
本文介绍了Android多线程编程的重要性及其实现方法,涵盖了基本概念、常见线程类型(如主线程、工作线程)以及多种多线程实现方式(如`Thread`、`HandlerThread`、`Executors`、Kotlin协程等)。通过合理的多线程管理,可大幅提升应用性能和用户体验。
150 15
一个Android App最少有几个线程?实现多线程的方式有哪些?
|
3月前
|
存储 开发工具 Android开发
使用.NET MAUI开发第一个安卓APP
【9月更文挑战第24天】使用.NET MAUI开发首个安卓APP需完成以下步骤:首先,安装Visual Studio 2022并勾选“.NET Multi-platform App UI development”工作负载;接着,安装Android SDK。然后,创建新项目时选择“.NET Multi-platform App (MAUI)”模板,并仅针对Android平台进行配置。了解项目结构,包括`.csproj`配置文件、`Properties`配置文件夹、平台特定代码及共享代码等。
272 2
|
3月前
|
XML Android开发 数据格式
🌐Android国际化与本地化全攻略!让你的App走遍全球无障碍!🌍
在全球化背景下,实现Android应用的国际化与本地化至关重要。本文以一款旅游指南App为例,详细介绍如何通过资源文件拆分与命名、适配布局与方向、处理日期时间及货币格式、考虑文化习俗等步骤,完成多语言支持和本地化调整。通过邀请用户测试并收集反馈,确保应用能无缝融入不同市场,提升用户体验与满意度。
123 3
|
3月前
|
Java 数据库 Android开发
一个Android App最少有几个线程?实现多线程的方式有哪些?
本文介绍了Android应用开发中的多线程编程,涵盖基本概念、常见实现方式及最佳实践。主要内容包括主线程与工作线程的作用、多线程的多种实现方法(如 `Thread`、`HandlerThread`、`Executors` 和 Kotlin 协程),以及如何避免内存泄漏和合理使用线程池。通过有效的多线程管理,可以显著提升应用性能和用户体验。
103 10
|
2月前
|
安全 网络安全 Android开发
深度解析:利用Universal Links与Android App Links实现无缝网页至应用跳转的安全考量
【10月更文挑战第2天】在移动互联网时代,用户经常需要从网页无缝跳转到移动应用中。这种跳转不仅需要提供流畅的用户体验,还要确保安全性。本文将深入探讨如何利用Universal Links(仅限于iOS)和Android App Links技术实现这一目标,并分析其安全性。
374 0
|
3月前
|
XML 数据库 Android开发
10分钟手把手教你用Android手撸一个简易的个人记账App
该文章提供了使用Android Studio从零开始创建一个简单的个人记账应用的详细步骤,包括项目搭建、界面设计、数据库处理及各功能模块的实现方法。
|
2月前
|
Java 测试技术 C#
自动化测试之美:从Selenium到Appium
【10月更文挑战第3天】在软件开发的海洋中,自动化测试如同一艘航船,引领着质量保证的方向。本文将带你领略自动化测试的魅力,从Web端的Selenium到移动端的Appium,我们将一探究竟,看看这些工具如何帮助我们高效地进行软件测试。你将了解到,自动化测试不仅仅是技术的展示,更是一种提升开发效率和产品质量的智慧选择。让我们一起启航,探索自动化测试的世界!
|
2月前
|
Web App开发 IDE 测试技术
自动化测试的利器:Selenium 框架深度解析
【10月更文挑战第2天】在软件开发的海洋中,自动化测试犹如一艘救生艇,让质量保证的过程更加高效与精准。本文将深入探索Selenium这一强大的自动化测试框架,从其架构到实际应用,带领读者领略自动化测试的魅力和力量。通过直观的示例和清晰的步骤,我们将一起学习如何利用Selenium来提升软件测试的效率和覆盖率。
|
1月前
|
Web App开发 设计模式 JavaScript
自动化测试之美:如何利用Selenium实现Web应用的高效测试
【10月更文挑战第29天】在软件开发的世界中,测试是确保产品质量的关键步骤。本文将带你了解如何使用Selenium这一强大的自动化测试工具,提高Web应用测试的效率和准确性。通过实际案例,我们将探索Selenium的核心功能及其在现代软件开发中的应用,旨在帮助读者掌握自动化测试的精髓,从而提升软件测试工作的整体效能。
44 0
下一篇
DataWorks