读程序员的制胜技笔记05_测试(上)

这篇具有很好参考价值的文章主要介绍了读程序员的制胜技笔记05_测试(上)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

读程序员的制胜技笔记05_测试(上)文章来源地址https://www.toymoban.com/news/detail-744926.html

1. 对测试普遍看法

1.1. 很乏味,没有人喜欢这样做,而且回报寥寥

1.2. 对测试人员有一种主观的看法,认为他们的工作太容易了

1.3. 测试看成项目的外部活动,希望尽量减少

1.4. 对于测试人员来说,他需要考虑的就是产品的质量

2. 测试是软件开发工作中不可或缺的一部分

2.1. 可为开发者的开发保驾护航

2.2. 能提供其他对你代码的操作所不能提供的保障

2.3. 能为你节省时间

3. 测试的类型

3.1. 测试虽然没法完全保证软件不出错,但是至少能让它在相当大的程度上达到稳定

3.2. 手动测试

3.2.1. 由人工手动完成的,但这通常由开发者完成,他们通过运行代码并检查其行为来测试代码

3.3. 代码审查(code review)

3.3.1. 主要目的是在代码被推送到存储库之前检查代码,并发现其中潜在的bug

3.3.2. 最重要的意义是这是你不动手改代码就能审视它的最后机会

3.3.3. 主要针对代码中可能给其他开发人员带来的bug和技术债

3.3.4. 其实是一种异步结对编程

3.3.5. 一段代码通过评审后,就变成了每个人的代码,因为这段代码大家都看过并通过了

3.3.6. 一种低成本、高效率的方法,可以让所有人达成共识,集中全体注意力去识别那些隐藏的问题

3.4. 代码分析工具(code analysis tool)

3.5. 自动化测试

3.5.1. 你是程序员,你有写代码的天赋,这意味着你可以让计算机为你做事情,其中也包括测试

3.5.2. 程序员通常只专注于为他们正在开发的软件创建工具,而不是开发过程本身,但过程同样重要

3.5.3. 最小的是单元测试(unit testing)

3.5.3.1. 也是最容易编写的

3.5.3.2. 只测试单个代码单元:公共函数(public function)

3.5.3.3. 需要是公开的,因为测试应该检查外部可见的接口,而不是类的内部细节

3.5.3.4. 问题是即便它让你能够知晓单个单元是否正常工作,但是并不能保证所有单元能够正常协同工作

3.5.4. 集成测试(integration testing)

3.5.4.1. 测试它们是否同样能很好地协同工作

3.5.4.2. 如果自动化UI测试是指运行生产代码来构建正确的用户界面,那么这种测试也属于集成测试

3.6. 生产环境

3.6.1. 实际用户访问的活动环境,其中任何更改都会影响实际数据

3.6.2. 生产环境的测试,被认为是一种大忌

3.6.2.1. 现行代码(live code)

3.6.2.2. 当你发现故障时,一顿修复,问题消失了,可你的客户或用户也消失了

3.6.2.3. 生产环境中的测试也有可取的时候。如果你引入的场景并不经常使用,也不是关键的代码路径的一部分,那你可能会在生产环境中进行测试

3.6.2.4. 如果你觉得放弃这个场景也无所谓,你的客户不会因为这个而放弃整个项目,那你甚至可以不进行代码测试

3.7. 开发环境

3.7.1. 作为运行时环境的名称,意味着代码在本地运行,并且不影响任何有损于生产的数据

3.8. 临时环境(staging)

3.8.1. 一个生产环境的近似环境

3.8.2. 它不会影响站点用户可见的实际数据

4. 选择正确的测试方法

4.1. 找到一个甜蜜点(sweet spot),让你的成本最低、风险最小

4.2. 每一个风险都意味着额外付出纠错成本

4.3. 你可以通过手动测试实现类似于自动化测试的快速迭代周期,只是它需要更多的时间

4.4. 编写测试能够使你思考你所写的代码,你甚至可以认为这是总结性的练习

4.5. 自动化测试使你保持状态,并花费你最少的时间

4.5.1. 编写和运行测试代码是不相干的活动,可能会使你离开这个状态

5. 要点

5.1. 采用测试框架

5.1.1. 使用测试框架的目的是让编写测试代码尽可能容易,但它并不是必需的

5.1.2. 它们是NASA的飞行前检查灯,是“系统状态名义”公告,是你的小纳米机器人,它们为你工作

5.1.3. 在测试框架出现之前,另写程序来测试功能代码就是测试程序的唯一方法

5.1.4. 不依靠测试框架,想要有选择性地运行某些测试,这不太可能

5.1.5. 利用测试框架可以得到一个代码覆盖率(code-coverage)报告,帮助你发现代码上缺少的内容

5.2. 避免用扩展方法“污染”代码补全

5.2.1. 开发者都非常喜欢扩展方法,并倾向于把所有东西都变成扩展方法,而不是静态方法

5.2.2. 每次你为一个众所周知的类(比如string或者int)写一个扩展方法的时候,你就会把它加入代码自动补全,也就是你在Visual Studio中在标识符后输入一个点时看到的下拉列表

5.2.3. 不要在常用的.NET类中引入你期望实现功能的方法,只有对那些将被普遍使用的通用方法才推荐你这样做

5.2.4. 你完全可以使用一个静态类和类似CDN.MakeFilename的语法

5.2.5. 当你本可以使方法成为类的一部分的时候,不要再去创建扩展方法

5.2.6. 例如

5.2.6.1. 你手头上可能有一个Web项目,这个项目使用一个不依赖网络组件库的类

5.2.6.2. 最好的方法就是只为Web项目中的扩展方法引入一个新的依赖,而不是让库依赖你的Web组件

5.3. 不要使用TDD或其他缩写

5.3.1. 测试驱动开发(testing-driven development,TDD)

5.3.1.1. TDD的思想是,在编写实际代码之前写测试可以指导你编写更好的代码

5.3.1.2. TDD的问题不在于心态,而在于实践,在于仪式化的方法

5.3.2. 行为驱动开发(behavior-driven development,BDD)

5.3.2.1. BDD也是一种测试优先的方法,和TDD在测试的命名和布局上有所不同

5.3.3. 不可否认,我们喜欢能拿来就用的方法套路,因为那样的话,我们所需要做的就是遵循它们,而不用想太多,但这会花费我们很多时间,让我们讨厌测试

5.3.4. 先写测试会限制你改变代码的设计

5.3.4.1. 降低了你在进行原型代码(prototyping code)设计时的灵活性

5.3.5. 你的思维空间被分配到了写测试的任务、测试框架的行为要素,以及测试的组织,而不是生产代码本身

5.3.6. 测试的目的应该是帮助你把一段代码写得尽可能简单

5.3.6.1. 如果不是这样,你就做错了

5.4. 为你自己的目的写测试

5.4.1. 最后写测试则可以使代码更加灵活,因为即便后续有重大更改你也可以很从容地进行,而不用提心吊胆,这可算让你解脱了

5.4.2. 它起到了保险的作用,避免了沉没成本谬论

5.4.3. 在快速迭代阶段(如原型代码设计阶段)它不会挡你的路

5.4.4. 测试如果写得足够清晰易懂,你就可以把它当成一种规范或者文档

5.4.4.1. 通过它的写作逻辑和命名格式来描述一个函数的输入和预期输出

5.4.5. 测试可以反过来倒逼软件质量和开发者本身技术水平的提高

5.4.5.1. 编写测试成为更有效率的开发者

到了这里,关于读程序员的制胜技笔记05_测试(上)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 读程序员的制胜技笔记14_安全审查(下)

    1.2.2.1. 看不出来是什么?那我拒绝为你服务 1.4.1.1. 工作量证明相当消耗客户端的运算资源,对那些性能较低的设备不友好,并且它还会影响设备电池的使用寿命 1.4.1.2. 有可能会严重降低用户体验,其后果甚至比验证码的还要恶劣 3.5.2.1. 存储需求更少,性能更强,数据管理

    2024年02月05日
    浏览(45)
  • 读程序员的制胜技笔记10_可口的扩展

    2.8.3.1. 纯函数有一个好处,它们是100%线程安全的 2.9.1.1. 这套数据结构并不都是无锁的 2.9.1.2. 虽然它们依然使用锁,但它们是被优化过的,锁的持续时间会很短,保证了其速度,而且它们可能比真正的无锁替代方案更简单 2.9.2.1. 其中原始数据从未改变,但每个修改操作都

    2024年02月05日
    浏览(67)
  • 读程序员的制胜技笔记09_死磕优化(下)

    7.5.3.1. 在256KB之后,提升突然变得杯水车薪

    2024年02月05日
    浏览(73)
  • 读程序员的制胜技笔记08_死磕优化(上)

    4.3.1.1. 只能给你一堆用于比较的数字 4.3.1.2. 不能告诉你代码的运行速度是快还是慢 4.3.1.3. 可以告诉你它们比其他一些代码运行得慢还是快 4.3.5.1. 可以消除因测量误差或者调用开销产生的波动 4.3.5.2. 适用于微观基准测试 4.3.5.2.1. 适用于微观基准测试 4.3.5.3. 基准测试并没

    2024年02月05日
    浏览(80)
  • 读程序员的制胜技笔记02_算法与数据结构

    3.1.1.1. 根据你的需要,可以有更智能的算法 3.1.3.1. 算法本身并不意味着它很聪明 3.2.1.1. public static bool Contains(int[] array, int lookFor) { for (int n = 0; n < array.Length; n++) {        if (array[n] == lookFor) {            return true;        }    }    return false; } 3.3.1.1. public sta

    2024年02月06日
    浏览(62)
  • 读程序员的制胜技笔记11_与Bug共存(上)

    2.7.3.1. 在构造时验证其有效性,这样一来就不可能包含无效值 2.8.2.1. 其主张一个花括号与声明在同一行 2.9.1.1. 看看这些现成的类型 2.9.3.1. 它代表持续时间 2.9.3.2. 你没有理由用TimeSpan以外的任何东西来表示持续时间,即使你所调用的函数不接受TimeSpan作为参数 2.9.4.1. 它也

    2024年02月05日
    浏览(55)
  • 读程序员的制胜技笔记12_与Bug共存(下)

    2.2.1.1. 故障代码(failing code)放在一个try语句块里,然后加上一个空的catch语句块,就大功告成了 2.2.1.2. 开发者为整个应用程序添加了一个通用的异常处理程序,但实际上这个程序的工作原理就是忽略所有的异常,也就防止所有的崩溃 2.2.1.3. 如果像那样添加一个空的处理程序

    2024年02月05日
    浏览(58)
  • 读程序员的制胜技笔记03_有用的反模式(上)

    4.5.4.1. 你在物理数据库结构上增加了一个依赖项 4.5.4.2. 如果你需要改变信息表的布局或所使用的数据库技术,你就必须检查所有的代码,确保所有的东西都能与新的表布局或新的数据库技术一起工作 4.5.6.1. 这是保持组件或整个层尽可能简单的关键 4.8.3.1. 每个成员只对自己

    2024年02月06日
    浏览(46)
  • 读程序员的制胜技笔记04_有用的反模式(下)

    1.3.1.1. 自己做自己的甲方 3.2.2.1. 紧耦合(tight coupling) 3.2.2.2. 依赖性是万恶之源 3.3.7.1. 因为你可能需要用接口而不是具体的引用来定义依赖关系,但这也会使代码摆脱依赖关系 5.2.3.1. 没有其他错误发生时执行的代码部分 5.3.3.1. 退出点(exit point)是指函数中导致其返回给调用

    2024年02月06日
    浏览(85)
  • 读程序员的README笔记05_日志、监控与配置

    6.1.1.1. 测量的是某个事件发生的次数 6.1.1.2. 通过使用计数器获得缓存命中数和请求总数,你就可以计算出缓存命中率 6.1.2.1. 一个基于时间点的测量值 6.1.2.2. 既可以上升又可以下降 6.1.3.1. 根据事件的大小幅度分成不同的范围 6.1.3.2. 每一个范围都会有一个计数器,每当某

    2024年02月05日
    浏览(54)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包