构建之法-2-个人技术和流程

个人技术和流程

成为一名合格的软件工程师

2.1 单元测试

2.1.1 为什么要写

团队合作里,每个工程师都有自己负责的模块,我们不希望调用别人的模块出现问题,同理别人在使用我们开发的功能也不希望出现问题。那么,要证明自己的模块是正确而稳定的,就必须使用单元测试

2.1.2 怎么写

  • 在最基本的功能参数上验证程序的正确性
    测试系统中最基本的功能点,测试api中的每一个方法及每一个参数。

  • 必须由最熟悉代码人来写
    那么,最好由作者本人来写。最好在模块设计之初就写好单元测试。

  • 单元测试过后,机器状态保持不变
    如果每次运行单元测试,都会改变状态,例如创建了临时文件或者目录或者改动了数据库,就会产生很多麻烦。所以单元测试产生的变动最好还是能恢复原样。这样就可以随时运行许多次单元测试了。

  • 单元测试要快
    软件中经常有几十个基本模块要测试,每个模块又会有要测试的方法,一个类的测试最好能在几秒钟内完成。如果软件有独立的层次,那么分成可以单独测试的层次。例如数据库层次,网络通信层次,客户逻辑层次,用户界面层次。这样就可以在修改了某一层次的代码时,只用测试某一层就行了。

  • 单元测试应该产生可重复一致的结果
    这个很好理解,因为如果测试完之后某个错误不可复现,那测试没啥意义了。所以应该避免使用随机数。

  • 不依赖别的测试,人为构造结果
    例如在请求网络时,可以手动构造数据。

  • 覆盖所有代码路径
    不要嫌弃麻烦,应该坚持覆盖所有的可能。但有时覆盖率100%也不一定全对。例如
    if(a&b&c) {} else {}
    当你固定b和c为true时,只测试a为true或false时,覆盖率也是100%,但是明显没有考虑所有的可能。

  • 集成自动测试框架
    随时随地运行测试,及时发现错误。

  • 和产品代码一起维护
    如果改动了产品没有相应的修改测试,会越来越难维护。

2.1.3 回归测试(Regression Test)

假如上一个版本中所有的单元测试都通过了,在新版本中某个测试未通过,我们就说发生了“倒退”。所以是为了验证新的代码没有破坏模块的现有功能。


2.2 效能分析工具

Performance Tools 有两种方法,抽样(Sampling)代码注入(Instrumentation)。前者基于统计,不太准确但是不会影响原有程序的运行。后者注入代码统计准确但是会影响原有程序的运行。


2.3 个人开发流程

软件工程师的任务清单.png

一个工程师在接到任务时应该细细考虑上述表中列出的每一项。程序员不应该仅仅是敲代码。表中就是PSP2.1模型(Personal Software Process)。


2.4 实践

2.4.1 做一份有实际意义的大作业

我们在课堂上布置的大作业类似于“成绩管理系统”、“图书馆管理系统”都是没有实际意义的。因为实际中的任务都是有不断变化的需求,而上述这两个“系统”都是没有变化的因素在里面,学生在完成这些任务时很容易把所有的功能都冗杂在一个类里面,下面介绍两个非常重要的设计原则。

  • 单一职责原则(Single Responsibility Principle, SRP)
    一个模块应该只有一个导致它变化的原因,一个模块应该完全对某个功能负责。

  • 开放封闭原则(Open-Close Principle, OCP)
    允许扩展(Open for extension):当应用的需求发生改变时,可以对模块进行扩展,从而改变模块的功能。
    不允许修改(Closed for modification):对模块进行扩展时,不必改变模块本身。(这里好抽象,不太懂)

2.4.2 项目:WC

实现一个命令行工具,它能统计文本文件的字符数、单词数和行数。程序处理用户需求的模式为:

wc.exe [parameter][file_name]

扩展功能:

-s 递归处理目录下符合条件的文件。
-a 返回高级选项(代码行/空行/注释行)

罗马不是一天建成的。同样,一个功能完备的程序也不是一蹴而就的。因此,要先完成把大任务划分为可操作的小任务,安排任务的次序等工作。


总结

要成为一名合格的软件工程师,要认真对待这些不起眼的工作,如单元测试、回归测试、效能分析,拿到任务后要按照任务清单来分解任务。永远记住,代码实现部分只是开发软件的一小部分。

我们是在开发一个软件,而不仅仅是在写一段程序。

你可能感兴趣的:(构建之法-2-个人技术和流程)