大家好,欢迎来到IT知识分享网。
目录
测试方法:等价类划分法、边界值分析法、判定表/因果图法、正交实验法
一、软件开发的基本概念
1、什么是软件
软件是计算机系统中与硬件相互依存的一部分,包括程序、数据、与其相关文档的完整结合。
软件 = 程序 + 数据 + 文档
2、软件的分类
按照功能划分:
系统软件:如操作系统、数据库管理系统,各种驱动软件等
应用软件:如Office、金山词霸、等
按照技术结构划分:
单机版本:如Office,画图工具等
C/S结构软件:如、MSN等
B/S结构软件:如新浪、搜狐、google等
按照用户划分:
产品软件:Office、财务处理软件、金山毒霸等
项目软件:如为企业定制的OA系统等
3、软件的生命周期及常见的开发模型
软件的生命周期——指软件产品从计划到软件交付使用,直到最终退出为止的过程。
包括计划阶段、分析阶段、实现阶段、测试阶段、运行维护阶段。
软件开发模型:
① 瀑布模型:严格遵循软件生命周期各阶段的固定顺序,一个阶段完成再进入另一阶段,适用于结构化开发方法。瀑布模型是文档驱动的。
传统的瀑布模型过于理想化了,瀑布模型是一种线性的开发模型,具有不可回溯性。
实际的瀑布模型是带“反馈环”的,如图所示:
瀑布模型适用于以下特征的软件开发项目:
(1)在软件开发的过程中,需求不发生或发生很少变化,并且开发人员可以一次性获取到全部需求。否则,由于瀑布模型较差的可回溯性,在后续阶段中需求经常性的变更需要付出高昂的代价。
(2)软件开发人员具有丰富的经验,对软件应用领域很熟悉。
(3)软件项目的风险较低。瀑布模型不具有完善的风险控制机制。
② 快速原型模型:开发人员对用户提出问题进行总结,就主要需求达成一致意见,快速地建立一个原型系统并运行,然后对原型进行反复修改,使之完善。
快速原型模型适用于具有以下特征的软件开发项目:
(1)已有产品或产品的原型( 样品),只需客户化的工程项目。
(2)简单而熟悉的行业或领域。
(3)有快速原型开发工具。
(4)进行产品移植或升级
③ 增量模型:增量模型也称为渐增模型。增量模型是把待开发的软件系统模块化,将每个模块作为一个增量组件,从而分批次地分析、设计、编码和测试这些增量组件。运用增量模型的软件开发过程是递增式的过程。开发人员可以分批次将软件产品提交给用户。
增量模型适用于具有以下特征的软件开发项目:
(1)软件产品可以分批次地进行交付。
(2)待开发的软件系统能够被模块化。
(3)软件开发人员对应用领域不熟悉,难以一次性地进行系统开发。
(4)项目管理人员把握全局的水平较高。
④ 螺旋模型:螺旋模型是一种用于风险较大的大型软件项目开发的过程模型。该模型将瀑布模型与快速原型模型结合起来,并且加入了风险分析。它把开发过程分为制定计划、风险分析、实施工程、客户评估。
⑤ 喷泉模型:喷泉模型是一种过程模型,同时也支持面向对象开发。分析模型和设计模型采用相同的符号标示体系,各阶段之间没有明显的界限,而且常常重复、迭代地进行(“喷泉”一词体现了面向对象方法的迭代和无间隙性)。迭代是指各阶段需要多次重复,无间隙性是指各个阶段之间没有明显的界限,并常常在时间上互相交叉,并行进行。
4、软件的开发流程
需求分析、概要设计、详细设计、编码、测试
5、软件设计和开发方法
软件的设计原则:高内聚,低耦合
软件的设计工具:UML图:用例图、类图、协作图、顺序图、状态图、活动图
软件的开发方法:
结构化的方法
- 面向数据流的方法——概要设计阶段
- 面向数据结构的方法——详细设计阶段
- 面向对象的方法——系统设计、对象设计
二、软件测试的基本概念
1、什么是软件测试
使用人工或自动的手段,来运行或测试软件系统的过程,目的是检验软件系统是否满足规定的需求,并找出与预期结果之间的差异。(标准定义IEEE )
软件测试就是“验证(Verification)”和“有效性确认(Validation)”活动构成的整体,即软件测试V&V 。(标准观点)
概括起来,软件测试就是贯穿整个软件开发生命周期,对软件产品(包括阶段性产品)进行验证和确认的活动过程,其目的是尽快尽早地发现在软件的缺陷。
2、软件测试的目的
从用户角度看的目的:通过软件测试发现隐藏的错误和缺陷,考虑是否可以接受该产品。
从开发者角度看的目的:表明软件产品不存在错误,验证软件实现了所有用户的要求。
从测试人员角度看的目的:发现错误,预测错误,提供软件可靠性错误,对软件做出评价。
① 帮助开发人员、测试工程师发现问题、分析问题。
② 减少软件的缺陷数目或者降低软件缺陷的密度。
③ 提高软件的可靠性
④ 评估软件的性能指标。
⑤ 增加用户对软件的信心。
⑥ 测试的最终目的是尽快尽早地发现在软件中的缺陷,通过修正各种错误和缺陷提高软件质量,回避软件发布后由于潜在的软件缺陷和错误造成的隐患所带来的商业风险。
3、软件测试的原则
- 所有的测试都应追溯到用户需求
- 应该尽早地和不断地进行软件测试——只要测试在生命周期中进行得足够早,就能够提高被测软件的质量,这就是预防性测试的基本原则
- 完全测试是不可能的,测试需要终止
- 测试不能显示软件潜在的缺陷
- 充分注意测试中的集群现象(二八定理)
- 程序员应避免检查自己写的程序
- 尽量避免测试的随意性
二八定理:一般情况下,80%软件缺陷出现在20%的功能区域,在测试过程中,投入主要的人力和精力重点测试这20%的功能区域。
4、软件测试的分类
每种测试的具体定义可以参考这篇博客:软件测试(理论基础) – LangZXG – 博客园 (cnblogs.com)
这里就简单列举出来。
5、软件测试的流程与阶段、
测试流程:需求分析、制定测试计划、编写测试用例、执行测试、编写测试报告
测试阶段:需求验证、单元测试、集成测试、确认测试、系统测试、验收测试
确认测试:检验所开发的软件是否满足SRD(System Requirement Document)中定义的需求、性能要求,以及软件配置是否完全正确。
6、测试用例
测试用例(TC):
在测试执行之前设计的一套详细的测试方案,是描述输入实际值和预期输出行为或者结果的文档,同时也标识了测试过程、结果与约束。
编写测试用例的唯一标准就是用户需求,具体的参考资料是《需求规格说明书》。
测试用例的八大要素:
用例编号,所属模块,测试标题,重要级别,前置条件,测试输入,操作步骤,预期结果
测试用例的四个基本属性:
- 代表性:能够代表并覆盖各种合理的和不合理合法的和不合法的、边界的和越界的以及极限的输入数据、操作等。
- 针对性:对程序中的可能存在的错误有针对性地测试。
- 可判定性:测试执行结果的正确性是可判定的,每一个测试用例都应有相应的期望结果。
- 可重现性:对同样的测试用例,系统的执行结果应当是相同的。
7、白盒测试
白盒测试又称为结构测试或逻辑驱动测试,它是把测试对象看成一个透明的盒子,它允许测试人员利用程序内部的逻辑结构设计测试用例,对程序所有逻辑路径进行测试。
采用白盒测试方法必须遵循以下原则:
- 保证一个模块中的所有独立路径至少被测试一次。
- 对所有的逻辑判定均需测试取真和取假两种情况。
- 在上下边界及可操作范围内运行所有循环。
- 检查程序的内部数据结构,保证其结构的有效性。
测试方法:静态测试方法、动态测试方法
静态测试: 不要求在计算机上实际执行所测试的程序,主要以一些人工的模拟技术对软件进行分析和测试,如代码检查法、静态结构分析法等;
动态测试: 是通过输入一组预先按照一定的测试准则构造实际数据来动态运行程序,达到发现程序错误的过程。白盒测试中的动态分析技术主要有逻辑覆盖法和基本路径测试法。
这里我们重点介绍动态测试。
动态测试
① 逻辑覆盖法
以程序内部的逻辑结构为基础来设计测试用例的测试技术,通过对程序内部的逻辑结构的遍历来实现程序的覆盖。
6种覆盖标准:
- 语句覆盖(SC)
设计足够的测试用例,使得被测程序中每条语句至少执行一次。又称行覆盖、段覆盖、基本块覆盖,它是最常见的覆盖方式,是一种弱覆盖
- 判定覆盖(DC)
又称为分支覆盖,其原则是设计足够的测试用例,使得程序中每个判定语句的取真和取假分支至少被执行一次。
- 条件覆盖(CC)
指的是设计足够的测试用例,使判定语句中的每个逻辑条件取真值与取假值至少出现一次。
条件分支覆盖的状态下仍旧不能满足判定覆盖
- 判定-条件覆盖(CDC)
设计足够的测试用例,使得判定语句中所有条件的可能取值至少出现一次,同时,所有判定语句的可能结果也至少出现一次。
- 条件组合覆盖(MCC)
设计足够的测试用例,使得每个判定中条件的各种可能组合都至少执行一次。
- 路径覆盖
设计足够的测试用例,使得程序中的每一条可能组合的路径都至少执行一次。
② 基本路径测试法
路径测试就是从一个程序的入口开始,执行所经历的各个语句的完整过程。从广义的角度讲,任何有关路径分析的测试都可以被称为路径测试。
完成路径测试的理想情况就是做到路径覆盖,但对于复杂性较大的程序要做到所有的路径覆盖(测试所有可执行路径)是不可能的。
在不能做到所有路径覆盖的情况下,如果某一程序的每一个独立路径都被执行到,那么就可以认为程序中的每个语句都已经检验过了,即达到了语句覆盖。这种测试方法就是通常所说的基本路径测试法。
基本路径测试法是在程序控制流图的基础上,通过分析控制构造的环路复杂性,导出基本可执行路径的集合,从而设计测试用例的方法。设计出的测试用例要保证在测试中程序的每个可执行语句至少执行一次。
基本路径测试法包括以下4个步骤:
- 以详细设计或源代码作为基础,绘制程序的控制流图。
- 计算得到的控制流图G的环路复杂性V(G)。
- 确定独立路径的集合。通过程序控制流图导出基本路径集,列出程序的独立路径。所谓独立路径,是指至少包含一条新边的路径,也就是包含一些前面的路径未包含的语句,当所有的语句都包含了,基路径集就够了。(线性无关路径)
- 设计测试用例,确保基本路径集中每条路径的执行。
8、黑盒测试
黑盒测试又称为功能测试,它是通过测试来检验程序的每个功能是否能正常使用。在测试中,将程序看成一个不能打开的黑盒子,在完全不考虑内部结构的情况下,在 程序接口进行测试 ,检查程序是否能适当的接受输入数据从而产生正确的输出信息。
黑盒测试主要针对 功能测试 和 软件界面测试 。
测试方法:等价类划分法、边界值分析法、判定表/因果图法、正交实验法
9、缺陷管理
软件缺陷
指存在于软件(程序、数据、文档)中的那些不符合用户需求的问题。
缺陷的基本概念
(1)缺陷(defect):存在于软件之中的偏差,可被激活,以静态的形式存在于软件内部,相当于bug;
(2)故障(Fault):软件运行中出现的状态,可引起意外情况,若不加处理,可产生失效,是一个动态行为;
(3)失效(Failure):软件运行时产生的外部异常行为结果,表现与用户需求不一致,功能能力终止,用户无法完成所需要的应用。
软件缺陷的发现手段
同行评审、测试、管理评审、QA发现、项目组内部发现、客户反馈
为了便于缺陷的定位、跟踪和修改,要对所发现的缺陷,按照缺陷的严重程度、优先级、发现阶段、修复阶段、缺陷的性质、所属功能模块、系统环境等方面进行分类和统计。
缺陷密度
基本的缺陷测量是以每千行代码的缺陷数(个/KLOC)来测量的,其测量单位是defects/KLOC。
软件缺陷报告内容
1、缺陷标题/简单描述
对测试执行过程中实际出现的问题的描述,尽量要简单概要。
2、重现步骤/详细描述
(1)描述问题的基本环境,包括操作系统、硬件环境、网络环境、被测试软件的运行环境;
(2)简单概括的描述清楚软件出现异常时,测试人员的操作步骤和使用数据;
(3)缺陷原因的分析;比如说:因为不支持字符集,而导致的乱码…
(4)要写清楚,重复操作了多少次,这个bug依然出现。(不能操作一次就提交bug,因为有可能是自己操作失误。)
(5)相关附件:为了让开发人员更好的了解Bug。 (如果从GUI界面上可以反映出软件的异常,可以截取界面,粘贴在问题单上 或者 日志、数据包);
(6)属性(在下面详细说明):缺陷报告中除了对缺陷的基本描述外,我们还要对其属性进行说明。
软件缺陷的相关属性
1、缺陷发现人
2、缺陷发现时间
3、缺陷状态
| New | 缺陷的初始状态 |
| Open | 开发人员开始修改缺陷 |
| Fixed | 开发人员修改缺陷完毕 |
| Closed | 回归测试通过 |
| Reopen | 回归测试失败 |
| Postpone | 推迟修改 |
| Rejected | 开发人员认为不是程序问题,不用修改 |
| Duplicate | 与已提交的 Defect 重复 |
| Abandon | 被 Reject 和 Duplicate 的 Defect,测试人员确认后的确不是问题,将 Defect 置为此状态 |
New–Open–fixed–closed这个状态是一个比较理想的缺陷流程,也就是测试人员提交问题,开发人员接受并修改问题,然后测试人员进行回归测试通过
4、缺陷严重程度(Severity)
| 致命的软件缺陷(Fatal) | 造成系统或应用程序崩溃、死机、系统挂起,或造成数据丢失,主要功能完全丧失,导致本模块以及相关模块异常等问题。如代码错误,死循环,数据库发生死锁、与数据库连接错误或数据通讯错误,未考虑异常操作,功能错误等。 |
| 严重错误的软件缺陷(critical) | 系统的主要功能部分丧失、数据不能保存,系统的次要功能完全丧失。问题局限在本模块,导致模块功能失效或异常退出。如致命的错误声明,程序接口错误,数据库的表、业务规则、缺省值未加完整性等约束条件。 |
| 一般错误的软件缺陷(major) | 次要功能没有完全实现但不影响使用。如:提示信息不太准确,或用户界面差,操作时间长,模块功能部分失效等,打印内容、格式错误,删除操作未给出提示,数据库表中有过多的空字段等。 |
| 较小错误的软件缺陷(Minor) | 使操作者不方便或遇到麻烦,但它不影响功能性的操作和执行,如错别字、界面不规范(字体大小不统一,文字排列不整齐,可输入区域和只读区域没有明显的区分标志),辅助说明描述不清楚。 |
| 建议问题的软件缺陷(Enhancemental) | 由问题提出人对测试对象的改进意见或测试人员提出的建议、质疑。 |
5、缺陷的优先级(Priority)
6、缺陷的类型
7、缺陷所属版本
8、缺陷修改日期
三、常见自动化测试工具
1、Selenium
Selenium是一系列基于Web的自动化工具,提供一套测试函数,用于支持Web自动化测试。函数非常灵活,能够完成界面元素定位、窗口跳转、结果比较。具有如下特点:
- 多浏览器支持
- 如IE、Firefox、Safari、Chrome、Android手机浏览器等。
- 支持多语言
- 支持多操作系统
- 如Windows、Linux、IOS、Android等。
- 开源免费
- 官网:http://www.seleniumhq.org/
Selenium框架由多个工具组成,包括:Selenium IDE,Selenium RC,Selenium WebDriver和SeleniumRC。
以百度搜索为例:
/ * @Description: 通过selenium操作浏览器打开百度进行搜索 * selenium版本:3.12.0; 通过maven管理jar包 * 开发工具:IDEA * jdk:1.8 * 浏览器:chrome 75+ */ public class BaiduSearch { public static void main(String[] args) { // 1.创建webdriver驱动 WebDriver driver = new ChromeDriver(); // 2.打开百度首页 driver.get("https://www.baidu.com"); // 3.获取输入框,输入selenium driver.findElement(By.id("kw")).sendKeys("selenium"); // 4.获取“百度一下”按钮,进行搜索 driver.findElement(By.id("su")).click(); // 5.退出浏览器 driver.quit(); } }
元素定位
我们必须告诉 selenium 怎么去定位元素,用来模拟用户的动作,或者查看元素的属性和状态,以便于我们可以执行检查。
8种的定位方式
- id
- name
- class name
- tag name
- link text
- partial link text
- xpath
- css selector
与浏览器交互
WebDriver 提供了一系列的 API 来和浏览器进行交互,如下:
| get(String url) | 访问目标 url 地址,打开网页 |
| getCurrentUrl() | 获取当前页面 url 地址 |
| getTitle() | 获取页面标题 |
| getPageSource() | 获取页面源代码 |
| close() | 关闭浏览器当前打开的窗口 |
| quit() | 关闭浏览器所有的窗口 |
| findElement(by) | 查找单个元素 |
| findElements(by) | 查到元素列表,返回一个集合 |
| getWindowHandle() | 获取当前窗口句柄 |
| getWindowHandles() | 获取所有窗口的句柄 |
通过 WebElement 实现与网站页面上元素的交互,这些元素包含文本框、文本域、按钮、单选框、div等。
常见API:
| click() | 对元素进行点击 |
| clear() | 清空内容(如文本框内容) |
| sendKeys(…) | 写入内容与模拟按键操作 |
| isDisplayed() | 元素是否可见(true:可见,false:不可见) |
| isEnabled() | 元素是否启用 |
| isSelected() | 元素是否已选择 |
| getTagName() | 获取元素标签名 |
| getAttribute(attributeName) | 获取元素对应的属性值 |
| getText() | 获取元素文本值(元素可见状态下才能获取到) |
| submit() | 表单提交 |
元素等待机制
在对元素进行定位时,有时候网页加载时间比较长,元素还没有加载出来,这个时候去查找这个元素的话程序中就会抛出异常,所以我们在编写代码时需要考虑延时问题。
硬性等待:
不管你浏览器元素是否加载完成,都要进行等待设置好的时间,利用 java 语言中的线程类 Thread 中的 sleep 方法,进行强制等待。
Thread.sleep(long millis) 该方法会让线程进行休眠。
隐式等待:
通过代码设置一个等待时间,如果在这个等待时间内,网页加载完成后就执行下一步,否则一直等待到时间截止。
driver.manage.timeouts.implicitlyWait(long time, TimeUtil unit);
隐式等待也有个弊端,因为这个设置是全局的,程序需要等待整个页面加载完成,直到超时,有时候我需要找的那个元素早就加载完成了,只是页面上有个别其他元素加载比较慢,程序还是会一直等待下去。直到所有的元素加载完成在执行下一步。
显式等待:
等待指定元素设置的等待时间,在设置时间内,默认每隔 0.5s 检测一次当前的页面这个元素是否存在,如果在规定的时间内找到了元素则执行相关操作,如果超过设置时间检测不到则抛出异常。默认抛出异常为:NoSuchElementException。推荐使用显示等待。
WebDriberWait wait = new WebDriverWait(dirver, timeOutInSeconds); wait.nutil(expectCondition);
页面加载超时设置
通过 TimeOuts 对象进行全局页面加载超时的设置,该设置必须放置 get 方法之前
driver.manage().timeouts().pageLoadTimeout(5, TimeUnit.SECONDS); driver.get("https://www.baidu.com");
特殊元素操作
1、弹出框处理(alert、confirm)
操作 alert、confirm 弹出框,可以通过 Alert 对象来进行操作,Alert类包含了确认、取消、输入和获取弹出窗内容。
| Alert.getText() | 获取弹出框内容。 |
| Alert.accept() | 接受弹窗的提示,相当于点击确认按钮。 |
| Alert.dismiss() | 取消提示窗。 |
| Alert.sendKeys(String s) | 给弹窗输入内容。 |
注:如果弹出框不是 js 原生的 alert 弹窗,我们还是按照原来的获取元素的方法
2、iframe 切换
有时候我们定位元素的时候,发现怎么都定位不了。 这时候你需要查一查你要定位的元素是否在iframe 里面。
什么是iframe?
iframe 就是HTML 中,用于网页嵌套网页的。 一个网页可以嵌套到另一个网页中,可以嵌套很多层。
使用selenium 操作浏览器时,如果需要操作 iframe 中的元素,首先需要切换到对应的内联框架中。
selenium 给我们提供了三个重载的方法,进行操作iframe;
// 方法一:通过 iframe的索引值,在页面中的位置 driver.switchTo().frame(index); // 方法二:通过 iframe 的name 或者id driver.switchTo().frame(nameOrId); // 方法三:通过iframe 对应的webElement driver.switchTo().frame(frameElement);
注:如果已经切换进入了其中的一个 iframe 中,再想对 iframe 外的元素进行操作,需要切换回到默认的页面中,否则会找不到元素。
// 切换到默认内容页面 driver.switchTo().defaultContent();
3、浏览器窗口的切换
有时候后在操作浏览器,可能打开了一个新的窗口,这个时候如果要对新窗口的元素进行操作,需要切换到新窗口中去,怎么去切换呢?在 selenium 中有个叫句柄的概念。
什么是句柄,简单理解就是浏览器窗口的一个标识,浏览器打开的每个窗口都有唯一的一个标识,也就是句柄,我们可以通过句柄来进行窗口之间的切换,从而来达到我们操作不同窗口的元素。
WebDriver 中提供了两个 API 来获取窗口的相关句柄:
// 获取当前窗口的句柄 String handle = driver.getWindowHandle(); // 获取所有窗口的句柄,返回一个集合 Set<String> handles = driver.getWindowHandles();
获取到句柄后,通过对应的方法进行切换:
// 切换到窗口 driver.switchTo.windwo(String handle);
4、select 下拉框处理
如果一个页面元素是一个下拉框(select),对应下拉框的操作,selenium有专门的类 Select 进行处理。其中包含了单选和多选下拉框的各种操作
| void deselectAll() | 取消所有选择项,仅对下拉框的多选模式有效,若下拉不支持多选模式,则会抛出异常 UnsupportedOperationException(不支持的操作) |
| void deselectByIndex(int index) | 取消指定index的选择,index从零开始,仅对多选模式有效,否则抛出异常 UnsupportedOperationException(不支持的操作) |
| void deselectByValue(String value) | 取消Select标签中,value为指定值的选择,仅对多选模式有效,否则抛出异常 UnsupportedOperationException(不支持的操作) |
| void deselectByVisibleText(String Text) | 取消项的文字为指定值的项,例如指定值为Bar,项的html为Bar,仅对多选模式有效,单选模式无效,但不会抛出异常 |
WebElement getFirstSelectedOption() |
获得第一个被选中的项,单选多选模式均有效,当多选模式下,没有一个被选中时,会抛出NoSuchElementException异常 |
ListgetOptions() |
获得下拉框的所有项,单选多选模式均有效,当下拉框没有任何项时,返回空列表,不会抛出异常 |
boolean isMultiple() |
判断下拉框是否多选模式 |
| void selectByIndex(int index) | 选中指定index的项,单选多选均有效,当index超出范围时,抛出NoSuchElementException异常 |
| void selectByValue(String value) | 选中所有Select标签中,value为指定值的所有项,单选多选均有效,当没有适合的项时,抛出NoSuchElementException异常 |
| void selectByVisibleText(String text) | 选中所有项的文字为指定值的项,与deselectByValue相反,但单选多选模式均有效,当没有适合的项时,抛出NoSuchElementException异常 |
5、带 readonly 属性的元素操作
标签元素如果带有 readonly 属性,表示只读不能进行编辑,如果我们需要操作这样的元素,需要把这个 readonly 属性进行移除后,再进行操作。
删除标签属性的话,webdriver 没有对应的 API,我们使用 JavaScript 脚本来进行操作。
// 通过js来移除readonly属性 String removeAttr = "document.getElementById('train_date').removeAttribute('readonly');"; // 执行js ((JavascriptExecutor)driver).executeScript(removeAttr);
6、日期控件操作
对于页面中出现时间控件选择时,一般分为两种:
(1)控件没有限制手动填写的,我们直接使用 sendKeys() 方法进行赋值即可。
driver.findElement(By).sendKeys("2020-03-30");
(2)控件限制了手动输入的,只能通过点击控件时间进行输入的,我们就需要使用 js 脚本进行操作了。
// 获取js执行器 JavaScriptExecutor js = (JavaScriptExecutor)driver; // 对时间输入框进入赋值 String script = "document.getElementById('xxx').value='2020-03-30';"; // 执行 js.executeScript(script);
注:需要注意的是,不管使用哪种方式进行时间的赋值,一点要注意输入时间的格式是否符合系统的要求
7、文件上传
对于通过 input 标签实现的上传功能,可以将其看作是一个输入框,即通过 sendKeys() 指定本地文件路径的方式实现文件上传。
//定位上传按钮, 添加本地文件 driver.findElement(By.name("file")).sendKeys("D:\\upload_file.txt"); Thread.sleep(5000);
注:sendKeys 参数为文件的绝对路径,并且上传的文件一定要存在,否则会抛异常。
控制浏览器操作
篇幅有限这里就先不说了,大家可以看看这篇selenium 使用教程详解-java版本 – 小葛师兄 – 博客园 (cnblogs.com)
写的非常详细完整
模拟鼠标键盘操作
同上
2、Pytest
pytest 是一个用于 Python 的测试框架,支持简单的单元测试和复杂的功能测试。它以其简单、易用、灵活的特点,受到了许多开发者的青睐。
pytest框架可以轻松编写小型、可读的测试,并可以扩展支持应用程序和库的复杂功能测试。
pytest 的主要特点包括:
- 简洁的语法:无需继承特定的测试类,只需使用简单的函数即可编写测试。
- 强大的断言:内置丰富的断言方法,提供详细的失败信息。
- 自动发现:自动发现测试文件和测试函数,无需显式地注册测试。
- 插件系统:丰富的插件生态系统,支持扩展和定制。
基本使用
1、pytest 默认测试用例
pytest 默认测试用例的格式:
- 模块名:模块名(文件名)通常被统一放在一个 testcases 文件夹中,然后需要保证模块名以test_ 开头或 _test 结尾,例如 test_demo1 或 demo2_test
- 类名:测试类类名必须以 Test 开头,并且不能带有 init 方法
- 方法名:测试方法名(Case 名)必须以 test_ 开头,例如 test_demo1(self)、 test_demo2(self)
test_demo1.py
class TestDemo: def test_demo1(self): print("测试用例1") def test_demo2(self): print("测试用例2")
2、全局配置文件 pytest.ini
我们可以在 pytest.ini 中进行一些属性的配置来修改 pytest 的默认属性,我们需要在根目录下创建,名称必须是 pytest.ini。
[pytest] #参数 addopts = ‐vs # 默认的执行路径,它会默认执行该文件夹下所有的满足条件的测试case testpaths = ./testcases # 文件命名规则 python_files = test_*.py # 类名命名规则 python_classes = Test* # Case命名规则 python_functions = test_* # 标记 markers = # 冒烟规则 smoke:冒烟用例 product_manage:商品管理
3、执行 pytest
方式一:使用命令行执行
最简单的就是直接在 console 命令行输入 pytest,如果存在 pytest.ini,它会根据文件内容进行执行; 如果没有就按照默认格式执行。但是我们可以通过一些参数来强化 pytest 参数指令:
# -vs: -v输出详细信息 -s输出调试信息
pytest -vs
# -n: 多线程运行(前提安装插件:pytest-xdist)
pytest -vs -n=2
# --reruns num: 失败重跑(前提安装插件:pytest-rerunfailres)
pytest -vs --reruns=2
# -x: 出现一个用例失败则停止测试
pytest -vs -x
# --maxfail: 出现几个失败才终止
pytest -vs --maxfail=2
# --html: 生成html的测试报告,后面 需要跟上所创建的文件位置及文件名称(前提安装插件:pytest-html)
pytest -vs --html ./reports/result.html
# -k: 运行测试用例名称中包含某个字符串的测试用例,我们可以采用or表示或者,采用and表示都
pytest -vs -k "qiuluo"
pytest -vs -k "qiuluo or weiliang"
pytest -vs -k "qiuluo and weiliang"
# -m:冒烟用例执行,后面需要跟一个冒烟名称,执行user_manage这个分组
pytest -vs -m user_manage
class TestDemo: # 我们在Case上采用@pytest.mark. + 分组名称,就相当于该方法被划分为该分组中 # 注意:一个分组可以有多个方法,一个方法也可以被划分到多个分组中 @pytest.mark.user_manage def test_demo1(self): print("user_manage_test1") @pytest.mark.product_manage def test_demo2(self): print("product_manage_test1") @pytest.mark.user_manage @pytest.mark.product_manage def test_demo3(self): print("manage_test1") # 执行 pytest -vs -m user_manage
方式二:使用 main 方法执行
if __name__ == '__main__': pytest.main() if __name__ == '__main__': pytest.main(["‐vs"])
4、跳过方法
pytest 的跳过案例方法其实和 unittest 是完全相同的,我们只需采用 skip 或 skipif 方法来指定参数并贴在方法上即可跳过。
# @pytest.mark.skip(跳过原因) # @pytest.mark.skipif(跳过条件,跳过原因) # 示例 class TestDemo: workage2 = 5 workage3 = 20 @pytest.mark.skip(reason="无理由跳过") def test_demo1(self): print("我被跳过了") @pytest.mark.skipif(workage2<10,reason="工作经验少于10年跳过") def test_demo2(self): print("由于经验不足,我被跳过了") @pytest.mark.skipif(workage3<10,reason="工作经验少于10年跳过") def test_demo3(self): print("由于经验过关,我被执行了") def test_demo3(self): print("我没有跳过条件,所以我被执行了")
5、pytest 前后置方法
篇幅有限,详细请看 Python测试框架 pytest : 从零开始的完全指南_python pytest-CSDN博客
参考文章:
https://blog.csdn.net/weixin_/article/details/
软件测试(理论基础) – LangZXG – 博客园 (cnblogs.com)
https://blog.csdn.net/_/article/details/
selenium 使用教程详解-java版本 – 小葛师兄 – 博客园 (cnblogs.com)
Python测试框架 pytest : 从零开始的完全指南_python pytest-CSDN博客
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/117992.html







