第Ⅰ部分 基础 3
第1章 软件质量 3
1.1 外部质量 4
1.2 内部质量 4
1.3 技术债务 5
1.4 结构性质量保证 6
1.5 整洁代码 7
1.5.1 显式、最小的依赖 7
1.5.2 责任明确 8
1.5.3 不可复制 8
1.5.4 尽可能少的执行分支、尽可能简短的方法 8
1.6 软件度量 8
1.6.1 圈复杂度与npath复杂度 9
1.6.2 CRAP 9
1.6.3 non-mockable total recursive cyclomatic complexity 9
1.6.4 全局可变状态 10
1.6.5 聚合与耦合 10
1.7 工具 10
1.7.1 PHPUnit 10
1.7.2 phploc 10
1.7.3 PHP Copy-Paste-Detector 10
1.7.4 PHP Dead Code Detector 11
1.7.5 PHP_Depend 11
1.7.6 PHP Mess Detector 11
1.7.7 PHP_CodeSniffer 11
1.7.8 bytekit-cli 11
1.7.9 PHP_CodeBrowser 11
1.7.10 CruiseControl与PHPUnderControl 11
1.7.11 Hudson 12
1.7.12 Arbit 12
1.8 本章小结 12
第2章 软件测试 13
2.1 黑盒测试与白盒测试 13
2.2 需要多少次测试 13
2.3 系统测试 14
2.3.1 浏览器测试 15
2.3.2 自动测试 16
2.3.3 孤立测试 16
2.3.4 验收测试 17
2.3.5 系统测试的局限 17
2.4 单元测试 18
2.4.1 返回值 19
2.4.2 依赖性 21
2.4.3 副作用 21
2.5 案例探究 21
2.5.1 分析待测试代码 24
2.5.2 创建测试环境 25
2.5.3 避免全局依赖性 27
2.5.4 独立于数据源的测试 28
2.5.5 异步事件测试 33
2.5.6 数据库变化的存储 36
2.5.7 意外的结果 37
2.5.8 封装输入数据 39
2.5.9 问题的进一步研究 40
2.6 本章小结 41
第Ⅱ部分 最佳实践第3章 TYPO3:呆板项目之敏捷未来 45
3.1 简介 45
3.1.1 TYPO3的历史:13个春秋 45
3.1.2 敢于重新开始 46
3.1.3 我们的测试经验 47
3.2 方法和技术 47
3.2.1 苦甜参半的“大块头” 48
3.2.2 测试驱动开发 48
3.2.3 文档式测试 49
3.2.4 持续集成 50
3.2.5 整洁代码 51
3.2.6 代码重构 52
3.2.7 编程向导 52
3.2.8 领域驱动设计 53
3.3 开发过程中的行动方向 54
3.3.1 开发新代码 54
3.3.2 扩展和调试代码 54
3.3.3 优化代码 55
3.3.4 寻找并修复漏洞 56
3.3.5 处理旧代码 56
3.4 测试处方 56
3.4.1 无意的功能性单元测试 57
3.4.2 文件系统入口 57
3.4.3 接口处的构造函数 58
3.4.4 测试抽象类 58
3.4.5 测试受保护方法 59
3.4.6 回调函数的使用 61
3.5 迈向未来 62
第4章 单元测试的糟糕实践 63
4.1 为什么测试质量很重要 63
4.2 糟糕实践和测试味道 64
4.2.1 测试代码重复 64
4.2.2 断言复杂和测试试图 65
4.2.3 脆弱测试 67
4.2.4 模糊测试 69
4.2.5 谎言测试 73
4.2.6 慢测试 74
4.2.7 测试中的条件逻辑 75
4.2.8 自行验证测试 76
4.2.9 Web冲浪测试 77
4.2.10 模拟过度杀伤 78
4.2.11 跳过蔓延 79
4.3 本章小结 79
第5章 Digg公司的质量保证 81
5.1 面临的问题 81
5.1.1 遗留基本代码 82
5.1.2 如何解决这些问题 83
5.1.3 选择测试框架 84
5.1.4 引进专家 84
5.1.5 会议室内的一周 84
5.2 训练团队 84
5.3 编写可测试代码 87
5.3.1 规避静态方法 87
5.3.2 依赖注入 89
5.4 模拟对象 89
5.4.1 综述 89
5.4.2 数据库 89
5.4.3 松散耦合依赖 90
5.4.4 测试类内部构件的试验对象观察者 91
5.4.5 分布式缓存 92
5.4.6 模拟服务型架构 92
5.5 Digg的质量保证过程 96
5.5.1 测试 96
5.5.2 益处 97
5.6 本章小结 98
第Ⅲ部分 服务器与服务第6章 服务型API测试 101
6.1 问题 102
6.2 解决方案 103
6.2.1 API证书 103
6.2.2 API限制 106
6.2.3 服务协议的脱机测试 107
6.2.4 具体服务的脱机测试 110
6.3 本章小结 115
第7章 测试WebDAV服务器 117
7.1 关于eZ WebDAV组件 117
7.1.1 WebDAV 117
7.1.2 体系结构 119
7.2 开发过程中的挑战 120
7.2.1 需求分析 120
7.2.2 RFC之后的TDD 121
7.2.3 测试一个服务器 121
7.3 使用PHPUnit进行自动验收测试 123
7.3.1 捕获追踪测试 124
7.3.2 测试方法 125
7.3.3 集成到PHPUnit 126
7.3.4 定制测试案例 126
7.3.5 验收测试套件 129
7.3.6 验收测试示例 130
7.4 本章小结 132
第Ⅳ部分 体系结构第8章 Symfony测试与Symfony项目 135
8.1 测试框架 135
8.1.1 Symfony发布管理过程 136
8.1.2 测试与真实代码 137
8.1.3 运行测试套件 137
8.1.4 主要教训 137
8.2 测试Web应用程序 141
8.2.1 减少进入测试的障碍 142
8.2.2 单元测试 142
8.2.3 功能测试 146
8.3 本章小结 150
第9章 测试ezcGraph组件 151
9.1 开发理念 152
9.2 图形组件 152
9.2.1 体系结构 153
9.2.2 测试需求 154
9.3 驱动程序的模拟化 154
9.3.1 模拟驱动程序 154
9.3.2 多重断言 156
9.3.3 结构 157
9.3.4 预处理 157
9.3.5 小结 158
9.4 测试二进制数据 158
9.4.1 驱动程序 158
9.4.2 预处理 159
9.4.3 SVG 159
9.4.4 创建位图 160
9.4.5 位图对比 161
9.4.6 Flash 162
9.5 本章小结 164
第10章 测试数据库交互 165
10.1 概述 165
10.2 不编写数据库测试的原因 166
10.3 编写数据库测试的原因 166
10.4 测试的内容 167
10.5 编写测试:模拟数据库连接 168
10.6 编写测试:PHPUnit数据库扩展 168
10.6.1 数据库测试案例类 169
10.6.2 建立数据库测试连接 170
10.6.3 创建数据集 172
10.6.4 数据操作 185
10.6.5 建立测试 187
10.6.6 使用数据库测试器 193
10.7 应用测试驱动的设计进行数据库测试 195
10.8 使用数据库测试进行回归测试 195
10.8.1 数据的测试问题 196
10.8.2 数据揭示的测试问题 197
10.9 本章小结 197
第Ⅴ部分 整体问题与解决方案第11章 studiVZ的质量保证 201
11.1 简介 201
11.2 验收测试 202
11.3 Selenium 203
11.4 studiVZ的技术设置 205
11.4.1 开发环境 205
11.4.2 测试环境 206
11.5 最佳做法 206
11.5.1 早期的错误 207
11.5.2 策略变更 208
11.6 我们需要一个DSL 215
11.6.1 内部DSL 216
11.6.2 Testing_SeleniumDSL 1.0版本 216
11.6.3 Testing_SeleniumDSL 2.0版本——一个草案 218
11.6.4 Testing_SeleniumDSL 2.0版本的现状和展望 218
11.7 本章小结 219
第12章 持续集成 221
12.1 简介 221
12.1.1 持续集成 222
12.1.2 静态分析 223
12.2 安装 232
12.3 配置 233
12.3.1 静态测试 236
12.3.2 动态测试 240
12.3.3 报告 241
12.3.4 成果 242
12.4 操作 244
12.5 高级话题 244
12.5.1 持续部署 244
12.5.2 使用反向代理 245
12.5.3 持续集成和敏捷范式 246
12.6 本章小结 247
第13章 swoodoo:真正的敏捷史 249
13.1 简介 249
13.2 强者生存 249
13.3 现在我们正在做的工作 255
13.4 演化的艺术 258
13.4.1 经验不足 259
13.4.2 Java开发人员使用PHP编码的现象 260
13.4.3 只有自己理解其代码的开发人员 262
13.5 本章小结 263
第Ⅵ部分 非功能性方面第14章 易用性 267
14.1 开销和工作的平衡 268
14.2 设计 269
14.2.1 可访问性 269
14.2.2 可读性 270
14.2.3 表单元素标签 270
14.2.4 键盘导航 270
14.2.5 有效的对比度 271
14.2.6 返回首页的连接标志 271
14.2.7 图像的替代文本 272
14.2.8 背景图像的背景颜色 272
14.2.9 可用的打印版本 272
14.2.10 可视的链接 272
14.2.11 良好的书签 272
14.2.12 不使用帧 272
14.2.13 可缩放的字体 273
14.3 技术 273
14.3.1 性能 273
14.3.2 JavaScript 274
14.4 用户指南 275
14.4.1 “折叠”的神话 275
14.4.2 互动的反馈 276
14.4.3 导航 276
14.4.4 弹出窗口和其他的烦恼 277
14.4.5 习惯和期望 277
14.4.6 容错和反馈 277
14.5 测试易用性 277
14.6 本章小结 278
第15章 性能测试 279
15.1 简介 279
15.1.1 工具 280
15.1.2 环境的注意事项 280
15.2 负载测试 281
15.2.1 Apache Bench 282
15.2.2 Pylot 283
15.2.3 其他负载测试工具 285
15.3 剖析 285
15.3.1 Callgrind 286
15.3.2 KCachegrind 289
15.3.3 APD 290
15.3.4 Xdebug 291
15.3.5 XHProf 292
15.3.6 OProfile 293
15.4 系统指标 294
15.4.1 strace 294
15.4.2 Sysstat 295
15.4.3 自定义工具 297
15.5 常见的陷阱 297
15.5.1 开发与生产环境 297
15.5.2 CPU时间 298
15.5.3 微优化 298
15.5.4 将PHP作为粘合剂 298
15.5.5 优化的优先级 299
15.6 本章小结 299
第16章 安全性 301
16.1 安全性概述 301
16.2 设计安全 302
16.2.1 操作 302
16.2.2 物理访问 303
16.2.3 软件开发 303
16.3 安全性的开销 305
16.4 最常见的问题 306
16.4.1 未经验证的重定向和转发 306
16.4.2 传输层保护不足 307
16.4.3 限制URL访问失败 307
16.4.4 不安全的加密存储 308
16.4.5 安全性错误配置 308
16.4.6 跨站点请求伪造 309
16.4.7 不安全的直接对象引用 309
16.4.8 破坏的认证和会话管理 310
16.4.9 跨站点脚本 310
16.4.10 注入 311
16.5 本章小结 312
第17章 结束语 313