一、 Views and Quality Objectives of Software Construction
1. Multi-dimensional software views
构建时的view:
表示代码的 逻辑 组织
表示代码的 物理 组织
表现源码和组件在 特定时刻 的软件形态
表现软件形态 随时间的变化
源码组织在文件中,进而组织在目录中
文件存档在包中,并逻辑上归属于组件和子系统
可重用的模块以库的形式存在,库存储在磁盘文件中
静态链接:库被拷贝进代码形成整体,执行的时候无需提供库文件
运行时的view:
逻辑实体 在内存中如何呈现
物理实体 在物理硬件环境中如何呈现
逻辑 / 物理实体在内存 / 硬件环境中 特定时刻 的形态
逻辑 / 物理实体在内存 / 硬件环境中的形态 随时间的变化
动态链接:库文件不会在构建阶段被加入可执行软件,仅仅做出标记;程序运行时,根据标记装载库至内存;发布软件时,将程序所依赖的所有动态库都复制给用户
分布式程序:需要多个运行程序,分别部署于多个计算机物理环境
代码快照:描述程序运行时内存里变量层面的状态
内存转储(Memory dump):一个包含进程内存拷贝的磁盘文件,包含程序异常退出时的寄存器、调用栈、程序数据等,调试器可以加载转储文件并显示信息
执行跟踪(Execution tracing):软件层面,用日志方式记录程序执行的调用次序
事件日志:系统层面的日志
2. 软件的质量因素
外部质量因素:可被用户感知的因素,如软件速度、易用性;影响用户
内部质量因素:作为软件产品的质量,如代码可读性;影响软件本身和它的开发者
外部质量取决于内部质量。
2.1. 外部质量因素
2.1.1. 正确性
正确性:按照预先定义的规约执行,是最重要的质量指标
2.1.2 健壮性/鲁棒性
健壮性:针对异常情况的处理,关键在于出现异常时不要崩溃
2.1.3. 可扩展性
可扩展性:对软件的规约进行修改,是否足够容易
2.1.4. 可复用性
可复用性:一次开发,多次使用
2.1.5. 兼容性
兼容性:不同的软件系统之间相互可容易的集成
核心是保持设计的同构性,关键在标准化。
2.1.6. 性能
除非有足够的正确性,否则性能毫无意义。对性能的关注要与其他质量属性进行折中,过度的优化会导致软件不再适应变化和复用。
2.1.7. 可移植性
可移植性:软件可方便的在不同的技术环境之间移植,包括硬件和操作系统
2.1.8. 易用性
易用性:对用户而言容易学、安装、操作、监控
2.1.9. 功能性(Functionality)
程序设计中一种不适宜的趋势,即软件开发者增加越来越多的功能,企图跟上竞争,其结果是程序极为复杂、不灵活、占用过多的磁盘空间,忽视整体质量,失去可持续性。
2.1.10. 及时性(Timeliness)
及时性:在用户有对应需求前放出新版本
2.2 内部质量因素
源码方面:行数(LoC)、逻辑复杂度
结构方面:耦合、内聚
除此之外还有代码可读性、易于理解、清晰、大小等。
二、 Testing and Test-First Programming
1. 软件测试
一个好的测试具有这些特征:能发现错误、不冗余、最佳组合、不能太过复杂也不能太过简单。
测试和调试的区别
测试:发现是否存在错误
调试:识别错误根源,消除错误
2. 测试的分类
从范围上看
单元测试:针对软件的最小单元模型开展测试(一般来说是在单个方法/类的级别),隔离各个模块,容易定位错误和调试
集成测试:将多个程序员/团队编写的类/包/组件/子系统联合起来测试
系统测试:对整个系统进行测试,将硬件、软件、配置信息等看作一个整体
验收测试:产品发布之前所进行的软件测试活动,是技术测试的最后一个阶段,目的是确保软件准备就绪,并且可以让最终用户将其用于执行软件的既定功能和任务
回归测试:一旦程序被修改,重新执行之前的所有测试以确认修改没有引入新的错误或导致其他代码产生错误
从静态/动态上看
静态测试:在编写代码的阶段由程序员或是代码编辑器、编译器等工具进行检查(如语法检查、代码评审)
动态测试:通过测试用例实际执行了编写的代码
动态测试可能在程序完全编写完成前就用于测试代码的特定节
从结构上看
白盒测试:对程序内部代码结构的测试
黑盒测试:对程序外部表现出来的行为的测试(例如输入输出)
等价类划分
基于等价类划分的测试:将被测函数的输入域划分为等价类,从等价类中导出测试用例
每个等价类代表着对输入约束加以满足/违反的有效/无效数据的集合。
边界值分析
边界值分析方法是对等价类划分方法的补充。
原理:大量的错误发生在输入域的“边界”而非中央
语句覆盖:每⼀条语句至少执行一次
分支覆盖:判定中每个条件的所有可能结果至少出现一次,并且每个判定本身的所有可能结果也至少出现一次
路径覆盖:每条可能执行到的路径至少执行一次
测试效果:路径覆盖 > 分支覆盖 > 语句覆盖
测试难度:路径覆盖 > 分支覆盖 > 语句覆盖