精华内容
下载资源
问答
  • 随着软件发展到不同的阶段对自动化会有不同的测试需求,因此也产生了多种测试类型,然而万变不离其宗,一切皆可自动化

    随着软件发展到不同的阶段对自动化会有不同的测试需求,因此也产生了多种测试类型,然而万变不离其宗,一切皆可自动化

    单元测试

    单元测试也可以看做是代码层的测试,而但凡成熟的语言都附有单元测试框架,例如Java的Junit和TestNG,例如Python的Unittest和Pytest,在很多场合我都曾强调,单元测试才是自动化的核心,从某种意义上讲具备单元测试框架的语言就都能进行单元测试的自动化执行,而这最小单元可以是一个函数、一个方法、一个类或是一个模块

    然而很多公司的研发团队虽然要求单元测试,但很少要求交付单元测试报告的,也有很多公司的单元测试是有自动化测试团队承担的,虽然测试无法穷尽,但测试不同的输入、边界值、非法值、默认值、异常情况等等是基本要求,而这些内容让研发团队自行去做,若非严格的制度限制,又如何能保证高速迭代的环境里真的能达到单元测试目的呢,研发人员的兴趣点绝大多数都在创造力上,他们更喜欢开发新东西,而对质量兴趣不大

    功能测试

    通常情况下,功能测试是测试团队介入的第一个阶段,开发人员将完成的功能特性写成文档输出给测试团队,测试团队根据这些文档开发设计测试用例,最后执行测试用例,对功能进行验证,理想情况下,如果功能特性文的规范写的足够清晰,测试团队应该在功能开发完成之前就开发完测试用例,甚至可以根据这些用例来编写自动化测试用例

    然而尽管大多数情况下,都希望根据质量体系的规范输出详尽的文档,但实操起来确是各种问题:

    • 功能文档不规范,协作之间理解不一致,出现偏差,导致设计的用例变成了无效用例
    • 需求变更,导致功能特性更新,直接影响原先的测试用例设计
    • 新功能不稳定,导致测试用例无法顺利执行

    以第三点新功能不稳定为例,过早的执行自动化测试会被不稳定的新功能阻碍住,一个严重的问题可能导致很多用例无法执行或执行失败,最终仍然需要人来干预执行结果的,认为进行判断甚至重复劳动,这就使得自动化不那么自动了,也就是说需要人值守,遇到问题后手动介入解决
    测试开发也是软件开发的一个类型,其本身的质量不能和被测系统的质量纠缠到一起,否则会让问题的排查更为复杂

    因此,如果非牛逼的研发团队,自动化测试用来辅助测试提升测试效率的角度出发更为实际,将其用于单元测试自动化,接口测试自动化,辅助自动化工具类将成为相当可行的选择,当功能相对稳定后,在全面的实现自动化测试。

    再不然,对于功能测试而言非要强行引入自动化测试,那么测试用例本身的构建和修改一定要非常迅速,自动化测试框架需要提供快速构建用例的能力,以此来响应需求的变更,测试代码的健壮性和灵活性要求非常高,从而应对不稳定的功能产生的阻塞,并且还要对灾难性的错误进行测试环境上的自动恢复

    回归测试

    回归测试时软件开发迭代阶段的一种测试,主要是保障原有的功能没有因为新功能的引入而导致功能回退,在这个阶段自动化测试将得到大量的应用,相对于新功能的不稳定,回归测试的目标是已经发布的或者稳定的功能,相应的测试代码也相对比较稳定,自动化代码也已经经过多轮的完善,执行结果相对也会稳定的多

    可用性测试及冒烟测试

    可用性测试和冒烟测试都是一种快速验证的过程,测试周期很短,为保证这种快速验证,有些测试团队会针对性的快速开发一些用例,然而这些用例往往又和实际的功能测试验证点重复,因此在大量自动化测试用例中迅速抽取核心的测试用例集,然后将测试用例集集成到整个团队的CI中,将测试用例的执行放在编译的job后作为下游任务,当编译结束后自动执行下游任务,而对于一些持续CD情况中,自动化又需要集成在发布上线前的节点,来保证上线的包不存在基本功能问题

    系统测试

    系统测试是一个复杂的测试过程,其主要目的是使被测产品的众多功能甚至是产品本身的集合,以系统级别运行时进行行为级别的验证,其测试类型非常多样且复杂,例如:

    • 相对于功能测试比较固定的测试环境,系统测试环境比较复杂,配置繁多,不固定,不稳定,在这种情况下,自动化测试需要足够灵活的应对不同的环境配置来执行相同的测试目的
    • 测试用例的兼容性要足够强,稳定性足够强,且被测系统的稳定性足够强
    • 压力测试和性能测试的需求,自动化测试应能够快速的集成相应的标准性能测试设备或工具
    • 客户场景模拟测试,即便再聪明的测试工程师能够设计出种类繁多的测试方案,总有想象不到的场景,客户才是麻烦的最佳制造者,因此很多企业会花一些经历收集客户场景,并加入到系统测试的模拟场景中

    可以看出,自动化测试要有足够的弹性来匹配不同的测试场景,而不是通过不同的测试用例来对应不同的场景,同时要具备足够的可扩展性,能够加入不同的第三方工具或者设备来满足更多的测试场景

    展开全文
  • 公司要求招一名自动化测试,能力要求不高,1年左右自动化经验+部分性能经验即可,让我出一份题,我就百度+公司项目遇到的问题,出了一份,出题整体思路是:接口自动化问题+性能问题+规划的ui、app自动化+整体质量...

    写在前面

    公司要求招一名自动化测试,能力要求不高,1年左右自动化经验+部分性能经验即可,让我出一份题,我就百度+公司项目遇到的问题,出了一份,出题整体思路是:接口自动化问题+性能问题+规划的ui、app自动化+整体质量体系建设等多方面考虑。下面是正题

    岗位JD

    在这里插入图片描述
    | 1、【技术能力】能独立完成产品线中自动化测试工作,根据测试任务,搭建软件测试环境,编写测试脚本,输出报告;
    2、【项目管理】熟练开发测试工具、测试脚本,及迭代优化测试框架,使用合理方式进行自动化管理项目;
    3、【业务推动】对测试项目的结果负责,使用合理方式推动业务端测试的效率、开发质量;
    4、【规范制定】 熟悉CI系统,完善准入/准出标准,持续提升测试效率;
    5、【效率提升】根据业务特点,引入新的测试方法和工具,探索新技术。改进测试工具或测试方法,提高效率,培训测试人员并支持技术难题解决 | |

    |-1)3年以上测试工作经验,1年以上自动化测试经验或开发经验;
    2)至少熟悉一种脚本语言,如Shell、Python、java等;
    3)至少熟悉一种测试框架,unittest、pytest、testng等;可独立完成复杂逻辑的接口自动化测试;
    4)熟悉appium、selenium可独立完成android和ios的UI自动化测试;
    5)熟悉jenkins、svn、git的搭建和使用;
    6)熟悉常用性能测试工具的使用,并可进行分析调优:ab、jmeter、loadrunner、locust等,有分布式压测经验优先;
    7)熟悉使用django开发框架,可完成web页面和功能的开发(此条可放宽);
    8)具备丰富的系统测试经验,并且能够进行系统级的原因定位与分析;
    9)具备较强的计划、组织、协调、沟通及分析能力,优秀的职业素养和团队协作精神、敬业精神,能承受工作压力;
    10)学习能力强,对技术有着特别的渴求,在关注的领域有着深入的研究,并不断创新;具备较强的技术培训能力和领导能力-|–|

    自动化测试面试题1:基础篇

    目的:验证求职者是否在自动化测试岗位有实际应用于生产的工作经验

    1、使用什么测试框架做的上一个项目的自动化测试?说下怎么做的?对自动化的理解?
    答:(junit、unittest、testng、 pytest ,优先python语言,用过pytest或unittest框架的;只会selenium能力较弱)
    2、使用什么测试框架做的上一个项目的自动化测试?说下怎么做的?对自动化的理解?
    答:最好能答出独立负责且封装页面元素、断言封装、请求封装、取参方式具体实现
    3、GET与POST的区别?
    (1)GET请求资源数据,POST向服务器传递需要处理的数据
    (2)GET传递数据大小不超过2kb,POST没有限制
    (3)GET请求的参数会在Url上暴露显示,POST请求参数在Requestbody里,所以相对GET来说,POST安全性较高
    (4)GET 请求的静态资源会被浏览器缓存,POST不会被缓存
    (5)GET传递的数据类型是文本,POST是文本或者二进制
    (6)GET请求被回退时是无害的,POST请求被回退是会被重新再执行一次
    GET和POST的使用场景:
    (1)在传递一些机密信息时必须要使用POST
    (2)只是查询获取数据时可以用GET
    (3)POST请求速率会比GET慢,因为GET请求产生一个TCP数据包;POST请求产生两个TCP数据包
    4、//*[contains(@text,“登录”)] 是什么意思?
    答:查包含登录关键字的所有元素
    5、自动化遇到用例fail掉如何排查故障?
    答:看出错log,如果能按层次说清楚排查失败:手工查应用是否真的有bug, 确认不是bug,是不是新版本引入了新的变更,调试脚本看看自己的脚本是不是因为没有等待元素出现后就操作了,是不是元素上面有其他元素出现这样操作是不是操作了其他的元素上了
    6、说说接口测试的流程和接口自动化流程,介绍一下request有哪些内容?
    答:(1)流程:获取接口文档,依据文档设计接口参数,获取响应,解析响应,校验结果,判断测试是否通过。 (2)request 内容:1,封装了get、post等;
    2、以关键字参数的方式,封装了各类请求参数,params、data、headers、token、cookie等;3,封装了响应内容,status_code、json()、cookies、url等;
    session会话对象,可以跨请求;
    7、接口测试用例的编写要点有哪些?
    1)必填字段:请求参数必填项、可选项
    2)合法性:输入输出合法、非法参数
    3)边界:请求参数边界值等
    4)容错能力:大容量数据、频繁请求、重复请求(如:订单)、异常网络等的处理
    5)响应数据校验:断言、数据提取传递到下一级接口…
    6)逻辑校验:如两个请求的接口有严格的先后顺序,需要测试调转顺序的情况
    7)性能:对接口模拟并发测试,逐步加压,分析瓶颈点
    8)安全性:构造恶意的字符请求,如:SQL注入、XSS、敏感信息、业务逻辑(如:跳过某些关键步骤;未经验证操纵敏感数据)
    8,postman的使用方式?高级用法?mock的应用场景和基础用法?
    答:A,基础使用:入参出参校验返回;
    b,Environment–配置不同的环境参数,Globals即设置全局变量,Pre-request Script–配置使用环境变量或进行前置脚本处理;
    c,团队可以更好地并行工作,前后端人员只需要定义好接口文档就可以开始并行工作,互不影响,只在最后的联调阶段往来密切,开启TDD(Test-Driven Development)模式,即测试驱动开发;
    9,你之前自动化测试的数据放哪?怎么使用?公共变量的管理方式?管理测试用例的手段?如何提高用例覆盖率?接口测试关联性接口实现方式?
    答:测试数据存放总结:
    1.对于账号密码,这种管全局的参数,可以用命令行参数,单独抽出来,写的配置文件里(如ini)
    2.对于一些一次性消耗的数据,比如注册,每次注册不一样的数,可以用随机函数生成
    3.对于一个接口有多组测试的参数,可以参数化,数据放yaml,text,json,excel都可以
    4.对于可以反复使用的数据,比如订单的各种状态需要造数据的情况,可以放到数据库,每次数据初始化,用完后再清理
    5.对于邮箱配置的一些参数,可以用ini配置文件
    6.对于全部是独立的接口项目,可以用数据驱动方式,用excel/csv管理测试的接口数据
    7.对于少量的静态数据,比如一个接口的测试数据,也就2-3组,可以写到py脚本的开头,十年八年都不会变更的。
    10,不可逆的操作,如何处理,比如删除一个订单这种接口如何测试?
    此题考的是造数据的能力,接口的请求数据,很多都是需要依赖前面一个状态的
    比如工作流这种,流向不同的人状态不一样,操作权限不一样,测试的时候,每种状态都要测到,就需要自己会造数据了。
    平常手工测试造数据,直接在数据库改字段状态。那么自动化也是一样,造数据可以用python连数据库了,做增删改查的操作
    测试用例前置操作,setUp做数据准备
    后置操作,tearDown做数据清理
    11、、说出5个以上 Linux 命令(注重考察性能测试监控常用命令?)
    答:cd、ls、grep、mkdir、pwd、ping等等,重要是性能测试常用监控命令:netstat 、top 、Nmon 、dstat、ulimit、vmstat 、tcpdump、free 、lsof ,需回答上至少两个。
    12、介绍一下你在这个项目中是如何使用 Jenkins 的。
    答:基本操作,比如定时构建执行代码等。
    13、举例说明,Linux下命令行cURL的种常见用法和示例?
    答:常用10种,这里举出三种常用:A,获取页面内容:curl+get请求;curl https://www.baidu.com
    B,把链接页面的内容输出到本地文件中:curl https://www.baidu.com > index.html
    C,使用 -d 发送 POST 请求:curl -d “userName=tom&passwd=123456” http://www.example.com/login
    14,jmeter上一个接口参数返回值做为下一个接口入参的实现方式有几种,举例?
    答:正则表达式处理器、JSON Path Extractor
    15、接口自动化中,遇到签名、鉴权加密等,如何处理的,用到哪些方法?
    答:比如MD5加密–hashlib内置库,看怎么回答怎么具体问:开放性。
    16、对pytest的理解程度?使用规范?参数化方法?说说常用装饰器?
    答:pytest是一个非常成熟的全功能的的Python测试框架,主要特点有以下几点:
    1,简单灵活,容易上手,文档丰富;
    2,支持参数化,可以细粒度地控制要测试的测试用例;
    3,能够支持简单的单元测试和复杂的功能测试,还可以用来做selenium/ appnium等自动化测试,接口自动化测试(pytest +请求);
    4,pytest具有很多第三方插件,并且可以自定义扩展,比较好用的如pytest - selenium(集成selenium),pytest-HTML(完美的HTML测试报告生成),pytest-rerunfailures(失败情况下重复执行),pytest -xdist(多CPU分发)等;
    5,测试用例的跳跃和xfail处理;
    使用规范:
    测试文件名必须以“test_”开头
    测试类以Test开头,并且不能带有 init 方法
    测试方法必须以“test_”开头
    除了有setup/teardown,还能更自由的定义fixture装载测试用例
    参数化方法:
    pytest支持在多个完整测试参数化方法:
    pytest.fixture(): 在fixture级别的function处参数化
    @pytest.mark.parametrize:允许在function或class级别的参数化,为特定的测试函数或类提供了多个argument/fixture设置。
    pytest_generate_tests:可以实现自己的自定义动态参数化方案或扩展。
    17、举例说明pytest.mark标记的使用?
    答:1,无条件跳过测试pytest.mark.skip
    2,有条件跳过测试pytest.mark.skipif
    3,标记测试功能按预期失败pytest.mark.xfail
    4,将测试功能标记为使用给定的夹具名称pytest.mark.usefixtures
    5,向特定测试项添加警告过滤器,以便更好地控制应在测试,类甚至模块级别捕获哪些警告@pytest.mark.filterwarnings
    6,自定义标记:标记指定标签
    18,自动化测试报告生成方式?如果是allure详述?
    答:@allure.severity(“critical”) # 优先级,包含blocker, critical, normal, minor, trivial 几个不同的等级
    @allure.feature(“测试模块_demo1”) # 功能块,feature功能分块时比story大,即同时存在feature和story时,feature为父节点
    @allure.story(“测试模块_demo2”) # 功能块,具有相同feature或story的用例将规整到相同模块下,执行时可用于筛选
    @allure.issue(“BUG号:123”) # 问题表识,关联标识已有的问题,可为一个url链接地址
    @allure.testcase(“用例名:测试字符串相等”) # 用例标识,关联标识用例,可为一个url链接地址

    19、什么是冒泡排序,手写一个冒泡排序?
    答:冒泡排序(Bubble Sort)也是一种简单直观的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢"浮"到数列的顶端。

    自动化测试面试题2:细节篇之语言:python基础

    目的:验证求职者自动化岗位的开发、脚本语言的基础以及熟悉程度

    1、super 是干嘛用的?在 Python2 和 Python3 使用,有什么区别?为什么要使用 super?请举例说明。
    答:super 用于继承父类的方法、属性。super 是新式类中才有的,所以 Python2 中使用时,要在类名的参数中写 Object。Python3 默认是新式类,不用写,直接可用。使用 super 可以提高代码的复用性、可维护性。修改代码时,只需修改一处。
    2、L = [1, 2, 3, 11, 2, 5, 3, 2, 5, 3],用一行代码得出 [11, 1, 2, 3, 5]
    答:list(set(L))
    3、列表和字典有什么区别?
    答:一般都是问列表和元组有什么不同。 (1)获取元素的方式不同。列表通过索引值获取,字典通过键获取。 (2)数据结构和算法不同。字典是 hash 算法,搜索的速度特别快。 (3)占用的内存不同。
    4,json和字典dict的区别?
    答:json是一种轻量级的数据交换格式
    dict是python中的数据类型(python里面的基础数据类型有:int、str、 float、list、bool、tuple、dict、set这几种类型,里面没json这种数据类型,json本质上字符串,按照key:value键值对格式的字符串;在json中空值是用Null表示,在dict中空值是用None表示)
    主要区别:json的key只能是字符串,python的dict可以是任何可hash对象(hashtable type);
    json的key可以是有序、重复的;dict的key不可以重复。
    json的value只能是字符串、浮点数、布尔值或者null,或者它们构成的数组或者对象。
    json任意key存在默认值undefined,dict默认没有默认值;
    json访问方式可以是[],也可以是.,遍历方式分in、of;dict的value仅可以下标访问。
    json的字符串强制双引号,dict字符串可以单引号、双引号;
    dict可以嵌套tuple,json里只有数组。
    json:true、false、null
    python:True、False、None
    json中文必须是unicode编码,如"\u6211".
    json的类型是字符串,字典的类型是字典。
    5,python深拷贝和浅拷贝的概念和区别?
    答:浅拷贝:拷贝最外层容器
    深拷贝:拷贝的最外层容器,还拷贝容器中的元素
    对于不可变元素,使用浅拷贝
    6、python单行注释和多行注释分别用什么?
    答:单行注释用# 多行注释用""" “”"
    7,Python垃圾回收机制?
    答:1,回收计数引用为0的对象,释放其占用空间
    2、循环垃圾回收器。释放循环引用对象
    8,如何安装第三方模块?以及用过哪些第三方模块?
    答:使用官方推荐的setuptools的包管理工具,easy – install和pip、requests模块
    9、进程、线程有什么区别?什么情况下用进程?什么情况下用线程?
    答:(1)区别:
    ① 地址空间和其它资源(如打开文件):进程之间相互独立,同一进程的各线程之间共享。某进程内的线程在其它进程不可见。② 通信:进程间通信 IPC,线程间可以直接读写进程数据段(如全局变量)来进行通信——需要进程同步和互斥手段的辅助,以保证数据的一致性。③ 调度和切换:线程上下文切换比进程上下文切换要快得多。④ 在多线程操作系统中,进程不是一个可执行的实体。(2)使用场景:同时操作一个对象的时候,比如操作的是一个全局变量,我用线程,因为全局变量是所有线程共享的。
    10,谈谈你对面向对象的理解?
    体现在三个方面: 封装、继承、多态
    继承有两种方式:
    1、将同一类的方法封装到类中
    2、将数据封装到对象中
    继承:子类拥有父类的所有方法和属性,
    好处:抽取重复代码,减少代码冗余。
    坏处:耦合性太强。
    多态:对于不同的类可以有同名的方法,同名的方法应用到不同的类可以有不同行为。

    自动化测试面试题3:细节篇之selenium

    目的:验证求职者在自动化测试岗位的selenium工具的熟悉程度

    1、selenium中如何判断元素是否存在?
    答:isElementPresent
    2、selenium中hidden或者是display = none的元素是否可以定位到?
    答:a、可以:定位是可以定位到的,但是不能操作,可以判断元素is_displayed()
    想点击的话,可以用js去掉dispalay=none的属性;b、不能:可以写JavaScript将标签中的hidden先改为0,再定位元素。两个答案都算对,说明出原因即可。
    3、selenium中如何保证操作元素的成功率?也就是说如何保证我点击的元素一定是可以点击的?
    答:添加元素智能等待时间 driver.implicitly_wait(30)
    添加强制等待时间(比如python中写 sleep)
    try 方式进行 id,name,clas,x path, css selector 不同方式进行定位,如果第一种失败可以自动尝试第二种
    4、如何提高selenium脚本的执行速度?
    答:1.少用sleep,尽量不用implicitly_wait
    2.多用显式等待方法
    3.弄个性能好的电脑具体?(看个人思路)
    5、用例在运行过程中经常会出现不稳定的情况,也就是说这次可以通过,下次就没办法通过了,如何去提升用例的稳定性?
    答:
    6、你的自动化用例的执行策略是什么?
    答:自动化测试与软件开发本质上是一样的,利用自动化测试工具,经过测试需求分析,设计出自动化测
    试用例,从而搭建自动化测试的框架,设计与编写自动化脚本,验证测试脚本的正确性,最终完成自
    动化测试测试脚本(即主要功能为测试的应用软件)并输出测试结果
    7、什么是持续集成?
    答:持续集成是一种软件开发实践,即团队开发成员经常集成它们的工作,通过每个成员每天至少集成一次,也就意味着每天可能会发生多次集成。
    每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽早地发现集成错误。
    8、自动化测试的时候是不是需要连接数据库做数据校验?
    答:一般来说1、 UI自动化不需要(很少需要);2、接口测试会需要:从数据库层面来进行数据校验可以更方便验证系统的数据处理方面是否正确;
    9、有几种元素常用定位方式,分别是?你最偏爱哪一种,为什么?
    答:8种:id、name、class name、tag name、link text、partial link text、xpath、css selector 偏爱哪一种?答:xpath、css几乎所有的元素都可以定位到,但是它们的短处在于页面上更改了元素后位置很容易改变,且xpath语法长,定位慢,还不稳定;css语法简洁,定位快,瑕不掩瑜,所以首先使用的还是id或者name、css等。
    10、如何去定位页面上动态加载的元素?
    答:1,触发动态加载元素的事件,直至动态元素出现,进行定位
    2,WebDriverWait()方法循环去查询是否元素加载出来了
    11、如何去定位属性动态变化的元素?
    答:xpath或者css通过同级、父级、子级进行定位
    点击链接以后,selenium是否需要自动等待该页面加载完毕?
    答:需要
    12、webdriver client的原理是什么?
    答:Selenium RC的原理是当浏览器启动时,向其中注入Javascript,从而使这些JS来驱动浏览器中的AUT
    (Application Under Test),而Selenium Webdriver是通过调用浏览器原生的自动化API直接驱动浏览器
    13、什么是page object设计模式?
    答:简单来说,就是把页面作为对象,在使用中传递页面对象,来使用页面对象中相应的成员或者方法,能更好的体现面向对象语言(比如java或者python)的面向对象和封装特性。
    14、什么是断言(assert),常用断言方法,UI自动化中断言方式?
    答:断言的英文是assertion,断言检查的英文是assertion checking。
    断言是指定一个程序必须已经存在的状态的一个逻辑表达式,或者一组程序变量在程序执行期间的某个点上必须满足的条件
    UI自动化中断言方式:定位页面当前页面或跳转页面中元素唯一的一个或多个元素判断是否存在,即可。
    15、你觉得自动化测试最大的缺陷是什么?
    答:不稳定、可靠性、不易维护、成本与收益
    16、什么是分层测试?
    答:行业里面提的一般是金字塔的分层模型:UI测试、集成/接口测试、单元测试
    17、列举出你熟悉的自动化工具,并说明其实现原理
    18、高质量的自动化脚本应该具有什么特性?

    自动化测试面试题4:细节篇之性能篇

    目的:验证求职者在性能测试方面熟悉程度

    1,基础概念:HPS、TPS、QPS、RPS、RT、并发用户数概念?简要介绍?
    HPS(Hits Per Second):每秒点击次数,单位是次/秒。
    TPS(Transaction per Second):系统每秒处理事务数,简称TPS, 每秒事务数, 是衡量系统性能的一个非常重要的指标。
    QPS(Query per Second):系统每秒处理查询次数,单位是次/秒。对于互联网业务中,如果某些业务有且仅有一个请求连接,那么TPS=QPS=HPS,一般情况下用TPS来衡量整个业务流程,用QPS来衡量接口查询次数,用HPS来表示对服务器点击请求
    RPS 即每秒请求数(Request Per Second),通常用来描述施压引擎实际发出的压力大小。PS:并发数过低时可能达不到预期的 RPS,并发数过高时可能压力过大压垮服务器
    并发用户数:简称VU ,指的是现实系统中操作业务的用户,在性能测试工具中,一般称为虚拟用户数(Virutal User),注意并发用户数跟注册用户数、在线用户数有很大差别的,并发用户数一定会对服务器产生压力的,而在线用户数只是 ”挂” 在系统上,对服务器不产生压力,注册用户数一般指的是数据库中存在的用户数。
    响应时间:简称RT,指的是业务从客户端发起到客户端接受的时间。
    2,压测工具?你主要看哪些指标?
    答:jmeter:
    Label:每个 JMeter 的 element(例如 HTTP Request)都有一个 Name 属性,这里显示的就是 Name 属性的值
    #Samples:表示你这次测试中一共发出了多少个请求,如果模拟10个用户,每个用户迭代10次,那么这里显示100
    Average:平均响应时间——默认情况下是单个 Request 的平均响应时间,当使用了 Transaction Controller 时,也可以以Transaction 为单位显示平均响应时间
    Median:中位数,也就是 50% 用户的响应时间
    90% Line:90% 用户的响应时间
    Note:关于 50% 和 90% 并发用户数的含义,请参考下文
    http://www.cnblogs.com/jackei/archive/2006/11/11/557972.html
    Min:最小响应时间
    Max:最大响应时间
    Error%:本次测试中出现错误的请求的数量/请求的总数
    Throughput:吞吐量——默认情况下表示每秒完成的请求数(Request per Second),当使用了 Transaction Controller 时,也可以表示类似 LoadRunner 的 Transaction per Second 数
    KB/Sec:每秒从服务器端接收到的数据量,相当于LoadRunner中的Throughput/Sec
    3,性能测试中TPS上不去的几种原因浅析?
    TPS(Transaction Per Second):每秒事务数,指服务器在单位时间内(秒)可以处理的事务数量,一般以request/second为单位。
    a、网络带宽 在压力测试中,有时候要模拟大量的用户请求,如果单位时间内传递的数据包过大,超过了带宽的传输能力,那么就会造成网络资源竞争,间接导致服务端接收到的请求数达不到服务端的处理能力上限。
    b、连接池
    可用的连接数太少,造成请求等待。连接池一般分为服务器连接池(比如Tomcat)和数据库连接池(或者理解为最大允许连接数也行)。
    c、垃圾回收机制
    从常见的应用服务器来说,比如Tomcat,因为java的的堆栈内存是动态分配,具体的回收机制是基于算法,如果新生代的Eden和Survivor区频繁的进行Minor GC,老年代的full GC也回收较频繁,那么对TPS也是有一定影响的,因为垃圾回收其本身就会占用一定的资源。
    d、数据库配置
    高并发情况下,如果请求数据需要写入数据库,且需要写入多个表的时候,如果数据库的最大连接数不够,或者写入数据的SQL没有索引没有绑定变量,抑或没有主从分离、读写分离等,就会导致数据库事务处理过慢,影响到TPS。
    e、通信连接机制
    串行、并行、长连接、管道连接等,不同的连接情况,也间接的会对TPS造成影响。
    f、硬件资源
    包括CPU(配置、使用率等)、内存(占用率等)、磁盘(I/O、页交换等)。
    g、压力机
    比如jmeter,单机负载能力有限,如果需要模拟的用户请求数超过其负载极限,也会间接影响TPS(这个时候就需要进行分布式压测来解决其单机负载的问题)。
    h、压测脚本
    还是以jemter举个例子,之前工作中同事遇到的,进行阶梯式加压测试,最大的模拟请求数超过了设置的线程数,导致线程不足。
    提到这个原因,想表达意思是:有时候测试脚本参数配置等原因,也会影响测试结果。
    i、业务逻辑
    业务解耦度较低,较为复杂,整个事务处理线被拉长导致的问题。
    j、系统架构
    比如是否有缓存服务,缓存服务器配置,缓存命中率、缓存穿透以及缓存过期等,都会影响到测试结果。
    4,性能测试工具了解几个?压测结果区别?
    A,ab,是apache自带的压力测试工具
    B,Jmeter 基于Java的压力测试工具
    c,Locust是一个Python编写的分布式的性能测试工具
    5,性能测试策略?
    做性能测试需要一套标准化流程及测试策略。在做负载测试的时候,传统方式一般都是按照梯度施压的方式去加用户数,避免在没有预估的情况下,一次加几万个用户,导致交易失败率非常高,响应时间非常长,已经超过了使用者忍受范围内;较为适合互联网分布式架构的方式,是用TPS模式(吞吐量模式)+设置起始和目标最大量级,然后根据系统表现灵活的手工实时调速,效率更高,服务端吞吐能力的衡量一步到位。

    6,性能测试场景设置思路?
    无论并发模式还是TPS模式,场景就是一个压测模型,压测模型中有串行的事务(如添加购物车+购物车下单+付款)也有并行的接口(在不同串联链路中的压测API),最终组成一个复杂或者简单的场景。然后根据新业务上线的目标、或者日常峰值的等比例目标、或者重大业务活动的预估支撑能力去设置每个API的目标能力(TPS是一步到位的按照吞吐能力设置的,推荐TPS模式,比如前面提到的添加购物车+购物车下单+付款这种流程就是一个漏斗模型,TPS设置为逐渐变小的模型即可),当然也可以在初期的测试中更谨慎一点,将目标量级设置得整体低一点,当最终能力达到之后建议可以调整原定目标量级到120%或者150%,验证限流准入/高可用基础设施的抗压能力。目标量级即当前压测场景中这个压测API的施压上限。而起步量级可以从5%或者10%开始,过程中视业务指标数据和被压测端的整体负载临时调整。

    7,对服务器性能测试的看法?
    针对服务器端的性能,以TPS为主来衡量系统的性能,并发用户数为辅来衡量系统的性能,如果必须要用并发用户数来衡量的话,需要一个前提,那就是交易在多长时间内完成,因为在系统负载不高的情况下,将思考时间(思考时间的值等于交易响应时间)加到串联链路(场景)中,并发用户数基本可以增加一倍,因此用并发用户数来衡量系统的性能没太大的意义。同样的,如果系统间的吞吐能力差别很大,那么同样的并发下TPS差距也会很大

    8,系统的性能决定的要素?跟并发用户数的关系?
    由TPS决定,跟并发用户数没有多大关系。
    系统的最大TPS是一定的(在一个范围内),但并发用户数不一定,可以调整。
    建议性能测试的时候,不要设置过长的思考时间,以最坏的情况下对服务器施压。

    下面是我自己的群,大家一起讨论学习,现在人不多,来了就是元老哦哈哈,失效的时候联系我

    在这里插入图片描述

    展开全文
  • Java接口自动化测试框架

    千次阅读 2019-11-21 12:07:20
    自动化测试框架 1. 测试框架TestNG 1.1 适合测试人员使用的原因 (1)比Junit涵盖功能更全面的测试框架 (2)Junit更适合隔离性比较强的单元测试 (3)TestNG更适合复杂的集成测试 1.2 基本介绍 (1)基本注解:...

    一. 自动化测试框架

    在这里插入图片描述

    1. 测试框架TestNG

    1.1 适合测试人员使用的原因

    (1)比Junit涵盖功能更全面的测试框架
    (2)Junit更适合隔离性比较强的单元测试
    (3)TestNG更适合复杂的集成测试

    1.2 基本介绍

    (1)基本注解:决定执行顺序
    例:
    @Test:标记一个类或方法作为测试的一部分
    @beforeTest、@afterTest:做前置或后置处理
    (2)属性
    例:
    groups:分组测试
    dependsOnGroups:依赖测试
    description:描述
    (3)测试套件
    组织测试类一起执行的或者一组行为的测试用例的集合,由一个XML文件标记

    2. 测试报告ExtentReport

    2.1 添加测试类

    ExtentTestNGIReporterListener

    2.2 基本配置

    在测试套件中 @listener标签下添加监听器

    3. HttpClient

    一个HTTP客户端编程工具,可用来发送请求、接收响应

    4. MyBatis

    持久层框架,支持定制化 SQL、存储过程以及高级映射。
    可以使用简单的 XML 或注解来配置和映射原生信息。

    5. MySQL

    存储测试用例

    二. 编写步骤及文件目录结构

    1. 测试用例的表结构设计

    在这里插入图片描述

    2. 基础配置文件设计

    在这里插入图片描述

    2.1 pom.xml:引入第三方依赖包

    配置httpclient、json、mybatis、mysql、lombok、extentreports、testng的各种依赖

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <parent>
            <artifactId>AutoTest</artifactId>
            <groupId>Chapter</groupId>
            <version>1.0-SNAPSHOT</version>
        </parent>
        <modelVersion>4.0.0</modelVersion>
    
        <artifactId>Chapter12</artifactId>
    
        <dependencies>
            <dependency>
                <groupId>org.apache.httpcomponents</groupId>
                <artifactId>httpclient</artifactId>
                <version>4.1.2</version>
            </dependency>
            <dependency>
                <groupId>org.json</groupId>
                <artifactId>json</artifactId>
                <version>20170516</version>
            </dependency>
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis</artifactId>
                <version>3.4.4</version>
            </dependency>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>1.16.14</version>
            </dependency>
            <dependency>
                <groupId>com.relevantcodes</groupId>
                <artifactId>extentreports</artifactId>
                <version>2.41.1</version>
            </dependency>
            <dependency>
                <groupId>com.vimalselvam</groupId>
                <artifactId>testng-extentsreport</artifactId>
                <version>1.3.1</version>
            </dependency>
            <dependency>
                <groupId>com.aventstack</groupId>
                <artifactId>extentreports</artifactId>
                <version>3.0.6</version>
            </dependency>
            <dependency>
                <groupId>org.testng</groupId>
                <artifactId>testng</artifactId>
                <version>6.10</version>
            </dependency>
            <dependency>
                <groupId>commons-logging</groupId>
                <artifactId>commons-logging</artifactId>
                <version>1.0.4</version>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
            </dependency>
        </dependencies>
    </project>
    

    2.2 databaseConfig.xml:数据库配置文件

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE configuration
            PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-config.dtd">
    
    <configuration>
        <!-- 注册对象的空间命名 -->
        <environments default="development">
            <environment id="development">
                <transactionManager type="JDBC"/>
                <dataSource type="POOLED">
                    <!-- 1.加载数据库驱动 -->
                    <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                    <!-- 2.数据库连接地址 -->
                    <property name="url" value="jdbc:mysql://localhost:3306/course?serverTimezone=GMT"/>
                    <!-- 数据库用户... -->
                    <property name="username" value="root"/>
                    <!-- 数据库密码... -->
                    <property name="password" value="12345678"/>
                </dataSource>
            </environment>
        </environments>
        <!-- 注册映射文件:java对象与数据库之间的xml文件路径! -->
        <mappers>
            <mapper resource="mapper/SQLMapper.xml"/>
        </mappers>
    </configuration>
    

    2.3 application.properties:接口信息配置文件

    test.url=http://localhost:8080
    
    #登陆接口uri
    login.uri=/v1/login
    

    2.4 testng.xml:用以执行所有testng的测试套件

    <?xml version="1.0" encoding="UTF-8" ?>
    <suite  name="用户管理系统测试套件">
        <test name="用户管理系统测试用例">
            <classes>
                <class name="com.tester.cases.LoginTest">
                    <methods>
                        <include name="loginTrue"/>
                        <include name="loginFalse"/>
                    </methods>
                </class>       
            </classes>
        </test>
        <listeners>
            <listener class-name="com.tester.config.ExtentTestNGIReporterListener"/>
        </listeners>
    </suite>
    

    2.5 SQLMapper.xml:用以存储所有测试用例的SQL语句

    <?xml version="1.0" encoding="UTF-8" ?>
    
    <!DOCTYPE mapper
            PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    
    <mapper namespace="com.tester.model">
        <!--获取登陆接口case-->
        <select id="loginCase" parameterType="Integer" resultType="com.tester.model.LoginCase">
            select *from logincase where id=#{id};
        </select>
     </mapper>
    

    3. model层、config层、utils层、cases层

    在这里插入图片描述

    3.1 model层:放置各个接口的数据配置文件+InterfaceName枚举

    3.1.1 放置登录接口的数据配置文件LoginCase.java

    package com.tester.model;
    
    import lombok.Data;
    
    @Data
    public class LoginCase {
        private int id;
        private String userName;
        private String password;
        private String expected;
    }
    

    3.1.2 InterfaceName.java

    package com.tester.model;
    
    public enum InterfaceName {
        LOGIN
    }
    

    3.2 Config层:配置信息TestConfig类+ExtentTestNGReportListener类

    3.2.1TestConfig类:声明各个测试用例的URL、和之后要用的一些全局变量

    package com.tester.config;
    
    import lombok.Data;
    import org.apache.http.client.CookieStore;
    import org.apache.http.impl.client.DefaultHttpClient;
    
    
    
    @Data
    public class TestConfig {
        //登陆接口uri
        public static String loginUrl;
        //声明http客户端
        public static DefaultHttpClient defaultHttpClient;
        //用来存储cookies信息的变量
        public static CookieStore store;
    }
    

    3.2.2 ExtentTestNGReportListener类:测试报告配置

    package com.tester.config;
    
    
    import com.aventstack.extentreports.ExtentReports;
    import com.aventstack.extentreports.ExtentTest;
    import com.aventstack.extentreports.ResourceCDN;
    import com.aventstack.extentreports.Status;
    import com.aventstack.extentreports.model.TestAttribute;
    import com.aventstack.extentreports.reporter.ExtentHtmlReporter;
    import com.aventstack.extentreports.reporter.configuration.ChartLocation;
    import com.aventstack.extentreports.reporter.configuration.Theme;
    import org.testng.*;
    import org.testng.xml.XmlSuite;
    
    import java.io.File;
    import java.util.*;
    
    public class ExtentTestNGIReporterListener implements IReporter {
        //生成的路径以及文件名
        private static final String OUTPUT_FOLDER = "test-output/";
        private static final String FILE_NAME = "index.html";
    
        private ExtentReports extent;
    
        @Override
        public void generateReport(List<XmlSuite> xmlSuites, List<ISuite> suites, String outputDirectory) {
            init();
            boolean createSuiteNode = false;
            if(suites.size()>1){
                createSuiteNode=true;
            }
            for (ISuite suite : suites) {
                Map<String, ISuiteResult> result = suite.getResults();
                //如果suite里面没有任何用例,直接跳过,不在报告里生成
                if(result.size()==0){
                    continue;
                }
                //统计suite下的成功、失败、跳过的总用例数
                int suiteFailSize=0;
                int suitePassSize=0;
                int suiteSkipSize=0;
                ExtentTest suiteTest=null;
                //存在多个suite的情况下,在报告中将同一个一个suite的测试结果归为一类,创建一级节点。
                if(createSuiteNode){
                    suiteTest = extent.createTest(suite.getName()).assignCategory(suite.getName());
                }
                boolean createSuiteResultNode = false;
                if(result.size()>1){
                    createSuiteResultNode=true;
                }
                for (ISuiteResult r : result.values()) {
                    ExtentTest resultNode;
                    ITestContext context = r.getTestContext();
                    if(createSuiteResultNode){
                        //没有创建suite的情况下,将在SuiteResult的创建为一级节点,否则创建为suite的一个子节点。
                        if( null == suiteTest){
                            resultNode = extent.createTest(r.getTestContext().getName());
                        }else{
                            resultNode = suiteTest.createNode(r.getTestContext().getName());
                        }
                    }else{
                        resultNode = suiteTest;
                    }
                    if(resultNode != null){
                        resultNode.getModel().setName(suite.getName()+" : "+r.getTestContext().getName());
                        if(resultNode.getModel().hasCategory()){
                            resultNode.assignCategory(r.getTestContext().getName());
                        }else{
                            resultNode.assignCategory(suite.getName(),r.getTestContext().getName());
                        }
                        resultNode.getModel().setStartTime(r.getTestContext().getStartDate());
                        resultNode.getModel().setEndTime(r.getTestContext().getEndDate());
                        //统计SuiteResult下的数据
                        int passSize = r.getTestContext().getPassedTests().size();
                        int failSize = r.getTestContext().getFailedTests().size();
                        int skipSize = r.getTestContext().getSkippedTests().size();
                        suitePassSize += passSize;
                        suiteFailSize += failSize;
                        suiteSkipSize += skipSize;
                        if(failSize>0){
                            resultNode.getModel().setStatus(Status.FAIL);
                        }
                        resultNode.getModel().setDescription(String.format("Pass: %s ; Fail: %s ; Skip: %s ;",passSize,failSize,skipSize));
                    }
                    buildTestNodes(resultNode,context.getFailedTests(), Status.FAIL);
                    buildTestNodes(resultNode,context.getSkippedTests(), Status.SKIP);
                    buildTestNodes(resultNode,context.getPassedTests(), Status.PASS);
                }
                if(suiteTest!= null){
                    suiteTest.getModel().setDescription(String.format("Pass: %s ; Fail: %s ; Skip: %s ;",suitePassSize,suiteFailSize,suiteSkipSize));
                    if(suiteFailSize>0){
                        suiteTest.getModel().setStatus(Status.FAIL);
                    }
                }
    
            }
    //        for (String s : Reporter.getOutput()) {
    //            extent.setTestRunnerOutput(s);
    //        }
    
            extent.flush();
        }
    
        private void init() {
            //文件夹不存在的话进行创建
            File reportDir= new File(OUTPUT_FOLDER);
            if(!reportDir.exists()&& !reportDir .isDirectory()){
                reportDir.mkdir();
            }
            ExtentHtmlReporter htmlReporter = new ExtentHtmlReporter(OUTPUT_FOLDER + FILE_NAME);
            // 设置静态文件的DNS
            //怎么样解决cdn.rawgit.com访问不了的情况
            htmlReporter.config().setResourceCDN(ResourceCDN.EXTENTREPORTS);
    
            htmlReporter.config().setDocumentTitle("api自动化测试报告");
            htmlReporter.config().setReportName("api自动化测试报告");
            htmlReporter.config().setChartVisibilityOnOpen(true);
            htmlReporter.config().setTestViewChartLocation(ChartLocation.TOP);
            htmlReporter.config().setTheme(Theme.STANDARD);
            htmlReporter.config().setCSS(".node.level-1  ul{ display:none;} .node.level-1.active ul{display:block;}");
            extent = new ExtentReports();
            extent.attachReporter(htmlReporter);
            extent.setReportUsesManualConfiguration(true);
        }
    
        private void buildTestNodes(ExtentTest extenttest, IResultMap tests, Status status) {
            //存在父节点时,获取父节点的标签
            String[] categories=new String[0];
            if(extenttest != null ){
                List<TestAttribute> categoryList = extenttest.getModel().getCategoryContext().getAll();
                categories = new String[categoryList.size()];
                for(int index=0;index<categoryList.size();index++){
                    categories[index] = categoryList.get(index).getName();
                }
            }
    
            ExtentTest test;
    
            if (tests.size() > 0) {
                //调整用例排序,按时间排序
                Set<ITestResult> treeSet = new TreeSet<ITestResult>(new Comparator<ITestResult>() {
                    @Override
                    public int compare(ITestResult o1, ITestResult o2) {
                        return o1.getStartMillis()<o2.getStartMillis()?-1:1;
                    }
                });
                treeSet.addAll(tests.getAllResults());
                for (ITestResult result : treeSet) {
                    Object[] parameters = result.getParameters();
                    String name="";
                    //如果有参数,则使用参数的toString组合代替报告中的name
                    for(Object param:parameters){
                        name+=param.toString();
                    }
                    if(name.length()>0){
                        if(name.length()>50){
                            name= name.substring(0,49)+"...";
                        }
                    }else{
                        name = result.getMethod().getMethodName();
                    }
                    if(extenttest==null){
                        test = extent.createTest(name);
                    }else{
                        //作为子节点进行创建时,设置同父节点的标签一致,便于报告检索。
                        test = extenttest.createNode(name).assignCategory(categories);
                    }
                    //test.getModel().setDescription(description.toString());
                    //test = extent.createTest(result.getMethod().getMethodName());
                    for (String group : result.getMethod().getGroups())
                        test.assignCategory(group);
    
                    List<String> outputList = Reporter.getOutput(result);
                    for(String output:outputList){
                        //将用例的log输出报告中
                        test.debug(output);
                    }
                    if (result.getThrowable() != null) {
                        test.log(status, result.getThrowable());
                    }
                    else {
                        test.log(status, "Test " + status.toString().toLowerCase() + "ed");
                    }
    
                    test.getModel().setStartTime(getTime(result.getStartMillis()));
                    test.getModel().setEndTime(getTime(result.getEndMillis()));
                }
            }
        }
    
        private Date getTime(long millis) {
            Calendar calendar = Calendar.getInstance();
            calendar.setTimeInMillis(millis);
            return calendar.getTime();
        }
    }
    

    3.3 utils层: 抽取公用的方法ConfigFile类+DatabaseUtil类

    3.3.1 ConfigFile类:对各个测试用例的URL进行赋值

    package com.tester.utils;
    
    import com.tester.model.InterfaceName;
    
    import java.util.Locale;
    import java.util.ResourceBundle;
    
    public class ConfigFile {
        public static ResourceBundle bundle=ResourceBundle.getBundle("application", Locale.CHINA);
        public static String getUrl(InterfaceName name){
            String address=bundle.getString("test.url");
            String uri="";
            String testUrl;
         
            if(name==InterfaceName.LOGIN){
                uri=bundle.getString("login.uri");
            }
            
            testUrl=address+uri;
            return testUrl;
        }
    }
    

    3.3.2 DatabaseUtil类:配置一个getSqlSession()方法

    作用是执行配置文件SQLMapper中的SQL语句

    package com.tester.utils;
    
    import org.apache.ibatis.io.Resources;
    import org.apache.ibatis.session.SqlSession;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.apache.ibatis.session.SqlSessionFactoryBuilder;
    
    import java.io.IOException;
    import java.io.Reader;
    
    public class DatabaseUtil {
        public static SqlSession getSqlSession() throws IOException {
            //获取配置的资源文件
            Reader reader= Resources.getResourceAsReader("databaseConfig.xml");
            //得到SqlSessionFactory,使用类加载器加载xml文件
            SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(reader);
            //得到sqlsession对象,这个对象就能执行配置文件中的sql语句啦
            SqlSession session=factory.openSession();
            return session;
        }
    }
    

    3.4 cases层:用来放接口的测试用例

    package com.tester.cases;
    
    import com.tester.config.TestConfig;
    import com.tester.model.InterfaceName;
    import com.tester.model.LoginCase;
    import com.tester.utils.ConfigFile;
    import com.tester.utils.DatabaseUtil;
    import org.apache.http.HttpResponse;
    import org.apache.http.client.methods.HttpPost;
    import org.apache.http.entity.StringEntity;
    import org.apache.http.impl.client.DefaultHttpClient;
    import org.apache.http.util.EntityUtils;
    import org.apache.ibatis.session.SqlSession;
    import org.json.JSONObject;
    import org.testng.Assert;
    import org.testng.annotations.BeforeTest;
    import org.testng.annotations.Test;
    
    import java.io.IOException;
    
    public class LoginTest {
        @BeforeTest(groups = "loginTrue",description = "测试准备工作,获取HttpClient对象")
        public void beforeTest(){
            TestConfig.getUserInfoUrl= ConfigFile.getUrl(InterfaceName.GETUSERINFO);
            TestConfig.getUserListUrl=ConfigFile.getUrl(InterfaceName.GETUSERLIST);
            TestConfig.addUserUrl=ConfigFile.getUrl(InterfaceName.ADDUSERINFO);
            TestConfig.loginUrl=ConfigFile.getUrl(InterfaceName.LOGIN);
            TestConfig.updateUserInfoUrl=ConfigFile.getUrl(InterfaceName.UPDATEUSERINFO);
    
            TestConfig.defaultHttpClient=new DefaultHttpClient();
        }
    
        @Test(groups = "loginTrue",description = "用户成功登陆接口")
        public void loginTrue() throws IOException {
            SqlSession session= DatabaseUtil.getSqlSession();
            LoginCase loginCase=session.selectOne("loginCase",1);
            System.out.println(loginCase.toString());
            System.out.println(TestConfig.loginUrl);
    
            //下边的代码为写完接口的测试代码
            String result=getResult(loginCase);
            //处理结果,就是判断返回结果是否符合预期
            Assert.assertEquals(loginCase.getExpected(),result);
        }
    
    
    
        @Test(groups = "loginFalse",description = "用户登录接口失败")
        public void loginFalse() throws IOException {
            SqlSession session=DatabaseUtil.getSqlSession();
            LoginCase loginCase=session.selectOne("loginCase",2);
            System.out.println(loginCase.toString());
            System.out.println(TestConfig.loginUrl);
    
            //下边的代码为写完接口的测试代码
            String result=getResult(loginCase);
            //处理结果,就是判断返回结果是否符合预期
            Assert.assertEquals(loginCase.getExpected(),result);
        }
    
        private String getResult(LoginCase loginCase) throws IOException {
            //下边的代码为写完接口的测试代码
            HttpPost post=new HttpPost(TestConfig.loginUrl);
            JSONObject param=new JSONObject();
            param.put("userName",loginCase.getUserName());
            param.put("password",loginCase.getPassword());
            //设置请求头信息,设置header
            post.setHeader("content-type","application/json");
            //将参数信息添加到方法中
            StringEntity entity=new StringEntity(param.toString(),"utf-8");
            post.setEntity(entity);
            //声明一个对象来进行响应结果的存储
            String result;
            //执行post方法
            HttpResponse response=TestConfig.defaultHttpClient.execute(post);
            //获取响应结果
            result= EntityUtils.toString(response.getEntity(),"utf-8");
            System.out.println(result);
    
            TestConfig.store=TestConfig.defaultHttpClient.getCookieStore();
            return result;
        }
    }
    
    展开全文
  • 一系列自动化测试的开源项目介绍

    万次阅读 多人点赞 2018-11-21 14:14:22
    本文针对性能测试、Web UI 测试、API 测试、数据库测试、接口测试、单元测试等方面,为大家整理了github或码云上优秀的自动化测试开源项目,希望能给大家带来一点帮助。 一、性能自动化测试 1、项目名称:基于...

           在如今开源的时代,我们就不要再闭门造车了,热烈的拥抱开源吧!本文针对性能测试、Web UI 测试、APP测试、数据库测试、接口测试、单元测试等方面,为大家整理了github或码云上优秀的自动化测试开源项目,希望能给大家带来一点帮助。

    一、性能自动化测试

    1、项目名称:基于Jmeter实现的在线压测平台和在线管理Jmeter脚本系统

    项目简介:

    • 本项目基于renren-fast Java开发平台开发,内核基于Jmeter-Api和Jmeter脚本实现在线性能压测。

    具有如下特点

    • 友好的代码结构及注释,便于阅读及二次开发
    • 实现前后端分离,通过token进行数据交互,前端再也不用关注后端技术
    • 灵活的权限控制,可控制到页面或按钮,满足绝大部分的权限需求
    • 页面交互使用Vue2.x,极大的提高了开发效率
    • 完善的代码生成机制,可在线生成entity、xml、dao、service、html、js、sql代码,减少70%以上的开发任务
    • 引入quartz定时任务,可动态完成任务的添加、修改、删除、暂停、恢复及日志查看等功能
    • 引入API模板,根据token作为登录令牌,极大的方便了APP接口开发
    • 引入Hibernate Validator校验框架,轻松实现后端校验
    • 引入云存储服务,已支持:七牛云、阿里云、腾讯云等
    • 引入swagger文档支持,方便编写API接口文档
    • 引入路由机制,刷新页面会停留在当前页
    • 引入最新版本Jmeter-Api,支持分布式压测,测试报告生成及在线查看下载。
    • 引入Echarts,支持在线观测性能压测结果。

    项目地址:https://gitee.com/smooth00/stressTestSystem

    2、项目名称:分布式压力测试工具 Beetle.DT

    项目简介:基于 .NET 实现的分布式压力测试工具,用户可以根据需求编写相关的测试用例;通过工具的管理界面即可以把测试用例推送到服务中心,再根据实际压测的需求把测试用例分配到不同节点上运行。工具会根据测试的情况实时获取测试结果,测试完成后用户还可以查询具体的测试报告。节点采用进程隔离的方式运行测试用例,所以测试用例的运行都是相互独立。

    项目地址:https://gitee.com/ikende/Beetle.DT

    3、项目名称:基于 Go 的压力测试工具 armyant

    项目简介:armyant 是从 http 压力测试工具 hey 改装而成。不过,hey 只支持 http 接口的压力测试,而 armant 可以自定义压测协议。目前默认实现了 http,mqtt 两种协议的压力测试。

    项目地址:https://gitee.com/plug/armyant

    二、Web UI 自动化测试

    1、项目名称:自动化测试平台 LuckyFrame 

    项目简介:本项目是一款免费开源的测试平台,最大的特点是全纬度覆盖了接口自动化、WEB UI自动化、APP自动化,并且支持分布式测试,测试关键字驱动也很大程度上解决了测试同学代码基础弱的问题。同时也集成了质量管理相关的一些功能,解决 QA 的日常工作中,项目过程数据的收集问题,并能展示一些简单质量报表。

    项目地址:https://gitee.com/seagull1985/LuckyFrameWeb

    2、项目名称:AutoLine开源平台

    项目简介:AutoLine开源平台是一个开源自动化测试解决方案,基于RobotFramework进行二次开发,支持RobotFramework几乎所有的库。

    项目地址:https://gitee.com/lym51/AutoLine

    三、APP 自动化测试

    项目名称:Opendx 基于Appium的开源自动化测试平台

    项目简介:Opendx 是一个开源的自动化测试平台,底层采用appium,目前已支持Android和iOS的自动化测试。平台没有对appium做任何入侵及修改,我们可以随意升级appium版本,使用其新特性。

    项目地址:https://jiangyitao.gitee.io/opendx/

    https://github.com/opendx

    四、接口自动化测试

    1、项目名称:Restful Api 集成测试工具 Hitchhiker

    项目简介:Hitchhiker 是一款开源的 Restful Api 测试工具,支持Schedule, 数据对比,压力测试,支持上传脚本定制请求,可以轻松部署到本地,和你的team成员一起管理 Api。

    项目地址:https://gitee.com/iwxiaot/Hitchhiker

    2、项目名称:自动化测试平台 phoenixframework

    项目简介:phoenixframework 是一个自动化测试平台,集代码托管, 分机(node节点)管理,定时任务,分布式或并发等方式执行通过 phoenix_develop 模块调试好的用例。平台使用 SSH4 开发,覆盖了 webgui,接口,移动mobile 等终端的测试与监控。
    目前 webGUI 模块已经完成,兼容 chrome,Firefox,IE,httpunit 以及 phantomjs 驱动。

    项目地址:https://gitee.com/phoenixframework/phoenixframework

    3、项目名称:TCP/UDP 测试工具 SocketDebugger

    项目简介:SocketDebugger 是一款 TCP/UDP 测试工具,并且包括串口转发功能,以及自动回复功能。

    项目地址:https://gitee.com/hkiaipc/Socket-Debugger

    4、项目名称:HTTP 接口测试插件 ApiDebug

    项目简介:ApiDebug 是一个浏览器HTTP接口测试插件,可以用来测试 HTTP、HTTPS接口。支持POST、GET 等方式,同时也支持 json、xml 等自定义接口参数。系统支持保存历史记录,也可同步测试接口至 CrapApi 接口管理系统(登陆 http://api.crap.cn ,点击同步即可保存)。除接口测试外,系统还包含 json 格式化等小工具。 

    项目地址:https://gitee.com/CrapApi/ApiDebug

     5、项目名称:基于 Java 的 Http 接口测试工具

    项目简介:JApiTest 是使用 java 开发的 Http 接口测试工具,以可视化形式通过配置 http 参数访问测试接口,并可对返回结果还有判断。

    项目地址:https://gitee.com/penngo/JApiTest

    6、项目名称:基于 Python3.6的Django 2.0.2框架的接口测试工具

    项目简介:系统采用Django REST framework编写接口,前端页面采用比较容易上手的vue+elementUI。

    项目地址:https://github.com/githublitao/api_automation_test

    7、项目名称:FXTest测试平台

    项目简介:flask + Python3.6 实现的API自动化测试平台。

    项目地址:https://github.com/liwanlei/FXTest

    8、项目名称:基于开源的httprunner接口自动化框架平台

    项目简介:

    前端:js vue element-ui

    github地址:https://github.com/pencil1/ApiTestWeb

    后端:python flask httprunner

    github地址: https://github.com/pencil1/ApiTestManage

     五、数据库自动化测试

    项目名称:数据库单元测试框架 xlsunit

    项目简介:面向数据库应用的单元测试框架,使用excel,作为输入,以及输出比较,适合大量数据库操作。

    如下情况可以使用 xlsunit:

    • 必须使用 Spring 或者 Spring Boot,因为会利用 Spring 单元测试事务回滚机制。

    • 面向数据库应用,特别是一个业务操作,有多个表的变化。

    • xlsunit 支持 Spring 4 以上,SpringBoot1.5 以上,支持 Oracle,MySql,Postgres 等数据库。

    项目地址:https://gitee.com/xiandafu/xlsunit

    六、数据调优测试

    影响系统性能和效率,数据库起到一个非常关键的作用,而SQL的优化又是成本最低的一种优化方式,所以我把这一项也列为测试人员需要关注的方面。

    项目名称:soar-web

    项目简介:基于小米 soar 的开源 sql 分析与优化的 WEB 图形化工具,支持 soar 配置的添加、修改、复制,多配置切换,配置的导出、导入与导入功能。目前只支持mysql。

    项目地址:https://github.com/xiyangxixian/soar-web

    项目介绍:10月20日,在开源先锋日(OSCAR DAYS)上,小米将宣布开源自研的SOAR(SQL Optimizer And Rewriter)。

           这是一款智能 SQL 优化和改写工具,开发人员可以直接通过此工具快速的对自己的 SQL 进行质量检查,生成评估报告,防止将问题 SQL 带到线上从而导致服务质量下降。它不仅能够尽可能地提高线上代码质量,还能避免一些由于人为疏漏而带来的隐患。

           SOAR 由语法解析器、集成环境、优化建议、重写逻辑、工具集五大模块组成。它拥有独立的不依赖数据库的 SQL 解析能力,能够通过提供的集成环境对 SQL 本身及数据库环境进行评审,找出可能存在的隐患或问题。

    展开全文
  • Mac App自动化测试

    千次阅读 2019-02-27 16:44:12
    一、前言 Mac已然是一个不可或缺的平台,但是相对其它平台来说,针对Mac app的各项...我们对比了多款自动化框架,最终选择了atomac作为视频Mac端的自动化框架。 表1不同框架对比 从表中可以看出,atomac是基于...
  • 先前我介绍过我们的一个简单的自动化测试框架 —— 《一个简单的测试框架》,最近我又设计实现了另一个,叫 TLATS,原因是我们有了新的测试需求。在原有基础上修修补补,倒不如吸收其经验与思想重新设计,以满足更...
  • [人工智能]AI移动自动化测试

    千次阅读 2017-03-28 17:14:20
    1. 实现的效果开发者通过上传移动端软件(apk,pkg等)到云端,点击云端自动化测试来对上传的软件进行自动化测试,分析和bug定位,最终输出bug检测结果.2.实现的步骤这里先列出大致的一个实现步骤,然后对每一步如何做,在列...
  • 自动化测试面试题(一)

    千次阅读 2020-08-27 21:41:20
    自动化测试面试题(一)NO.1 什么是自动化测试NO.2 什么是分层测试?NO.3 自动化测试的适用和不适用场景NO.4 你觉得自动化测试最大的缺陷是什么?NO.4 项目使用的自动化测试框架NO.5 对库的使用NO.6 如何设计高质量...
  • 测试开发笔记

    万次阅读 多人点赞 2019-11-14 17:11:58
    测试开发笔记 第一章 测试基础 7 什么是软件测试: 7 ★软件测试的目的、意义:(怎么做好软件测试) 7 3.软件生命周期: 7 第二章 测试过程 8 1.测试模型 8 H模型: 8 V模型 9 2.内部测试 10 3外部测试: 10 验收...
  • 移动APP自动化测试框架对比

    万次阅读 2016-10-20 18:34:01
     移动APP的UI自动化测试长久以来一直是一个难点,难点在于UI的”变”, 变化导致自动化用例的大量维护。从分层测试的角度,自动化测试应该逐层进行。最大量实现自动化测试的应该是单元测试,最容易实现也最容易在...
  • 软件测试_笔记(完整版)

    万次阅读 多人点赞 2018-07-02 08:51:28
    广义的软件测试定义:人工或自动地运行或测定某系统的过程,目的在于检验它是否满足规定的需求或弄清预期结果和实际结果间的差别 为什么要做软件测试 发现软件缺陷 功能错 功能遗漏 超出需求部分(画蛇添足) ...
  • Java基础知识面试题(2020最新版)

    万次阅读 多人点赞 2020-02-19 12:11:27
    String为什么是不可变的 Date相关 包装类相关 自动装箱与拆箱 int 和 Integer 有什么区别 Integer a= 127 与 Integer b = 127相等吗 常用工具类库 单元测试 日志 Java面试总结汇总,整理了包括Java基础知识,集合...
  • Selenium是基于Web的最流行的UI自动化测试工具。它提供了一组支持多种平台的公开API(例如Linux,Windows,Mac OS X等)。此外,像Google Chrome,Mozilla Firefox,Internet Explorer和Safari等所有现代浏览器都...
  • UI测试自动化是移动端APP经常用到的测试手段,UI自动化测试化工具众多,android端和IOS端分别有各自不同的工具。本文通过简单分析几种自动化框架的异同和继承关系, 使测试人员在选择自动化框架时有所参考。
  • 前言:做UI自动化,不可避免的要和页面上的元素打交道,有的童鞋可能会选择把页面元素的定位,操作都写在测试代码中,当页面元素比较少,测试代码比较少的情况下还好,但是一旦页面元素多起来(实际运用中也不太可能...
  • 物联网IoT自动化渗透测试

    千次阅读 2019-11-04 21:30:09
    的渗透测试方法及其自动化,以评估物联网的安全性。 1 什么是IoT? 物联网 (IoT)是1999年由麻省理工学院(MIT)提出;这段特殊的时期预示着重要的新一代信息技术的出现。物联网被认为是交易的延伸附加互联网,便于...
  • 自动化测试面试

    万次阅读 多人点赞 2016-03-04 09:04:38
    目前市场上 自动化测试职位开放了很多很多 几乎每个公司都会这样发布招聘信息,但是我们理解的自动化测试,是不是用人单位理解的自动化测试呢。好似与雷军理解的黑科技一样。 我们在招聘自动化测试职位的时候,又...
  • Python从无到有搭建接口(API)自动化测试框架

    千次阅读 多人点赞 2021-01-03 23:51:03
    目录 1、前言 2、思路 3、正文 一、请求requests模块 ...十、参数par模块 十一、核心工厂factory模块 1、前言 pass 2、思路 pass 3、正文 pass 一、请求requests模块 pass 二、UT测试Unitest模块 pass
  • Java面试题大全(2020版)

    万次阅读 多人点赞 2019-11-26 11:59:06
    发现网上很多Java面试题都没有答案,所以花了很长时间搜集整理出来了这套Java面试题大全,希望对大家有帮助哈~ 本套Java面试题大全,全的不能再全,哈哈~ 一、Java 基础 1. JDK 和 JRE 有什么区别? JDK:Java ...
  • 软件测试入门知识了解

    万次阅读 多人点赞 2018-09-05 14:59:58
    1.软件测试定义两面性 2.测试的生命周期 测试需求分析--&gt;测试设计--&gt;测试计划--&gt;测试执行--&gt;质量评估 3.软件测试过程: 需求评审和设计评审是验证软件产品的需求定义和设计...
  • //获得根节点的所有子节点 List elements = rootelement.elements(); for (Element element : elements) { //获得student子元素的id属性 Attribute idattribute = element.attribute("id"); //获得student元素...
  • 客户端自动化测试研究

    千次阅读 2017-06-23 16:33:00
    从开发工程师到测试工程师,人人都应具备良好的测试意识,将隐患和风险在上线之前找出并解决,可以有效的减少线上事故。 美团和大众点评App作为美团点评平台的主要入口,支持承载着美团点评各大业务。其中美团点评...
  • 从0到1开发自动化测试框架

    千次阅读 2017-10-09 16:27:18
    一、序言  随着项目版本的快速迭代、APP测试有以下几个特点: 1. 首先,功能点多且细,测试工作量大,... 为节省成本,保证高效及高质量迭代,我们需采用更高效的测试方式,App自动化测试是较高效的手段。
  • 1.新建maven项目,引入jar包如下: &lt;dependency&gt; &lt;groupId&gt;org.testng&lt;/groupId&gt; &lt;artifactId&gt;testng&lt;/artifactId&gt; ...
  • CANoe的测试模块包括Test Module和Test Unit两大组件,并且集成了TFS测试功能集(Test Feature Set)和TSL测试服务库(Test Service Library)来帮助用户实现高效的自动化测试。 TFS是CANoe扩展出来的一系列测试...
  • 本文内容节选自第六届全球软件案例研究峰会,时任美团点评酒旅质量团队工具链负责人王鹏老师分享的《微服务架构下的自动化测试和持续集成工具链实践》实录,重点分享:微服务架构下解决自动化测试、开发联调、测试...
  • Robot Framework Selenium UI自动化测试 --- 进阶篇

    万次阅读 多人点赞 2019-03-10 14:42:50
    回顾: 如果您对Robot Framework ... 本篇主要讲述了如何工程的使用RFS,并穿插介绍各种常用关键字和使用技巧,希望能给大家带来帮助。 写在正片开始之前----论元素定位的重要性 web页面的元素定位是UI...
  • Rest-Assured接口自动化测试简单笔记

    千次阅读 2018-02-13 17:34:42
    接口自动化测试1.准备工作:IntelliJ IDEA JDK 1.8.0 Json格式化工具: 浏览器chrome安装JSONHandlerJava+maven+TestNG+junit+rest-assured抓包:charles请求工具:postman2.为什么要进行接口测试?接口测试主要用于...
  • 什么是前端自动化测试? 前端编写一段js 去运行生产中的js代码,我们预期会出现的结果与实际出现的结果是否相等,在上线前检测成问题,这样通过代码自动检测,而非人肉点击就是前端自动化测试 前端自动化测试的优势 ...
  • 自动化测试面试题库

    千次阅读 2018-09-04 09:09:03
    《常规问题》 ...2、对xx应用自己会花多久可以在业务上...3、如果在没有QA流程的情况下何开展测试工作(考察对方自管理和对测试流程的掌握)  4、遇到开发不认为是issue的情况下如何处理 5、如果和开发人员发生技术或...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 78,901
精华内容 31,560
关键字:

自动化测试引入的时间节点