时间总是过得很快,希望借助于纸笔可以将时间拖慢点(我一定是想多了…)。

本周主要开发两个功能:

  • 多虚拟机申请
  • 环境复用功能优化

测试

本周还大规模的写了很多spec测试case,并有意识的进行了TDD尝试,即先写测试Case,再进行功能编写或者重构。Martin Fowler说过,重构的三个建议:

  • 不要在重构的时候增加新的功能
  • 在重构之前有足够的测试case
  • 小步进行,每一步都深思熟虑

我认为最重要也是最难做到的就是第二点。

写spec case的一点经验:

  • 要挑选适合做spec的接口。输入输出确定,内部逻辑较为复杂
  • count_machines的接口内部是用递归实现的,但是输入是一个对象,输出是一个数组,都容易确定
  • 当跑通一个case之后,可以站在spec case(黑盒)的角度,来构造测试用例
  • spec强调的是规格测试,更多的要站在需求点的角度思考测试方案。通过describe, context来区分测试的场景。
  • 可以用send来测试private方法

do less

多虚拟机申请最初是打算是采用部署的流程来帮助用户来进行部署服务,但是团队有人建议直接给用户提供机器的用户名、密码等信息,而不用替用户做那些功能。

细细思索之后,其实这种do less的方式也是有好处的:

  • 简化了申请虚拟机的逻辑,便于用户理解。
  • 如果do more, 用户会问:你从哪里卸载的脚本,你做了哪些工作,发现一个问题是不是你的代码导致的?但是do less, 用户会很明白的知道,你只是给他们提供了用户名、密码,其他都是用户自己用脚本来决定。
  • 简化了代码的逻辑
  • 因为do more借用了原有的业务逻辑,这样原有业务逻辑如果变动了,就需要考虑是否给这个功能带来影响——换句话说,增加了模块间的耦合度。另外,你需要进行判断什么时候是部署,什么时候是申请虚拟机,这里就会有分支的概念。一旦有了分支,一般某一部分的逻辑复杂度就是直接乘2.

抽取

环境复用的难点在于,复用的时候哪些步骤可以省略,哪些步骤又必须执行呢?

如果准备环境的操作是Steps A, 而复用的时候可以进行省略。Steps A可以作为一个整体来看待,对于一个串行的应用来说。这部分逻辑,我考虑将其剥离到Engine来执行,而不是将其放倒App中。这样有两个好处:

  • 模块之间的功能划分更清晰,避免了App过重。Engine本身就负责机器的申请,环境复用的判断,所以将机器的基础环境部署接过来也很合理。由Engine来处理是否需要复用的逻辑。而App可以专注于具体的测试Steps过程。
  • 将这部分工作从App中剥离出来,可以更方便的为以后的并行处理做准备。

问题在于,Steps A并非可以完全剥离出来。Steps A可以分为两部分:1. Steps A1 完全属于环境准备的操作 2. Steps A2跟App本身依赖的应用构建有关的。前者适合由Engine来处理,后者跟App脱离似乎就有些不合适了。从并行的角度看,前者很自然的可以并行处理,后者却不能:

reuse

这样的流程也算是差强人意,唯一的遗憾是复用的判断在两个地方同时存在,这似乎也意味着以后可能有更多的逻辑都需要做两次处理,使得Engine和App的职责变得不那么清晰了。

这部分继续考虑考虑,还有什么更好的方法。