软件测试案例|使用 pytest+selenium 进行UI自动化测试(源码+视频)

软件测试案例:使用 pytest+selenium 进行UI自动化测试

01

实验概述

pytest是一个非常成熟的全功能的Python测试框架,编写用例格式简单,拥有比较丰富好用的插件,例如:pytest-html是完美的html测试 告生成插件;pytest-rerunfailures可以令失败case重复执行。通过本实验,可以基本了解pytest的基本使用。

英文文档地址:https://docs.pytest.org/en/stable/

中文文档地址:https://www.osgeo.cn/pytest/

使用pytest+selenium 实现对UI界面自动化测试。

02

实验目的

1.练习编写Python代码

2.学习使用pytest测试框架

3.了解pytest的基本使用,运行方式

4.会使用命令行执行测试用例

5.理解命令行执行参数的意义如 -s -v -m,理解测试结果符 代表的含义。

6.理解Conftest.py使用,作用和场景

7.断言使用python的原生断言assert

8.当写了多个测试用例时候,可将测试用例分组:利用@pytest.mark.p0

9.熟悉pytest中的插件pytest-html 用来出测试 告。

03

实验要求

1. 建立项目。

2. 项目下面至少包含:

-data 文件夹

-tests 包

-report 文件夹

3. 在tests文件夹下面,创建test_ 开头,或者以_test结尾的 .py 文件。

4. 模块(.py)文件中,定义函数名以 test_开头,编写至少3个测试用例。

5. 将测试用例标上合适的标签 @pytest.mark.smoke 或 @pytest.mark.p0 将测试用例分组,以方便后面分组运行测试用例。

6. 使用 pytest.main([参数列表])方式运行测试用例。

7. 在cmd命令窗口,用命令行方式运行测试用例。

8. 记录上面2种运行方式的运行结果,并将关键测试步骤截图。

9. 使用pytest-html插件生成测试 告并截图。

04

实验过程

1.安装pytest, selenium, pytest-html, chromedriver

1) 打开命令行,输入命令:pip install pytest

如果出现如图1所示的 错,这样一段话表示的是因为 络的问题超时,需要使用国内的镜像源来加速。可以按Ctrl+C退出,然后可以去淘宝,豆瓣等镜像找到资源进行下载,这里我使用的是豆瓣源。

图1 “pip install pytest”可能出现的 错

输入命令:pip install -U pytest -i http://pypi.douban.com/simple/ –trusted-host pypi.douban.com

这里的-U就是–upgrade,意思是如果已安装就升级到最新版。运行后结果如图2所示,可以看到pytest由6.0.1升级到了最新的6.2.4。

图2 pytest升级成功

2)安装selenium和pytest-html方法类似,如图3、图4所示,将pytest换成对应名称即可。

图3 selenium安装成功

图4 pytest-html安装成功

安装成功后,可以输入pytest –version和pip show selenium来查看一下pytest和selenium的版本 ,如图5所示分别为6.2.4和3.141.0。

图5 查看pytest和selenium的版本

3) 安装chromedriver

chromedriver的版本一定要与Chrome的版本一致,不然就不起作用。首先需要查看Chrome版本,如图6所示,在浏览器中输入chrome://version/

图6 查看Chrome版本

例如我的版本是90.0.4430,所以点这里下载,如图7所示。

https://sites.google.com/chromium.org/driver/downloads

图7 选择版本对应的ChromeDriver

完成后在cmd下输入chromedriver验证是否安装成功,如图8所示。

图8 ChromeDriver安装成功

2.练习使用pytest

1)建立项目PracticePytest,及项目下面包含的三个文件夹:-data 文件夹,-tests 包,-report 文件夹,如图9所示。

图9 PracticePytest目录结构

2)在tests下新建test_sample.py,编写第一个测试用例,如图10所示。使用标准的python assert 用于验证Python测试中的期望和值。

图10 test_sample.py内容

3)在项目根文件夹路径下开启cmd,输入命令:pytest,结果如下。pytest运行规则:查找当前目录及其子目录下以test_*.py或*_test.py文件,找到文件后,在文件中找到以test开头的函数并执行。运行结果如图11所示。

图11 test_sample.py运行结果

这个 [100%] 指运行所有测试用例的总体进度。完成后,pytest会显示一个失败 告,因为func(3)不返回5。

4)编写更多测试用例。前面是写的一个test开头的测试函数,当用例有多个的时候,写函数就不太合适了。这时可以把多个测试用例,写到一个测试类里,如图12所示。

图12 test_class.py内容

pytest会找到符合规则(test_.py和_test.py)所有测试,因此它会发现两个文件有test_前缀。我们现在只想运行其中一个,可以指定传递文件名test_class.py来运行模块,切换至子目录tests下后输入命令:pytest test_class.py,运行结果如图13所示。

图13 test_class.py运行结果

可以看到第一、三个测试通过,第二个测试失败。并且可以在断言中轻松查看失败的原因。

5)可以看到我其实在test_class.py为测试类编写了主函数,这是cmd之外另一种运行测试用例的方式,即使用pytest.main([参数列表])方式。如图14所示,直接运行test_class.py即可。

图14 参数列表方式运行测试用例

6)可以看到上面主函数的参数列表中除了要运行的文件,还有一个-q参数,如果改成-s,效果如图15所示。

图15 执行参数-s的效果

-q, –quiet和-s, –capture=method都是pytest的运行参数,-q是安静模式,不输出环境信息,只显示整体测试结果;-s 用于显示测试函数中print函数输出,因为默认情况下写在用例中的print或者log输出,都不会在测试结果中展示,如果想看到用例中的标准输出,那么需要加上-s参数。

另外一些常见的运行参数有-v, –verbose用于显示更详细的、每个测试函数的执行结果;-m MARKEXPR,只能运行有相应标识的测试用例等等,-h, –help帮助,可以查询帮助信息,看到其他运行参数如何使用,如图16所示。

图16 pytest的help文档

7) -m MARKEXPR,使用这个参数,测试用例要使用@pytest.mark.marker修饰。

a) 例如,我们修改test_class.py,使用@pytest.mark.group1和@pytest.mark.group2来修饰测试其中的用例函数,如图17所示。

图17 添加mark的test_class.py

输入命令:pytest –m “group1” test_class.py,运行结果如图18所示。

注意,-m后面不能带’’(单引 ),只能带“”(双引 ),不然识别不到。

图18 pytest –m “group1” test_class.py运行结果

最后一行总结信息可以看到三个测试用例,一个未通过,一个未选中。

b) 根据长长的 错信息可以知道,当使用-m参数执行 mark 标记的用例时,pytest会发出warning信息 “PytestUnknownMarkWarning: Unknown pytest.mark.login – is this a typo? ”,就是说这是一个 pytest 未知的一个标记,为了消除warning,需要在pytest的配置文件中注册 mark 标记。

首先在项目根目录创建一个文件pytest.ini,这是pytest 的配置文件;然后在pytest.ini文件的markers 中写入mark 标记,冒 “:”前面是标记名称,后面是mark标记的说明,可以是空字符串;注意pytest.ini 文件中只能使用纯英文字符。pytest.ini内容如图19所示。

图19 pytest.ini内容

再次运行之前的指令,如图20所示,可以看到warning已经全都没有了。

图20 消除warning后的运行结果

c) 如果要运行多个标识的话,可以按照-m “mark1 and not mark2”的格式用表达式。

pytest -m “group1 or group2” 运行有group1标识或group2标识用例,运行结果如图21所示。

图21 pytest -m “group1 or group2”运行结果

pytest -m “group1 and group2” 运行有group1和group2标识的用例,运行结果如图22所示。

图22 pytest -m “group1 and group2”运行结果

pytest -m “group1 and not group2” 运行有group1和没有group2标识的用例,运行结果如图23所示。

图23 pytest -m “group1 and not group2”运行结果

8) fixture

fixture的作用类似unittest中的setup和teardown,可以做测试前后的初始化设置,实现如测试数据准备,链接数据库,打开浏览器等这些操作;实现测试用例的前置条件;支持经典的xunit fixture,像unittest使用的setup和teardown;可以实现unittest不能实现的功能,比如测试用例之间传递参数和数据。

fixture通过@pytest.fixture装饰器装饰一个函数,这个函数就是一个fixture。如图24所示,新建文件test_fixture.py,体会一下fixture的使用。

图24 test_fixture.py内容

fixtureFunc这个函数就是一个fixture,fixture函数内部可以实现一些初始化操作。输入命令:pytest -s test_fixture.py,运行结果如图25所示。

图25 pytest -s test_fixture.py运行结果

调用fixture有三种方式,如上图就是fixture的名字直接作为测试用例的参数。

还可以在每个函数或者类前使用@pytest.mark.usefixtures(‘fixture’)装饰器装饰,如图26所示。输入命令:pytest -s test_fixture.py,运行结果如图27所示。

图26 使用装饰器的test_fixture.py

图27 pytest -s test_fixture.py运行结果

也可以指定fixture的参数autouse=True,如图28所示,这样fixture作用范围内的每个测试用例会自动调用fixture,默认是函数级别的。输入命令:pytest -s test_fixture.py,运行结果如图29所示。

图28 指定fixture的参数autouse=True

图29 pytest -s test_fixture.py运行结果

从结果可以看到每个测试用例执行前都自动执行了fixture。

这三种方式都可以使用fixture,但是只有第一种可以调用fixture的返回值,即如果测试用例需要使用fixture返回的参数必须要用第一种方法。

fixture的scope参数可以控制fixture的作用范围,默认为function,session>module>class>function。

-function:每一个函数或方法都会调用;

-class:每一个类调用一次,一个类中可以有多个方法;

-module:每一个.py文件调用一次,该文件内又有多个function和class;

-session:是多个文件调用一次,可以跨.py文件调用,每个.py文件就是module,通常这个级别会结合conftest.py文件使用。

9) conftest.py

conftest.py是一个配置文件,单独管理一些预置的操作场景,pytest里面默认读取conftest.py里面的配置。配置时需要注意:conftest.py配置脚本名称是固定的,不能改名称;conftest.py与运行的用例要在同一个pakage下,并且有__init__.py文件;不需要import导入 conftest.py,pytest用例会自动查找。

如图30、31、32所示,在tests文件夹下创建conftest.py, 和两个测试用例test_01.py, test_02.py。

图30 conftest.py内容

图31 test_01.py内容

图32 test_02.py内容

执行结果如图33所示,可以看到两个测试文件的测试用例执行前都执行了conftest.py文件中的login方法。

图33 test_01.py, test_02.py运行结果

10) pytest-html

pytest-html用于html格式的测试 告,在pytest命令后加上参数–html=path即可使用。例如输入命令pytest –html=../report/report01.html,在report目录下生成名为report01.html的测试 告,运行结果如图34、35、36所示。

图34 pytest –html=../report/report01.html运行结果

图35 report目录

图36 report01.html内容

3. 练习使用selenium

在PracticeSelenium文件夹下新建一个python_org_search.py文件,如图37所示,练习selenium基本使用。

图37 python_org_search.py内容

下面开始逐行解释代码。

1-2 selenium.webdriver 模块提供了所有WebDriver的实现,当前支持的WebDriver有:Firefox, Chrome, IE and Remote。Keys类提供键盘按键的支持,比如:RETURN, F1, ALT等。

4 我这里用的是chrome浏览器,所以创建一个Chrome WebDriver的实例。

5 driver.get方法将打开URL中填写的地址,WebDriver将等待,直到页面完全加载完毕(其实是等到“” 方法执行完毕),然后返回继续执行该脚本。值得注意的是,如果这个页面使用了大量的Ajax加载,WebDriver可能不知道什么时候页面已经完全加载,Waits可以解决这个问题。

6 用assert的方式确认标题是否包含“Python”一词。

7 WebDriver提供了大量的方法让我们去查询页面中的元素,这些方法形如:find_element_by_*。例如:包含name属性的input输入框可以通过 find_element_by_name方法查找到。

8-10 我发送了一个关键字,这个方法的作用类似于用键盘输入关键字。特殊的按键可以使用Keys类来输入,该类继承自selenium.webdriver.common.keys,为了安全起见,先清除input输入框中的任何预填充的文本(例如:“Search”),从而避免搜索结果受影响。

11 提交页面后,会得到所有的结果。为了确保某些特定的结果被找到,使用assert。

12 最后,关闭浏览器窗口。还可以使用quit方法代替close方法,quit将关闭整个浏览器,而close只会关闭一个标签页,如果只打开了一个标签页,大多数浏览器的默认行为是关闭浏览器。

经验证以上程序可以正常运行,因为是对页面模拟一系列用户操作所以截图无法体现,会在视频中演示。

4. Pytest+Selenium实现UI自动化测试

首先,将python_org_search.py文件稍微改写成pytest形式,保存为TestAutomation文件夹下test_01.py,如图38所示。

图38 test_01.py内容

可以正常运行,如图39所示;并且打印出report01.html测试 告,如图40所示。

图39 test_01.py运行结果

图40 report01.html内容

接下来,我尝试写一个GitHub的登录测试文件。在TestAutomation文件夹下新建并编写test_02.py,如图41所示。

涉及到的用户行为是:打开GitHub登录页:https://github.com/login;输入用户名、密码,点击Sign in;点击右上角小三角,在下拉框里点击Sign out。接下来我们用selenium来模拟这个行为,并用pytest测试功能。

图41 test_02.py内容

下面开始逐行解释代码。

1-2 引入需要用到的pytest和selenium的webdriver模块。

4 声明测试方法为test_02。

5-7 打开 页,并用断言检验。

9 查找元素之前,先设置元素等待:implicitlywait。

现在的大多数的Web应用程序是使用Ajax技术。当一个页面被加载到浏览器时,该页面内的元素可以在不同的时间点被加载。这使得定位元素变得困难, 如果元素不再页面之中,会抛出ElementNotVisibleException异常。使用waits, 我们可以解决这个问题。waits提供了一些操作之间的时间间隔,主要是定位元素或针对该元素的任何其他操作。

Selenium Webdriver提供两种类型的waits -隐式和显式。显式等待会让WebDriver等待满足一定的条件以后再进一步的执行。如果某些元素不是立即可用的,隐式等待是告诉WebDriver去等待一定的时间后去查找元素。默认等待时间是0秒,一旦设置该值,隐式等待是设置该WebDriver的实例的生命周期。

我这里设置的是隐式10秒,确保页面加载完毕。

10 输入用户名。

首先,选中输入框,右键选择“检查”,即审查元素,Chrome浏览器会自动打开控制台并找到在源码中找到该元素的位置,设置高亮,如图42所示。

图42 审查元素-用户名输入框

根据这些信息,来定位这个元素。在一个页面中有很多不同的策略可以定位一个元素,这里选择用根据id查找的方式。找到这个元素后,调用send_keys方法,输入用户名。

11 输入密码。

方式同上,如图43所示。

图43 审查元素-密码输入框

12 点击Sign in。

因为这个元素没有id,所以我选择根据name查找,如图44所示。

图44 审查元素-Sign in按钮

14 检查结果。登录完成之后,需要检查是否登录成功,这里就需要有个检查点,我选择检验该页面的账户名是不是我刚才登录的这个账 。通过在控制台查阅源码,如图45所示,发现这一行有用户名信息,我选择用Xpath方法定位这个元素。

图45 控制台源码中的用户名信息

XPath是XML文档中查找结点的语法。因为HTML文档也可以被转换成XML(XHTML)文档,Selenium的用户可以利用这种强大的语言在web应用中查找元素。XPath扩展了(当然也支持)这种通过id或name属性获取元素的简单方式,同时也开辟了各种新的可能性,例如获取页面上的第三个复选框。

使用XPath的主要原因之一就是当你想获取一个既没有id属性也没有name属性的元素时, 你可以通过XPath使用元素的绝对位置来获取他(这是不推荐的),或相对于有一个id或name属性的元素(理论上的父元素)的位置来获取你想要的元素。XPath定位器也可以通过非id和name属性查找元素。

绝对的XPath是所有元素都从根元素的位置(HTML)开始定位,只要应用中有轻微的调整,会就导致定位失败。但是通过就近的包含id或者name属性的元素出发定位你的元素,这样相对关系就很靠谱,因为这种位置关系很少改变,所以可以使测试更加强大。

15 打印账户名。

16-19 判断是否登陆成功。通过判断获取到的值与期望结果是否一致实现,符合预期结果测试通过;不符合预期结果测试不通过。

21 测试完成,退出登录。先定位到右上角小三角,点击它获得下拉菜单。但是这一次审查元素定位到的位置是不准确的,如图46所示。

图46 审查元素-右上角小三角(错误)

再次点击小三角,经检验,这次定位到的元素是正确的,如图47所示。

图47 审查元素-右上角小三角(正确)

22 点Sign out退出登录。

审查元素结果如图48所示。依旧使用Xpath方式定位。

图48 审查元素-Sign out按钮

23 退出登录后,关闭浏览器。

25-26 执行pytest检测,并打印report02.html 告。

运行过程如图49所示,运行结果如图50所示,打印 告内容如图51所示。

图49 运行过程截图

图50 运行结果

图51 report02.html内容

05

实验总结

本实验主要分为安装并配置环境、练习pytest基本使用、练习selenium基本使用、使用pytest和selenium实现UI自动化测试四个部分。其中,练习pytest基本使用完全覆盖了实验目的和实验要求。并在第四部分通过脚本语言,模拟用户行为操作,接近用户真实场景,实现对 web 自动测试,以自动化测试python.org 页的搜索功能,github.com 页的登录功能为例进行了练习。通过本实验,我们基本了解了基于pytest和selenium的UI自动化测试的基本思路,熟悉了这两种测试工具的基本操作。

精彩回顾

软件测试案例

使用Appium测试Android应用程序

使用PostMan对getWeather接口进行关联测试

移动APP非功能性测试

运用Python + requests类库编写脚本测试天气预 接口

下期预告

软件测试案例

Python+Selenium+unittest完成对登录页面的自动化测试

06

视频 讲解

07

源代码下载

08

参考书籍

《软件测试技术》

ISBN:9787302573722

定价:59.80元

内容简介

本书较为全面、系统地阐述了当前软件测试领域的理论和实践知识,介绍了当前新的软件测试理论、标准、技术和工具。全书共三部分16章。第一部分(第1~7章)包括软件测试概述、软件测试模型、

软件测试方法、软件测试过程、

软件测试管理、敏捷项目测试、面向对象软件测试;

第二部分(第8~13章)包括软件测试自动化、缺陷跟踪管理、

JUnit单元测试、接口测试工具、LoadRunner性能测试、基于

Python的自动化测试;第三部分(第14~16章)包括

上书店系统测试、生活小工具微服务测试和手机视频播放App测试。每章均有实际案例作为补充,以加深读者对软件测试技术和过程的理解,做到理论与实践相结合。

本书可作为高等院校计算机、软件工程、软件测试等

相关专业软件测试相关课程的教材或教学参考书,也可供从事计算机应用开发的各类技术人员参考。

本书资源

09

精彩推荐

  • 微信小程序游戏开发│猜数字小游戏(附源码+视频)

  • Flink编程基础│Scala编程初级实践

  • Flink编程基础│FlinkCEP编程实践

  • Flink编程基础│DataStream API编程实践

  • Flink编程基础│DataSet API编程实践

  • 数据分析实战│客户价值分析

  • 数据分析实战│价格预测挑战

  • 数据分析实战│时间序列预测

  • 数据分析实战│KaggleTitanic生存预测

    声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

  • 上一篇 2022年3月4日
    下一篇 2022年3月5日

    相关推荐