前言
taozs
老师画的重点,极其重要!!!
25道多选
测试是为了证明这个系统没有bug。 错
测试四象限:
单元测试(工具)、组件测试(开发人员做,dao
层 controller
层,测试驱动开发),自动化,面向技术;
功能测试(接口测试,主要讲了rest接口; restAssured
,curl
,postman
),selenium
,自动化,面向业务;
探索测试:用户验收测试,可用性测试,面向业务;
系统测试:性能、压力,“非功能性”测试,面向技术,Jmeter
;
测试金字塔:测试投入比例: unit
> 接口测试 > UI
;
selenium grid
: 浏览器的兼容性测试。
cobertura
不是静态代码测试工具。
PMD
,ckeck style
, findbugs
(检查字节码) 特点。
Sonarqube
测试用例的设计方法:
基于直觉和经验的方法(名称)☆:随机测试…
基于输入域的方法:等价类划分法,边界值分析(互补的关系);
基于组合及其优化的方法(名称):解决测试用例过多的问题;
基于逻辑覆盖的方法:各个覆盖的意思。条件覆盖100% ≠ 分支覆盖100%;
测试controller
的三种方法:new ExampleController
;@SpringBootTest
(意味着要使用真实数据库);@WebMvcTest
;
HTTP
协议:四个动词,accept
,location
, 状态码;
testrestTemplate
,不是使用mockmvc
的环境,可以构建自己的请求头,请求体;
curl
常用参数: -i
-L
-v
;
postman
提供的功能:保存cookie
,cookie
共享,断言,环境(全局变量);
restAssured
:测试rest API,可以测试其他语言。Jsonpath
验证,写测试用例的方式(given,when,then);
docker常用参数: -P
-d
-e
,容器与虚拟机的区别;
持续集成:在合并到版本库之前需要进行构建测试(静态,单元)。分层构建(分层级,这个层级做单元测试… 快速反馈)。 哪些?
Jmeter
:分布式部署(selenium
),可以指定用例数,支持time
,支持ssl
,支持命令行,支持断言;
selenium ide
selenium
与robot framework
关系?
第一章 序言 软件开发过程
软件工程的发展
-
敏捷开发
以用户的需求进化为核心,采用迭代、循序渐进的方法进行软件开发。力求在最短的周期内开发出产品的核心功能,在后续的生产周期内,按照新需求不断迭代升级、完善产品。
-
敏捷关键词
迭代
反馈
-
XP 极限编程
价值观:沟通、简单、反馈、勇气;
编程方法:结对编程、测试驱动开发、重构、简单设计;
迭代前准备阶段
-
用户故事
3C原则:卡片
Card
、会话Conversation
、确认Confirmation
-
软件开发成本
总成本 = 开发成本 + 维护成本;
维护成本 = 理解代码的成本 + 修改成本 + 测试成本 + 部署成本;
维护成本 >>> 开发成本
迭代开发阶段
第二章 软件测试概念
测试目的
- 对软件进行充分的测试,找到其中的bug,并进行修复。√
- 证明代码中没有bug。 ×
- 软件质量:功能性、可用性(简单安装,轻松使用,用户界面良好)、可靠性、性能、容量、可维护性、兼容性、可扩展性;
测试四象限
-
象限一:测试驱动开发,关注代码内部质量,用户不关注,自动化,面向技术。
-
单元测试:错误发现的早,成本就越低;与写功能代码同时进行(测试驱动开发);黑盒测试(等价类划分、边界值分析法、错误推测法、因果图法、功能图法);白盒测试(逻辑驱动法和基本路径法,各种覆盖);快速反馈是单元测试的首要目标;
驱动和桩:驱动模块:对底层或子层模块进行测试所编写的调用这些模块的程序;桩模块:对顶层或上层模块进行测试时所编写的替代下层模块的程序。
-
组件测试:也称为集成测试;
非渐增式测试模式:先分别测试每个模块,再把所有的模块按设计要求放在一起结合成所要的程序;
渐增式测试模式:把下一个要测试的模块同已经测试好的模块结合起来进行测试,测试完以后再把下一个应该测试的模块结合进来测试;
-
-
象限二:更高层的测试,关注外部质量和客户需要的功能(对设计的软件功能的测试),尽量验证业务层的逻辑,自动化,面向业务。
主要讲了
restAssured
、curl
、postman
、selenium
-
象限三:确认需求是不是用户真正需要的;是不是错误的理解了需求(可能会提出新的需求);通常是用户或客户执行;可用性测试;面向业务;手工测试;
-
象限四:系统测试,现实的计算机环境
性能测试(性能指标,性能瓶颈)、压力(长时间,超负荷的运行,测试系统的性能,可靠性和稳定性)、容量(某项指标的极限值):目的有所不同,但手段和方法在一定程度上相似;
安全性、可靠性(在规定条件和规定时间下完成规定功能的能力)、容错性(异常条件下是否具有防护性等):目的不同,方法和手段也不同;
兼容性测试
测试金字塔
第三章 代码静态测试
分类
-
静态测试:不运行程序本身,通过分析或检查源程序的语法、结构、过程等检查程序的正确性;
动态测试:通过运行程序检查运行结果和预期结果的差异;
代码Review
QAPlugs工具包
-
PMD
:发现代码中无用的变量、空catch块、不必要的对象创建等,支持多种语言; -
findbugs
:检查java
类或者jar
文件(字节码),将字节码与一组缺陷模式进行对比以发现可能的问题,只寻找可能存在bug的地方,不注重样式或者格式,它试图只寻找真正的缺陷或者潜在的性能问题;可解决的问题:
efficient
性能问题、maintainability
可维护性、portability
可移植性、reliability
可靠性、usability
可用性 -
checkstyle
:代码风格检查,例如缩进,换行等,只支持java;
SonarQube
自动代码审查工具,可检测代码中的错误、漏洞和代码异味等,并且能够生成代码审查报告,支持多种语言。
问题类型:
- 错误(代码bug,影响程序运行);
- 漏洞(有可能被攻击);
- 代码异味(可以优化,不然会影响代码的可维护性)
问题级别:
BLOCKER
:阻断,影响程序运行;CRITICAL
:严重,可能影响程序运行,安全;MAJOR
:主要,影响开发效率,代码质量;MINOR
:次要,可能影响开发效率,代码质量;INFO
:提示,建议;
pylint
:python
中的代码检查工具;
sonarlint
:支持多种语言;
第四章 单元测试技术
JUnit:基于测试驱动开发的测试框架
-
规则
- 测试方法必须用
@Test
注解; - 测试方法必须使用
public void
进行修饰; - 测试类的包应该与被测试类的包名一致;
- 测试单元中的每个方法要能单独独立测试,不能相互依赖;
- 测试方法必须用
-
注解
@BeforeClass
:static,修饰方法会在所有方法被调用前执行;@AfterClass
:static@Before / @After
:在每个测试方法前后各执行一次;@Test
@Ignore
:忽略的测试方法;
-
断言
将程序预期的结果与程序运行的结果进行比较,确保对结果的可预知性;
-
Failure and Error
Failure
一般由断言方法判断失败引起的;Error
由代码异常引起的,可能是代码本身的错误,也可能是测试代码的错误; -
参数化测试
-
@RunWith(Parameterized.class)
指明运行器Parameterized
来运行测试; -
测试类必须由
Parameterized
测试运行器修饰; -
准备数据:在提供数据的方法上使用
@Parameters
注解;该方法必须为public static
;该方法返回值必须为Collection
;该方法没有参数;public class calculatorTest {calculator cal = new calculator();private int param;private int result;public calculatorTest(int param,int result) {this.param=param;this.result=result;}@Parameterspublic static Collection data(){return Arrays.asList(new Object[][] {{2,2},{10,10},{5,5}});}//...@Testpublic void test_devide() throws Exception{cal.add(param);assertEquals(result, cal.getresult());} }
-
hamcrest
使测试更具有可读性和可理解性。
mockito
-
什么是Mock?
模拟对象是以可控的方式模拟真实对象行为的假对象;
-
为什么使用Mock?
- 真实对象可能是图形用户界面;
- 真实对象可能很难搭建;
- 真实对象的行为很难触发;
- 真实对象的速度很慢;
- 真实对象使用了回调机制;
- …
-
//@WebMvcTest @SpringBootTest区别 @WebMvcTest(ContactController.class) //主要用于controller层测试,可以指定控制器类。 @SpringBootTest(classes = Application.class) //@SpringBootTest注解告诉SpringBoot去寻找一个主配置类(例如带有@SpringBootApplication的配置类),并使用它来启动Spring应用程序上下文。SpringBootTest加载完整的应用程序并注入所有可能的bean,然后再运行测试用例,因此速度会很慢;会使用真实的数据库;
cobertura
代码覆盖程度的一种度量,不是静态代码测试工具
-
语句覆盖
所有语句执行一次。
-
分支覆盖/判定覆盖
覆盖到每一个分支。
-
条件覆盖
需要度量判定中的每个子表达式结果true/false是否被测试到。
分支覆盖100% ≠ 条件覆盖100%
-
路径覆盖/断言覆盖
选取足够多的测试数据,使程序中的每条可能路径都执行一次。
-
循环覆盖
度量循环是否执行了零次,一次和多余一次循环。
覆盖程度:路径覆盖 > 条件覆盖 > 分支覆盖 > 语句覆盖
圈复杂度:度量一个方法中执行路径的复杂程度,建议不超过10,特殊情况不超过15。
计算方式一: 圈复杂度 = 区域数 = 判定节点数 + 1
第五章 测试驱动开发
- 在
XP
中与测试驱动开发同属于编程方法的还有:结对编程,重构,简单设计; - 测试驱动开发
TDD
:在编写某个功能代码之前先编写测试代码,然后只编写可以使测试通过的功能代码,通过测试来推动整个开发的进行。- 开始新增一个测试;
- 运行所有测试,发现新的测试不能通过;
- 做一些小小的改动;
- 运行所有测试,且全部通过;
- 重构代码,以消除重复设计,优化设计结构;
第六章 软件测试方法
场景法设计测试用例
- 基本流:按照正确的事件流实现的一条正确流程;
- 备用流:出现故障或缺陷的过程,使用备选流加以标注;
基于直觉和经验的方法 ☆
- 随机测试
- ALAC测试:
Act-Like-A-Customer
,80%的错误很可能集中在20%的程序模块中; - 错误推测法:推测可能存在的错误;某处出现了错误,可能会隐藏更多的错误;
基于输入域的方法
-
等价类划分法:将输入域划分为若干部分,在每部分中选取具有代表性的数据当做测试用例;
无效等价类,有效等价类。
-
边界值分析法:对等价类划分法的一种补充,测试用例来着于等价类的边界;
基于组合及其优化的方法
解决用例太多的问题,如何减少用例数,用尽量少的用例发现尽量多的问题。
-
判定表法
条件桩、动作桩、条件项(对应条件桩具体的取值)、动作项(期望对应动作桩的取值);
-
因果图法
基本符号:E(排他关系,最多有一个成立)、I(或关系,不能同时为零)、R(屏蔽关系,a=1 —> b≠1)、O(唯一关系,有且仅有一个为1);
-
Pairwise配对测试:缩减测试用例数量
测试用例间没有交集;根据数学统计分析,73%的缺陷是由单因子或两个因子相互作用产生的(其中单 因子是35%,两个因子是38%;
配对测试最终剩下的用例数肯定相同,但可以有不同的组合。
-
正交试验法
正交表
Ln(m^k)
,n表示试验次数(行数),m表示每个因素的水平数(每个因素可能出现几种情况),k表示列数;测试用例个数 n=k(m-1)+1*
正交表的两个性质:每一列,不同数字出现的次数相同;任意两列,数字的排列方式齐全且相等;
基于逻辑覆盖的方法
- 语句覆盖
- 分支覆盖
- 条件覆盖
- 路径覆盖
- 循环覆盖
基于缺陷模式的测试
Defect-Pattern-Based Testing, DPBT
FindBugs
基于模型的测试
第七章 组件测试技术
数据访问层测试
-
JPA测试:
@DataJpaTest
注解只扫描@Entity Bean
和装配Spring Data JPA
存储库,默认使用内存数据库h2 database
; -
@ActiveProfiles
:用于指定这个测试类里的测试方式运行时的profiles(环境); -
去除内存数据库:
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) //@SpringBoot @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
业务层测试
控制器层测试
三种方式:
- 直接
new ExampleController
@WebMvcTest(controllers = ExampleController.class)
@SpringBootTest
第八章 接口测试
微服务架构模式的特征
- 应用程序分解为具有明确定义了职责范围的细粒度组件
- 完全独立部署,独立测试,并可复用 ;
- 使用轻量级通信协议,HTTP和JSON,松耦合;
- 服务实现可使用多种编程语言和技术 ;
- 将大型团队划分成多个小型开发团队,每个团队只负责他们各自的服务;
Rest原则
- 无状态、可缓存、统一接口、客户端-服务端,分曾系统、按需编码
- 一个架构符合rest原则,则称为RESTful架构。
HTTP
-
**HTTP四种动词:
get
、post
、put、
delete` ** -
请求头,请求体
Accept
:客户端可识别的响应内容类型列表(客户端可以接受的language,encoding,charset…);Cookies
;Content-Type
:请求内容的类型;Content-Length
:标识请求内容的长度; -
响应头和响应体
状态码:
1xx
:表示服务器已接收了客户端的请求,客户端可以继续发送请求;
2xx
:表示服务器已成功接收到请求并进行处理;
3xx
:表示服务器要求客户端重定向;
4xx
:表示客户端的请求有非法内容;
5xx
:标识服务器未能正常处理客户端的请求而出现意外错误;Location
:服务器返回给客户端,用于重定向到新的位置;Keep-Alive
:300,期望服务端保持连接多长时间(秒);
TestRestTemplate
不是使用mockmvc的环境,可以构建自己的请求头,请求体
curl
命令行工具,用来请求web服务器。
常用参数:
-x
:指定http请求的代理;--cookie / -b
:设置cookie;-i
:打印响应的标头;-L
:要求客户端重定向,让http请求跟随服务器重定向;-v
:输出通信的整个过程;-X
:指定http请求的方法;-H
:添加http请求的标头;-d
:指定发送参数;-u
:设置认证的用户名密码;- …
postman
主要功能:
- 保存
cookie
; - 不同请求间
cookie
共享; - 断言;
- 环境(全局变量,变量共享);
- …
RestAssured
写测试用例的方式:
-
given() ... expect() ... when() ...
-
given() ... when() ... then() ...
-
when() ... then() ...
补:consumes = "application/json"
:接收参数的形式;produces = "application/json"
:返回数据的形式;
第九章 Docker在测试中的应用
轻量级的虚拟化,共用主机内核,利用内核的虚拟化技术隔离出一个独立的运行环境,拥有独立的一个文件系统,网络空间,进程空间视图等,轻量级、高性能。
容器vs虚拟机
- 容器是在Linux内核实现的轻量级资源隔离机制;
- 虚拟机是操作系统级别的资源隔离,容器本质上是进程级的资源隔离;
基本命令/参数:
docker image ls
:检测Docker主机中的本地仓库中是否包含镜像;docker image pull
: 是下载镜像的命令;-d
:后台运行容器,并返回容器ID;-i
: 以交互模式运行容器,通常与-t
同时使用;-t
: 为容器重新分配一个伪输入终端,通常与-i
同时使用;-p
: 指定(发布)端口映射,格式为:主机(宿主)端口:容器端口;-P
: 随机端口映射,容器内部端口随机映射到主机的高端口;-v
:绑定一个卷;--rm
:退出时自动删除容器;-M
:容器内存的上限;docker export 1e560fca3906 > ubuntu.tar
:导出容器1e560fca3906
快照到本地文件ubuntu.tar
;docker import ubuntu.tar test/ubuntu:v1
:将快照文件ubuntu.tar
导入到镜像test/ubuntu:v1
;
第十章 持续集成
- 将测试分组,先执行较快的测试,分层级构建(单元 —> 组件 —> 验收 —> 性能,可以做到快速反馈)。
- 需要在本地构建测试,通过了再合并到远程版本库
- 某个用例执行失败,不应立即让构建失败,等本层级所有用例执行完了之后在失败。
- 环境管理的关键在于通过一个全自动过程来创建环境。
- 交付团队提交到版本控制库,自动触发构建测试和单元测试,触发自动化验收测试。
- 对每一层部署都要做冒烟测试。
- 部署流水线的实践
- 只生成一次二进制包;
- 使用同样的脚本向所有环境部署;
- 对部署进行冒烟测试;
- 向生产环境的副本中部署;
- 每次变更都要立即在流水线中传递;
- 只要有环节失败,就停止整个流水线;
jenkins
post
:根据流水线或阶段的完成状态,运行post
部分的操作。stages
:包含一系列一个或多个stage
指令,stages
部分是流水线描述的大部分"work" 的位置。 建议stages
至少包含一个stage
指令用于连续交付过程的每个离散部分,比如构建, 测试, 和部署。steps
:部分在给定的 stage 指令中执行的定义了一系列的一个或 多个steps
。environment
:制定一个 键-值对序列,该序列将被定义为所 有步骤的环境变量,或者是特定于阶段的步骤, 这取决于environment
指令在流水线内的位置。options
:指定在一个小时的全局执行超时,在此之后,jenkins
将终止流水线运行。
第十一章 Selenium
selenium的三部分:
-
driver
:与浏览器运行在同一系统上;定位元素(
find_element_by_id
、find_element_by_name
…);通过链接文本查找超链接(
find_element_by_link_text
…);通过
css
选择器定位元素(find_element_by_css_selector
…);通过
XPath
定位(绝对路径find_element_by_xpath
…);强制等待、显示等待、隐式等待
-
selenium grid
-
Selenium Client & WebDriver
selenium IDE提供脚本录制、回放、编辑,以及元素定位功能。
为什么要自动化?
- 敏捷软件开发,迭代,频繁地进行周期性交付;
- 每次需要跑全部的测试,消耗大(自动化测试方便做回归测试);
第十二章 验收测试框架 Robot Framework
Robot Framework与Selenium的关系:RF中可以集成Selenium?
第十三章 性能测试
Jmeter
- 分布式部署;
- 可以指定用例数;
- 支持定时器time;
- 逻辑控制器;
- 支持
ssl
; - 支持命令行;
- 支持断言;
Apdex:性能指数