用虚拟机+mercurial来合理分配运行测试时间
在开发过程中,我们常常需要在提交代码之前先在本地运行测试,看一看当前修改的质量如何。可是问题是,一旦测试耗时过长(比如说超过15分钟),那么必然会对开发进程造成影响,因为通常在本地运行测试的时候我们都会暂时停止开发;而且过长的测试时间也势必会影响持续集成的频率,毕竟我们不想花太多的时间在等待上。
在Cruise上,我们运行本地测试的时间大约在15分钟左右,这在很大程度上阻碍了我们的持续集成步伐。解决这个问题,一方面是治本,那就是找出并解决影响测试速度的瓶颈来,我在github上有一个 项目, 专门用来做这个分析,最近一段时间会发布第一个版本;另一方面则是治标,也就是找到一个办法来让测试运行不影响本地的继续开发。
想达到后一个目的其实并不难。最简单的办法就是让测试运行在一台虚拟机上,这样测试和开发就互相不影响了。有了这个想法,我和同事Pavan就在我们的Ubuntu开发机器上装了一个VirtualBox虚拟机环境(另一个备选的方案是KVM,但是考虑到VirtualBox的安装和配置更简易省时,我们还是选定了后者),在其上创建了一个Ubuntu 8.10服务器版的虚拟机,分配了1G内存(我们的开发用机有4G内存!),然后在其上安装好运行测试所需的环境(mercurial, git, ant, nant, ruby, rake…)。
接下来要做的就是把源代码从开发机器上转移到虚拟机了。由于我们用的工具mercurial对点对点协作模式有着天然的支持,因此做到这一点非常容易:我们首先在开发机器上运行hg serve,使得它可以对外提供源代码访问服务;然后再在虚拟机里做hg clone,把开发机器上的修改同步到虚拟机上。整个过程结束后,我们就可以在虚拟机上直接运行ant命令来运行测试了。
如果工作机器上后续又出现了新的代码修改,我们的操作流程稍微有一点变化。由于我们在开发过程中都是使用 hg queue 来管理本地修改的,每次更新queue都会导致开发机器代码仓库中被修改的那条记录的版本发生变化,因此直接用hg pull -u更新到虚拟机的话就会产生版本冲突现象。解决的办法也很简单,就是在虚拟机里运行hg out,把相对于开发机器多出来的版本(其实也就是在开发机器上被更新过的版本)用hg strip命令消掉。然后再运行hg pull -u就不会出现冲突了。
通过把测试工作转移到单独的虚拟机来进行,我们节省了大量的原本用于等待的时间,从而很大地提升了团队的工作效率。