北京团建网站/优秀软文范例
文章目的
显示不同的博客能获得多少博客质量分
(这是关于博客质量分的测试 https://www.csdn.net/qc) 这个博客得了 83 分。怎么才能得到更多分数?
正文
我们谈了不少测试的名词, 软件是人写的, 测试计划和测试用例也是人写的, 人总会犯错误。错误发生之后, 总有人问: 为什么这个bug 没有测出来啊?! 我们看看一类简单的bug是如何发生的,以及如何预防它们再度发生:
闰年
软件少不了和日期打交道, 日历系统算是人类的一个遗留系统 (legacy system), 这个系统在逐步进化的过程中, 打了好多补丁, 闰年就是补丁之一。
关于闰年,现在的 规格说明书
(spec) 非常简单:
年份被 4 整除的,就是闰年, 但是被 100 整除的年份不闰,被 400 整除的年份又是闰年。
但是,人们在写软件的时候,还是犯了不少错误。
错误之一
下面是C# 的代码片段, 这段程序对么?
public static bool IsLeapYear(int year)
{System.Diagnostics.Debug.Assert(year >= 1900);if (year % 400 == 0)return true;if (year % 100 == 0)return false;if (year % 4 == 0)return true;return false;
}
1900 年是闰年么? 根据我们上面说的规格说明书,这不是一个闰年。
如果你要写这个程序的单元测试, 你会列出多少个测试用例? 你们保证所有代码路径都被覆盖么?
要写测试用例, 一个暴力的做法是穷举所有例子, 但是这有问题 – 你穷举不完
即使穷举了很多例子, 但是它们未必能帮助发现 独特
的问题. 例如你可以测试输入 为 100, 101, 102, 103, 104, … 但是你仍然不知道新加的一个测试数字 105 是否测试了 以前没有测试过的情况
, 也就是说, 105 这个测试数据,可能和 100,101 这些数字都是等价的。 但是独特的测试数据,可能还有很多。
这里我们要引入 等价类 (Equivalence)
这一概念。 一个粗浅的做法是:
如果一个函数可以返回 true | false, 你至少得有两类测试集合, 让它分别返回 true | false
如果你知道这个函数工作的原理, 或者了解程序要反映的现实世界, 你可以举出更详细的等价类, 例如针对 IsLeapYear():
- 被 400 整除的年份
- 被 100 整除, 但是不被400 整除的年份
- 被 100 整除, 同时被400 整除的年份
- 被 4 整除, 但是不被100 整除的年份
- 被 4 整除, 同时被100 整除的年份
- 偶数, 不被4 整除的年份
- 奇数年份
- 其它非法输入的年份
但是,在全世界被广泛使用的电子表格软件 Excel 就有这样一个Bug:Excel 的日期计算功能认为1900年是一个闰年。
故事是这样的,在 PC 萌芽的 1980 年代, 这类电子表格软件的市场领头羊是Lotus 1-2-3这一款软件:
来源: http://en.wikipedia.org/wiki/Lotus_1-2-3
Lotus 1-2-3 占据了大部分市场份额,这类软件在内部把日期保存为 “从1900/1/1 到当前日期的天数” 这样的一个整数。 不过,它的日期计算功能有一个小Bug,就是把1900 年当作闰年。这样,内部保存的 “天数” 就是多算了 1900 年并不存在的 2/29 号。 Excel 作为后来者,要支持 Lotus 1-2-3 的数据文件格式,这样才能正确处理别的软件产生的格式文件,Excel 只好也这么照做。 这个错误就这么延续下来了,每一版本都有人报告,但是都没有改正。我们可以在Excel 中试试看:
在任意格子(cell)中输入“=DATE(1900,2,28)”,并且定义这个格子的格式为数字。大家可以看到数值变为:59。表明1900/2/28 是1900/1/1开始的第59天。
输入“=DATE(1900,2,29)”,可以看到 60! 这是一个不存在的日期!
输入“=DATE(1900,3,1)”,数值是61,事实上,这应该是60。从这一天开始的所有日期都错了一天。
改正这个bug,技术上一点问题都没有。
改好了,我们更新 Excel 的版本,发布吧! 但是在现实中会出现下列问题:
(1)几乎所有现存文件的日期数据都要减少一天,所有依赖于日期的 Excel公式也要做检查和修改。可以想象在计算利率,判断日期是否相等这些问题上都会出现细小而不能忽视的问题。 这在现实生活会造成很大的麻烦。
(2)Excel的日期问题解决了,但是其他软件还是有这个Bug,数据文件在不同软件中使用,就会有很头痛的兼容性问题。
错误之二: 计算错误
一个应用程序从另一个模块中接到一个数值, 是当天距离 [1980/1/1] 的天数, 现在要求这个程序返回今天的年份。 下面的程序怎么样? 有bug 么?
public static int NumberToYear(int days)
{int year = 1980; /* start with 1980 */System.Diagnostics.Debug.Assert(days >= 0);while (days > 365){if (IsLeapYear(year)){if (days > 366){days -= 366;year ++;}}else{days -= 365;year ++;}}return year;
}
程序员都知道程序经常在边界条件附近出错, 针对IsLeapYear(), 你还可以得出下面两个测试用例:
- 设计允许的最小的年份
- 设计允许的最大的年份
啊, 设计中没有考虑这个? 那这个设计要出现问题。 在1950-70 年代, 很多程序用两位数字表示年份 (00 – 99), 那些聪明的程序员认为这已经足够了, 没想到这些程序和设计影响了很多要和它们兼容的程序 (就像 Excel 要兼容 Lotus 1-2-3 那样), 到了1990年代后期, IT 业花了很多人力物力来解决 Y2K 的千年虫问题。 一些程序员非常钟爱的 UNIX 操作系统 (32 位) 也有自己的千年虫问题, 它会发生在 2038 年! 到时候人们还会用32位的机器么? 也许在一个大家想不到的关键部位, 一些老旧的, 嵌入式的 Unix 系统会悄悄地发作…
除了从外部的输入/输出来设计测试用例, 我们也可以从内部考虑, 看看这些测试用例是否把所有语句都覆盖了。 但是要注意, 即使所有语句都被测试用例覆盖了, 程序还是可能出错!
例如, 我们测试 NumberToYear() 这个函数, 分析它的各个条件, 我们推算出我们的数据要覆盖下面一些情况:
- 输入的 day 大于 365
- 输入的 day 小于 365
- 输入的 day 大于 366 并且1980 年到那一年中, 至少有一年是闰年, 例如输入一个2008年的某一天。
- 输入的 day 大于 366 并且1980 年到那一年中不包括闰年。
这样是不是就把所有路径都包括了? 程序就没有错了?
不巧的是, 这个程序用在了某著名公司的产品上, 出品的前两年没什么事, 到了2008 年的最后一天 (那一年有366 天), 出了一个问题:
正如下面的代码显示的,年份一直增加到了 2008, 这时候, day == 366, 我们看看循环能做下去么?
if (IsLeapYear(year))
{if (days > 366) //day == 366, 不满足条件 {days -= 366;year ++;}
}
所以 day 没有减少, year 也没有增加, 循环又继续下去, 任何条件都没有改变, 进入了死循环!
不幸的是, 这个程序经过了种种测试, 进入了市场. 于是, 在2008 年的最后一天, 许多用户发现他们的 Zune Player (只限于 Zune 30 型号) 开机之后就进入死锁状态…
Microsoft says Zune players working again - USATODAY.com
http://www.zuneboards.com/forums/showthread.php?t=38143
官方的说法是 - 大家等到明天就好了! 不用说这对于用户, 对于产品的口碑, 对于这个代码的开发者, 测试者是一个极大的打击!
正确而简明的算法
也有程序员提出:
@bnu_chenshuo: 文中的函数可用一句话搞定
int NumberToYear(int days)
{ return 1980 + 100 * days / 36525;
}
我们看到,这段程序用了 36525 这个魔术数字,这个数字是怎么来的?因为近代科学测量的结果是:地球绕太阳转一圈,准确值是365天小5时48分46秒。如果用天为单位,就是 365.242199 天。
大家觉得这个函数有没有什么 bug? 在今后的 100 年都可以使用么?这个函数有多少条件分支,我们要如何去做分支测试,如何考察整个函数的覆盖率?
如果你是一个测试人员, 你应该增加什么测试用例呢? 如果用边界条件分析, 应该有至少 4 个新的测试用例:
- 闰年的第一天
- 闰年的最后一天
- 平年的第一天
- 平年的最后一天
错误之三: 没想到还有闰年
在IT 行业混了很多年的好处之一就是你可以看到不少 bug. 下面又来了一个:
Windows Home Server 与客户端的程序 connector 第一次连接时,需要 Server 为 connector 颁发安全证书。出于某种实现上无法避免的原因,客户端的证书日期一定要早于Windows Home Server 发布的日期,否则生成证书的函数会失败。Windows Home Server 是 2007年7月发布的。为了方便起见,设计中规定,给客户端生成证书的函数使用 2006 年作为年份。
作为一个程序员, 你如何实现这个设计呢? 一拍脑袋, 就取当天的日期, 然后把日期中的年字段改成 2006, 不就行了么?
然后到了 2008/2/29 这一天… 程序自动把日期改成了 2006/2/29,然后就悲剧了.
软件团队在自问: 为啥我们当初没测出来? 如果你是测试人员, 你会想到这个测试用例么?
错误之四: 闰年bug 一天损失 30 万
上面的错误都是外国软件公司搞的, 我们看看中国的软件 (还是嵌入式的软件) 也不甘落后, 也创出了自己的闰年bug:
广州出租车计价器无法识别闰年 损失约30万(图)-搜狐新闻
参考阅读
测试用例的等价类划分和边界条件分析:
http://en.wikipedia.org/wiki/Equivalence_partitioning
http://en.wikipedia.org/wiki/Boundary_value_analysis
相关文章:

软件测试的案例分析 - 闰年5
文章目的 显示不同的博客能获得多少博客质量分 (这是关于博客质量分的测试 https://www.csdn.net/qc) 这个博客得了 83 分。怎么才能得到更多分数? 正文 我们谈了不少测试的名词, 软件是人写的, 测试计划和测试用例也是人写的, 人总会犯错误。错误发生…...

Linux文件基础I/O
文件IO文件的常识基础IO为什么要学习操作系统的文件操作C语言对于函数接口的使用接口函数介绍如何理解文件文件描述符重定向更新给模拟实现的shell增加重定向功能为什么linux下一切皆文件?文件的常识 1.空文件也要在磁盘占据空间 2.文件 内容 属性 3.文件操作 对…...

HTML看这一篇就够啦,HTML基础大全,可用于快速回顾知识,面试首选
HTML 1 基础 1.1 DOCTYPE <!DOCTYPE> 文档类型声明,作用就是告诉浏览器使用哪种HTML版本来显示网页。 <!DOCTYPE html> 这句代码的意思是: 当前页面采取的是 HTML5 版本来显示网页. 注意: 声明位于文档中的最前面的位置,处于 标签之前。 …...

Altium Designer(AD)软件使用记录05-PCB叠层设计
目录Altium Designer(AD)软件使用记录05-PCB叠层设计一、正片层和负片层的介绍1、正片层(Signal)2、负片层(Plane)3、内电层的分割实现二、正片层和负片层的内缩设计1、负片设置内缩20H原则2、正片铺铜设置内缩1、设置规则2、重新铺铜三、AD的层叠设计四、叠层设计需要注意的问…...

ArcGIS动态表格批量出图
一.产品介绍:ArcGIS动态表格扩展模块Mapping and Charting Solutions,可用于插入动态表格,与数据驱动结合,出图效率无敌。注:优先选择arcgis10.2.2。 二、下载连接: https://www.xsoftnet.com/share/a001CX…...

ChatGPT真神奇,但是也真焦虑
ChatGPT火爆ChatGPT的火爆程度不用说也知道。就目前来说,已经开始冲击各行业了,比如客服、智能助手、语言学习、自然语言处理等等等。。ChatGPT冲击冲击最高的可能就是中间这个段位的了。高段位无法取代,但是低段位,通过使用ChatG…...

mos管驱动与米勒平台介绍、消除
mos驱动设计 1.选择适当的驱动芯片 为了控制MOSFET,需要使用专门的驱动芯片。选择合适的芯片需要考虑MOSFET的电压和电流需求。常见的驱动芯片包括IR2110、IR2184、MIC4424等。 2.设计电路 在驱动电路中,需要加入一些电路元件来保证MOSFET的顺畅工作…...

20230311英语学习
Philosophy of Food: Guidelines for an Authentic Approach to Eating 饮食哲学:值得思考的问题 Whats Philosophical About Food? Philosophy of food finds its basis on the idea that food is a mirror.Eating mirrors the making of a self, that is, the …...

【面试题】Nginx面试题汇总(无解答)
什么是Nginx?谈谈个人都理解,项目中是否用到,为什么要用,有什么优点?为什么要用Nginx?为什么Nginx性能这么高?Nginx怎么处理请求的?什么是正向代理和反向代理?使用“反向…...

Java面试总结(六)
进程和线程的区别 根本区别: 进程时操作系统资源分配的基本单位,而线程是处理器任务调度和执行的基本单位。 资源开销: 每个进程都有自己独立的代码和数据空间(程序上下文),进程之间的切换开销比较大&…...

Windows逆向安全(一)C与汇编的关系
前言 逆向是一种新型的思维模式也是软件开发领域中极为重要的技术,涵盖各种维度去深挖软件架构的本质和操作系统原理,学习逆向后可以在各领域中发挥至关重要的作用,其中包括黑灰色,安全开发,客户端安全,物…...

Lazada、Allegro、速卖通测评自养号技术(方法解析)
无论是亚马逊、拼多多Temu、shopee、Lazada、wish、速卖通、煤炉、敦煌、雅虎、eBay、TikTok、Newegg、乐天、美客多、阿里国际、沃尔玛、OZON、Joom、Facebook、Coupang、独立站、Cdiscount、Kaufland、DARTY、Allegro、MANO等平台测评自养号对于卖家来说算是一种低成本、高回…...

Vue3的composition API—setup函数, ref函数,reactive函数
1、Setup 函数 1.setup 是vue3中的一个配置项 2、setup是所有组件所需要的数据和方法都需要配置到setup中的 3、setup两种返回值: 若返回一个对象 若返回一个渲染函数 mian.js文件 注意:尽量不与Vue2混用 setup中无法访问vue2中的配置 不能是async函数…...

国外seo比较好的优化方法有哪些?
随着互联网的不断发展,SEO(搜索引擎优化)变得越来越重要。 对于国外市场,Google搜索引擎是最为重要的搜索引擎之一, 因此在优化国外网站时,需要将Google SEO优化作为首要任务。 关键词研究和优化 在进行…...

【JavaEE进阶】——第一节.Maven国内源配置
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 操作步骤 1.打开项目配置界面(当前项目配置) 2.检查并配置国内源 3.再次打开项目配置界面(新项目配置) 4…...

dockerFile编写
dockerFile编写 语法参数 # DockerFile常用指令 USER # 指定运行的用户,一般不用配置 FROM # 拉取基础镜像,一切从这里开始构建 ARG # 构建参数,只能在dockerFile中使用, # eg: JAR_FILEtarget/springboot-mongo-0.0.1-SNAPSHOT.jar MAI…...

jenkins扩展你的流水线
文章目录一、概述二、可信库和不可信库可信库不可信库三、内部库与外部库内部库SSH访问HTTP 访问外部库配置一个外部库四、在流水线脚本中使用库从源码版本控制中自动下载库加载库到脚本中Library 注解库步骤库指令五、Jenkins 项目中的库范围六、共享库代码的结构src示例一&am…...

Golang模糊测试入门
本教程介绍了 Go 中模糊测试的基础知识。通过模糊测试,随机数据会针对您的测试运行,以试图找到漏洞或导致崩溃的输入。可以通过模糊测试发现的一些漏洞示例包括 SQL 注入、缓冲区溢出、拒绝服务和跨站点脚本攻击。 在本教程中,您将为一个简单的函数编写模糊测试,运行 go 命…...

ARM uboot 的移植4 -从 uboot 官方标准uboot开始移植
一、添加DDR初始化1 1、分析下一步的移植路线 (1) cpu_init_crit 函数成功初始化串口、时钟后,转入 _main 函数,函数在 arch/arm/lib/crt0.S 文件中。 (2) 在 crt0.S 中首先设置栈,将 sp 指向 DDR 中的栈地址; #if defined(CONF…...

不用索引怎么优化百亿数据? | MySQL性能优化篇
文章目录数据库调优一、数据库调优原理1.1 为什么要进行MySQL数据库调优?1.2 什么影响数据库性能?1.3 数据库调优到底调什么?二、数据库压力测试2.1 什么是压测?2.2 JMeter简介2.3 驱动下载2.4 测试过程三、连接池3.1 压力测试连接…...

JavaScript(WebAPI)
目录 1.什么是Web API? 2.DOM和DOM树 3.获取元素 4.事件 5.操作元素 获取/修改元素内容 1.innerText 2. innerHTML 获取/修改元素属性 获取/修改表单元素属性 获取/修改样式属性 1.修改内联样式 2.修改元素应用的CSS类名 6.操作节点 新增节点 删除节点 7.案例…...

idea集成GitHub
设置 GitHub 账号绑定账号有两种方式:1. 通过授权登录2.如果上述登录不成功,用Token口令的方式登录,口令在github账号哪里生成,点击settings --->Developer settings --->pwrsonal access tokens ----> 复制口令到idea 口…...

软考高级信息系统项目管理师系列之四十一:项目组合管理
软考高级信息系统项目管理师系列之四十一:项目组合管理 一、项目组合管理内容二、项目组合管理基础概述1.项目组合定义及相关知识图2.项目组合、项目集和项目之间的关系3.项目组合模块具备的特征三、项目组合管理1.项目组合管理定义及要求2.不同级别管理之间的特性及关联3.项目…...

Spring——Spring整合Mybatis(XML和注解两种方式)
框架整合spring的目的:把该框架常用的工具对象交给spring管理,要用时从IOC容器中取mybatis对象。 在spring中应该管理的对象是sqlsessionfactory对象,工厂只允许被创建一次,所以需要创建一个工具类,把创建工厂的代码放在里面&…...

【专项训练】布隆过滤器和LRU缓存
布隆过滤器:与哈希表类似 哈希表是一个没有误差的数据结构! 有哈希函数得到index,会把要存的整个元素放在哈希表里面 有多少元素,每个元素有多大,所有的这些元素需要占的内存空间,在哈希表中都要找相应的内存大小给存起来 事实上,我们并不需要存所有的元素本身,而是只…...

从一道面试题看 TCP 的吞吐极限
分享一个 TCP 面试题:单条 TCP 流如何打满香港到旧金山的 320Gbps 专线?(补充,写成 400Gbps 更具迷惑性,但预测大多数人都会跑偏,320Gbps 也就白给了) 这个题目是上周帮一个朋友想的,建议他别问三次握手&a…...

rsync 的用法
rsync 介绍下 用法 rsync是一个常用的数据同步工具,它能够在本地和远程系统之间同步文件和目录。以下是rsync的基本用法: 同步本地文件夹: bash Copy code rsync -av /path/to/source /path/to/destination其中,-a表示归档模式&…...

【LeetCode每日一题:[面试题 17.05] 字母与数字-前缀和+Hash表】
题目描述 给定一个放有字母和数字的数组,找到最长的子数组,且包含的字母和数字的个数相同。 返回该子数组,若存在多个最长子数组,返回左端点下标值最小的子数组。若不存在这样的数组,返回一个空数组。 示例 1: 输入…...

华为OD机试题 - 简易压缩算法(JavaScript)| 机考必刷
更多题库,搜索引擎搜 梦想橡皮擦华为OD 👑👑👑 更多华为OD题库,搜 梦想橡皮擦 华为OD 👑👑👑 更多华为机考题库,搜 梦想橡皮擦华为OD 👑👑👑 华为OD机试题 最近更新的博客使用说明本篇题解:简易压缩算法题目输入输出示例一输入输出说明示例二输入输出说明…...

Kubenates中的日志收集方案ELK(下)
1、rpm安装Logstash wget https://artifacts.elastic.co/downloads/logstash/logstash-6.8.7.rpm yum install -y logstash-6.8.7.rpm2、创建syslog配置 input {beats{port> 5044 } }output {elasticsearch {hosts > ["http://localhost:9200"]index …...