移动端自动化测试实战(四)

说明:该篇博客是博主一字一码编写的,实属不易,请尊重原创,谢谢大家!

接着上一篇博客继续往下写 :https://blog.csdn.net/qq_41782425/article/details/101213973

目录

五丶第四阶段pytest入门

5.Pytest高阶用法(一)

6.fixture场景测试

7.Pytest高阶用法(二)

六丶第五阶段PO模式

1.PO基本介绍

2.Appium方法二次封装

3.页面元素操作封装(一)


五丶第四阶段pytest入门

5.Pytest高阶用法(一)

1.pytest之fixture

说明:fixture修饰器来标记固定的工厂函数,在其他函数,模块,类或整个工程调用它时会被激活并优先执行,通常会被用于完成预置处理和重复操作

方法:fixture(scope="function", params=None, autouse=False, ids=None, name=None)
常用参数:
scope:被标记方法的作用域
    function" (default):作用于每个测试方法,每个test都运行一次
    "class":作用于整个类,每个class的所有test只运行一次
    "module":作用于整个模块,每个module的所有test只运行一次
    "session:作用于整个session(慎用),每个session只运行一次
params:(list类型)提供参数数据,供调用标记方法的函数使用
autouse:是否自动运行,默认为False不运行,设置为True自动运行

2.fixture第一个例子(通过参数引用)

  • 示例代码如下:

  • 运行脚本,read_database_data会优先于测试函数运行,通过参数调用函数名并执行pytest的fixture方法,成功执行read_database_data函数里的代码

  • 如使用通过参数引用来读写文件中数据,并判断数据,代码如下

  • 运行脚本,测试通过

3.fixture第二个例子(通过函数引用)

  • 示例代码如下

  • 运行结果同理还是成功的,write_file_data会优先于测试类运行

  • 在类中再添加一个测试方法,执行测试后,发现运行了两次write_file_data方法以及类中所有的测试方法,换句话说则是有多少个测试方法则会执行多少次write_file_data函数,原因是将装饰器放到了类上面

  • 当将装饰器放在测试方法test_01上时,则只会运行一次

4.fixture第三个例子(autouse:是否自动运行,默认为False不运行,设置为True自动运行)

  • 示例代码如下

  • 运行脚本,before函数自动优先于测试类运行,有几个测试方法,就会执行多少次before,因为scope参数默认为function" (default):作用于每个测试方法,每个test都运行一次

5.fixture第四个例子(设置作用域为function) 

  • 因为默认scope参数的值就是为function,设置不设置都一样

  • 运行脚本,与上一个例子一样

6.fixture第五个例子(设置作用域为class) 

  • 将scope参数作用域设置为class时,则只运行了一次before函数

  • 运行结果如下

7.fixture第六个例子(返回值)

  • 示例代码1如下

  • 运行脚本结果如下

  • 示例代码2如下

  • 运行脚本如下,可以发现结果运行了三次,将列表中的所有值都进行了断言

  • 示例三在Pytest_Api目录下创建一个名为conftest.py文件,这是一个全局的文件,名称为官方提供的固定名称,编写如下代码

  • 在test_api_05.py文件中创建test_b测试方法,通过传递参数的方式来断言全局文件conftest.py文件中的返回值

  • 运行脚本,查看结果,成功的获取到全局文件返回值,并进行了断言

6.fixture场景测试

场景描述:首先需要打开设置——定位到位置信息——点击进入位置信息页面(到这里为第一个部分),然后在位置信息页面点击模式——选择准确度高——点击返回按钮即保存——最后断言位置信息页面中模式是否为准确度高(这是第二部分),需要注意的是,第二部分是依赖第一部分,因为第二部分的逻辑为修改模式,第一部分为进入到微信信息页面,那么则需要用到fixture函数引用

  • 代码实现如下

  • 运行代码成功,在手机端成功修改了模式为准确度高

7.Pytest高阶用法(二)

1.跳过测试函数

根据特定的条件,不执行标识的测试函数.

方法:
    skipif(condition, reason=None)
参数:
    condition:跳过的条件,必传参数
    reason:标注原因,必传参数
使用方法:
    @pytest.mark.skipif(condition, reason="xxx")

  • 示例代码如下

  • 运行代码,test_b函数没有执行

  • 运用到场景中跳过某一测试方法,根据函数返回值来进行skipif方法中condition参数的判断条件

  • 或者将方法放到类中,也是可以的

  • 运行脚本,结果都是一样的跳过test_b测试函数的执行

2.标记为预期失败函数

标记测试函数为失败函数
方法:
    xfail(condition=None, reason=None, raises=None, run=True, strict=False)
常用参数:
    condition:预期失败的条件,必传参数
    reason:失败的原因,必传参数
使用方法:
    @pytest.mark.xfail(condition, reason="xx")

  • 用法跟跳过测试函数一样,就不用多说了,在代码中将test_b测试函数标记为预期失败函数,则测试结果中会显示1个失败

7.函数数据参数化

方便测试函数对测试属于的获取。
方法:
    parametrize(argnames, argvalues, indirect=False, ids=None, scope=None)
常用参数:
    argnames:参数名
    argvalues:参数对应值,类型必须为list
                当参数为一个时格式:[value]
                当参数个数大于一个时,格式为:[(param_value1,param_value2.....),(param_value1,param_value2.....)]
使用方法:
    @pytest.mark.parametrize(argnames,argvalues)
    ⚠️ 参数值为N个,测试方法就会运行N次

  • 单个参数示例代码如下

  •  多个参数示例:

  • 函数返回值类型示例:

  • 通过return_test_data函数读取data.txt文件数据

8.小结

六丶第五阶段PO模式

1.PO基本介绍

测试PO模式(Page Object Model)

测试页面和测试脚本分离,即页面封装成类,供测试脚本进行调用

优点:

1.提高测试用例的可读性;
2.减少了代码的重复;
3.提高测试用例的可维护性,特别是针对UI频繁变动的项目;

缺点: 

结构复杂: 基于流程做了模块化的拆分。

2.Appium方法二次封装

系统已提供定位方法

driver.find_element_by_id()
driver.find_element_by_class_name()
driver.find_element_by_xpath()

driver.find_elements_by_id()
driver.find_elements_by_class_name()
driver.find_elements_by_xpath()

⚠️ 实际以上定位方法封装以下方法:
  find_element(by=By.XX, value=None)
  find_elements(by=By.XX, value=None)
  # by:定位类型(By.ID,By.CLASS_NAME,By.XPATH)
  # value:定位元素的属性值

  • 查看方法源码如下所示,最终核心的方法为find_element以及find_elements根据传递的by参数以及value参数的值来进行区分的

  • 那么现在只需要封装find_element以及find_elements两个核心方法即可

2.封装实现

  • 封装find_element定位元素方法以及click_element点击元素方法,通过类对象调用click_element方法传递元素定位方式以及匹配值

  • 运行代码,成功打开设置并点击更多按钮

3.Demo示例

业务场景:
  1.进入设置
  2.点击搜索按钮
  3.输入123
  4.点击搜索框返回按钮

  • 首先将上一步中的代码中的driver通过参数的方式进行使用,命名为find_element.py文件,并放到base包下

  • 然后在test_po_01模块中调用find_element模块方法,完成以上场景(这些封装PO模型博主在web自动化中已经写过了),博主这里将以上场景写成了三个测试方法,为了将控制测试方法执行的顺序,完全可以将以上场景写到一个测试方法中

  • 运行测试脚本,成功实现场景

4.显示等待

  • 在封装的核心方法find_element进行显示等待操作,设置参数timeout以及poll的固定值

  • 运行测试,没有任何问题

5.优化参数

  • 需要在我们封装的find_element模块中将调用的原生find_element方法传递的参数进行优化,前面步骤是传递的type元素定位类型以及value元素匹配值,现在则需要将这两个参数使用元组成为一个传递的参数,现在先看一个demo就明白了

  • 即在find_element模块中进行如下修改

  • 在测试模块中,修改传递的参数,如下

  • 运行脚本,测试结果与预期结果一致

3.页面元素操作封装(一)

1.确定好要封装的页面操作

  业务场景:
      1.进入设置
      2.点击搜索按钮
      3.输入123
      4.点击搜索框返回按钮
2.需要用到哪些元素和定位方法

  # 搜索按钮
  search_button = (By.ID, "com.android.settings:id/search")
  # 搜索输入框
  search_text = (By.ID, "android:id/search_src_text")
  # 搜索框返回按钮
  search_return_button = (By.CLASS_NAME,"android.widget.ImageButton")
3.依赖的定位方法

使用二次封装的方法,find_element.py文件

4.页面封装

  • 首先将test_po_01模块放到创建的scripts目录下,然后在模块中将场景中的步骤写到一个测试方法中,因为业务少,所以没有必要写成三个测试方法,博主之所以写成三个是为了方便大家观察了解

  • 在page包下创建search_page模块,将test_po_01测试模块中test_001测试方法中的操作元素的代码封装到search_page模块中,如下

  • 在scripts目录下创建test_po_02模块,在模块中导入page包下的search_page模块中的Search_Page类,通过实例化Search_Page类,通过这个类的对象来调用上一步封装的search_text方法实现场景

  • 运行脚本,成功实现场景

  • 使用pytest模块进行参数化

  • 运行脚本,成功在设置页面输入框输入列表参数

5.短信业务场景实例

场景描述:打开短信——点击新信息——添加接收人——添加消息——点击发送

  • 首先在page包下创建sms_page模块用于封装短信业务场景中的定位元素操作以及业务操作的代码

  • 紧接着在scripts测试脚本目录下创建test_po_03测试模块,在模块中通过实例化page包下的sms_page模块中的Sms_Page类,调用以上封装的方法,实现短信场景测试,博主在test_po_03模块中将业务场景分为两个测试方法进行测试,具体如下

  • 在运行脚本之前,需要注意修改pytest.ini配置文件中的python_files项的值为test_po_03.py固定值,运行脚本提示以下错误,压根就没有执行test_add_receiver方法而且执行了test_send_message测试方法,导致找不到元素,报错超时异常

  • 经过测试发现pytest.fixture装饰器与pytest.mark.run放在一起后就不会执行该测试方法了,所以需要将test_add_receiver方法上的fixture方法修改为mark.parametrize方法进行参数化

  • 再次运行测试脚本,成功实现业务场景

6.设置场景优化

  • 在第4步中对设置场景进行了简单的封装,现在将设置搜索页面元素定位模块进行拆分,之前在测试模块test_po_02中调用了search_page模块中的search_text方法完成业务场景,现在将该方法拆分成三个方法,如下红框所示

  • 在封装的元素操作模块find_element模块中的input_data输入数据方法进行优化,每当调用执行该方法的时候需将输入框内容进行清空操作,避免出现内容不一致

  • 创建test_po_04测试模块,通过调用上一步拆分出来的三个方法,来完成搜索页面场景测试

  • 运行脚本,肯定是没有问题的

7.通讯录业务场景实现(不难)

场景描述:循环添加三个联系人(打开通讯录——点击添加联系人——点击本地保存——输入姓名丶电话——点击返回按钮(保存)——点击手机返回按钮(返回上一级菜单)

  • 首先在page目录下创建telephone_page模块用于封装页面元素,因为在业务场景点击返回按钮这一块定位元素需使用到原生的find_elements方法来获取一组元素以及返回上一级菜单需要使用keyevent方法来向手机发送返回操作,也就是在base目录下的find_element模块中添加针对该业务场景的方法

  • 在telephone_page模块中则可以封装定位页面元素操作,如下所示(这些代码都很假单,唯一的需要测试数据来判断是否成功实现场景)

  • 在测试模块中完成将业务场景的步骤,分为两个测试方法进行测试(因为要实现以上的场景,就必须这样创建,不然无法循环添加联系人并每次返回

  • 运行脚本,成功实现场景

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cdtaogang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值