自动化测试UI+API

自动化测试框架有两种模式

1.  关键字驱动模式:对于有多个项目在同时进行,公司内容基于频繁的项目研发来实现盈收的。

 

2.  POM模式:Page Object Model,页面对象模型的简称。 2013年,由Martin Fowler提出了PageObject的观点。

  • 作者的观点是一种封装思想,旨在为每个待测页面创建一个页面对象,从而将繁琐的定位操作、操作细节封装到这个页面对象中,对外只提供必要的操作接口,在调用的时候只调用提供的接口,不用去调用操作细节,最终实现程序的高内聚低耦合,使程序模块的可重用性、移植性大大增强在这种模式下,对于应用程序中的每个页面都应该有相应单独的页面类(例如:login_page、userinfo_page),类中应该包含此页面上的元素对象操作这些元素对象所需要的方法。

     

  • 在这种模式下,对于应用程序中的每个页面都应该有相应单独的页面类(例如:login_page、userinfo_page),类中应该包含此页面上的元素对象操作这些元素对象所需要的方法
  • 再将流程所关联的页面作为对象,将对象串联起来形成不同的业务流程,例如:在登录页面完成登录操作后跳转到用户中心页面进行个人信息的修改

PageObject六大原则

  • The public methods represent the services that the page offers

    用公共方法表示页面提供的服务

    例如:登录页面,有用户名输入框、密码输入框、登录按钮,于是就可以用input_username()代表输入用户名、用input_password()代表输入密码、用click_submit()代表点击登录按钮

  • Try not to expose the internals of the page

    尽量不要暴露页面的内部信息

    将操作细节封装成方法,对外只提供对应的方法供调用

  • Generally don’t make assertions

    一般不使用断言

    断言要和Page代码分开,不要将断言写在PageObject层

  • Methods return other PageObjects

    方法返回其他PageObjects

    例如:首页有个方法是点击登录图标跳转到登录页面,因此这个方法应该返回login_page

  • Need not represent an entire page

    不需要表示整个页面

    不需要对页面中的每一个元素进行建模,只需要关注我们需要用到的元素。例如:登录页面除了账号密码登录,还有快捷登录、手机短信登录、扫码登录等

  • Different results for the same action are modelled as different methods

    同一行为的不同结果可以用不同的方法来模拟

    例如:对一个页面进行操作,可能出现正确的结果或者错误的结果,可以为这两种不同的结果分别创建两个不同的方法

POM框架

  • base:base_page,基类,定义项目所需的基础方法,对Selenium一些常用的api进行二次封装,如:find_element、click、send_keys、screenshot、调用JavaScript脚本的方法以及其他与浏览器相关的操作

    为什么要有基类?

    • 由于每个页面都会频繁使用这些方法,若单纯使用Selenium原始api,可能遇到一些问题,例如:某个按钮未加载完成,但已触发了点击事件,导致元素定位不到而报错。这时就可以对原始api进行二次封装,如:加入等待时间、对异常进行捕获并打印日志等,之后所有的PageObject都继承BasePage类,后续只需要调用这些封装好的方法,增强复用性
    • 假设以后不使用Selenium这个框架,就只需要修改BasePage中的方法,不用去修改具体的测试用例业务代码
  • pages:page_object,页面对象层,也是PO的核心层,继承BasePage,管理页面元素以及操作元素的方法(将操作元素的动作写成方法)

  • cases:测试用例层,用于管理测试用例,这里会用到单元测试框架,如:Pytest、Unittest。

  • data:测试数据层,用于测试数据的管理,数据与脚本分离,降低维护成本,提高可移植性,如:yml 文件数据

  • config:配置文件层,存放整个项目需要用到的配置项,如:URL、数据库信息等

  • utils:CommonUtil,公共模块,将一些公共函数、方法以及通用操作进行封装,如:日志模块、yaml 操作模块、时间模块等

  • run.py:批量执行测试用例的主程序,根据不同需求不同场景进行组装,遵循框架的灵活性和扩展性

  • logs:日志模块,用于记录和管理日志,针对不同情况,设置不同的日志级别,方便定位问题

  • reports:测试报告层,用于测试报告的生成和管理,如:基于 Allure 生成的定制化报告

 

3.  pytest从入门到精通

一、 pytest单元测试框架

(1) 什么是单元测试框架?

单元测试是指在软件开发当中,针对软件的最小单位(函数、方法)进行正确性的检查测试。

(2) 单元测试框架

java: junit和testng

python:unittest和pytest

(3) 单元测试框架主要是做什么?

1. 测试发现:从多个文件里面去找到我们测试用例。

2. 测试执行:按照一定的顺序和规则去执行,并生成结果。

3. 测试判断:通过断言判断预期结果和实际结果的差异。

4. 测试报告:统计测试进度、耗时、通过率,生成测试报告。

二、单元测试框架和自动化测试框架有什么关系?

(1)什么是自动化测试框架

(2)作用

1. 提高测试效率,降低维护成本

2. 减少人工干预,提高测试的准确性,增加代码的重用性。

3. 核心思想是让不懂代码的人也能够通过这个框架去实现自动化测试。

(3)pytest单元测试框架和自动化测试框架的关系

单元测试框架:只是自动化测试框架中的组成部分之一。

 POM设计模式:只是自动化测试框架中的组成部分之一。

关键字驱动。。。。

全局配置文件的封装

日志监控

slenium,requst二次封装。。。

断言

报告邮件

更多。。。。。

三、pytest简介

1. pytest是一个非常成熟的python的单元框架,比unittest更灵活,容易上手。

2. pytest可以和selenium,requests,appium结合实现web自动化,接口自动化,app自动化。

3. pytest可以实现测试用例的跳过以及reruns失败用例重试。

4. pytest可以和Allure生成非常美观的测试报告。

5. pytest可以和jenkins持续集成。

6. pytest有很多非常强大的插件,并且这些插件能够实现很多实用的操作(显著特征)

  pytest

  pytest-html  (生成hmtl格式的自动化测试报告)

  pytest-xdist 测试用例分布式执行,多CPU分发。1万个用例,每个用例需要执行1秒,用一万秒,若分布式执行的话,用五个进程执行,速度增加五倍。这个插件很有用。----(参数  -n NUm)

  pytest-ordering   用于改变测试用例的执行顺序。----(装饰器@pytest.mark.run(order =3)

  pytest-rerunfires    用于用例失败后重跑。----(参数  --reruns NUM)

  allure-pytest   用于生成美观的测试报告

  安装以上插件:pip install -U pytest   一个一个装很麻烦,可以一下子都装了。

  放到requirements.txt中,在 Terminal 中  通过pip install -r requirements.txt    :在 Terminal 中  安装的都是虚拟环境下的,在cmd的窗口中安装的是全局的本地环境的。

  检查是否成功:在 Terminal 中  pytest --version

四、使用pytest,默认的测试用例的规则以及基础应用

1. 模块名必须以test_开头或者_test结尾。

2.测试类必须以Test开头,并且不能有init方法。

3. 测试方法必须以test开头

五、pytest测试用例的运行方式

1. 主函数模式

  (1)运行所有用例:pytest.main()

  (2)指定模块:pytest.main(['-vs','test_login.py'])

  (3)指定目录:pytest.main(['-vs','interface_testcase'])                                这个要看当前的rootdir是啥?可以通过上面的edit configurations来编辑rootdir。

 

 

  (4)通过nodeid指定用例运行:nodeid由模块名,分隔符,类名,方法名,函数名组成。自己实践时,函数名咋都不行。原因找到了:函数名也必须是以test_开头。

      pytest.main(['-vs','./interface_testcase/test_interface_01.py::TestInterface::test_04_interface'])

    (5) 多线程运行: pytest.main(['-vs -n= 2'])

    (6)  失败用例重跑:pytest.main(['-vs','./testcase','-n=2','--reruns=2'])

2. 命令行模式

  (1)  运行所有用例:pytest

  (2)运行指定模块:pytest -vs test_login.py

    (3) 指定目录:pytest -vs ./interface_testcase

   (4) 指定目录下的某个函数:pytest  -vs ./interface_testcase/test_interface_01.py::test_func

  (5)多线程运行:pytest -vs  -n 2

    (6)  失败用例重跑:pytest  -vs  -n 2 ./testcase  --reruns 2

  

 

  参数详解:【】以列表形式输出

  -s :表示输出调试信息,包括print打印的信息。

  -v: 表示输出更详细的信息。

  -vs:这两个参数一起用。

  -n NUM8:支持多线程或者分布式运行测试用例。

  --reruns  NUM:失败用例重跑

 

  -x:只要有一个用例报错,那么测试停止。

  --maxfail 2  失败2个用例后才会停止;

  -k   根据测试用例的部分字符串指定测试用例。

     如:pytest -vs ./testcase -k "ao"

  --html  ./report/report.html   生成html的报告

3. 通过读取pytest.ini配置文件运行。

pytest.ini这个文件它是pytest单元测试框架的核心配置文件。

1. 位置: 一般放在项目的根目录。

2. 编码:必须是ANSI,可以使用notepad++修改编码格式。

3. 作用:改变pytest默认的行为。

4. 运行的规则:不管是主函数的模式运行,命令行模式运行,都会去读取这个配置文件。

【pytest】

addopts = -vs           #命令行的参数,用空格分隔

testpaths = ./testcase            #测试用例的路

python_files = test_*.py   #模块名的规则

python_classes = Test*    #类名的规则

python _functions = test       #方法名的规则

markers =  

  smoke:冒烟用例

  usermanage: 用户管理模块

       productmanange: 商品管理模块

 

增加pytest之后报错:UnicodeDecodeError: 'utf-8'

原因:1. 中间不能有中文, 且中文要删除干净,连空格也要删除掉才行。 

在pytest.ini中增加markers的选项后,老师那里的值里面有中文就不报错,可我这里就报错,错误同上,为什么?只有删除了中文才可以通过。         

 

 

 六。 pytest执行测试用例的顺序是怎样的呢?

unittest;ASCII的顺序执行的。

默认的执行:从上到下的顺序。

用以下装饰器改变测试用例的执行顺序:
@pytest.mark.run(order =3)

七、如何分组执行测试用例?

pytest.ini中增加markers配置项

pytest -vs ./testcase/test_login.py -m "smoke"   #仅执行smoke用例。

pytest -vs ./testcase -m "smoke or usermanage"   #既执行冒烟用例,也执行用户管理的用例。

八、如何分组执行测试用例?   如何跳过不想执行的用例?

比如:我只想执行正向用例,如何做?

 (1)无跳件跳过

@pytest.mark.skip(reason="这个是测试用的,不用执行。")

(2) 有条件跳过

@pytest.mark.skipif(age>=18,reason = "已成年")

 

 --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Pytest框架实现一些前后置(固件、夹具)的处理、常用三种。

一、setup/teardown,setup_class/teardown_class所有

为什么需要这些功能?

比如:WEB自动化执行用例实前,请问需要打开浏览吗?用例执行后需要关闭浏览器吗?

 def setup_class(self):    #这个在所有的用例之前只执行一次

  print(‘在每个类执行前的初始化工作:比如:创建日志对象,创建数据库的连接’)

def setup(self):              #在每个用例实前执行一次。

  print('\n在执行测试用例实前初始化的代码,打开浏览器,加载网页')

 

 二、使用@pytest.fixture()装饰器来实现部分用例的前后置
 

 装饰器

@pytest.fixture(scope="",params="",autouse="",ids="",name="")

---------------------------------------------------------------------------------------

(1) scope表示的是被@pytest.fixture标记的方法的作用域。 function(默认),class, module, package/session.

(2)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 
posted @ 2023-03-24 08:58  yoyoma0355  阅读(64)  评论(0编辑  收藏  举报