离开CPUG以后,我的邮箱清静了很多,果断退掉一些现在已经不太关注的邮件组后,只有haskell-cafe和python社区的邮件还比较热闹。不过这几天几位朋友都在问我这个事儿:
https://groups.google.com/forum/#!topic/python-cn/yT3FvzgFLAs/discussion
codebase 中 merge 了别人的代码以后。即便双方都没有改动同一个文件,也可能出现这种情况:
A 只改动了 a.py 的一个方法的传参个数。
B 改动了 b.py, 并且 b.py 中调用了 a.py 中的那个方法改动前的版本。
merge 了两个文件以后, 程序员基本都不会意识到现在出了问题。
原因有两个:
1. python 程序员基本不用什么IDE, 如果使用 pydev 之类, 大致还能依靠 IDE 在merge 以后看到这个错。
2. python 没有编译的概念,没有机会看到编译器对这个语法问题的报错。
好了,现在只有等上线以后,通过某个事件触发这个bug了。
请问各位是杂么防范这种问题的?
unit test ?
如果问我的意见,其实我的意见很简单的,这位楼主自己也很清楚。
是的,测试,测试再测试,计算机不变魔法。
我做过python-C#,python-Java的不同项目对接,为此同时在一个项目里用不同的语言开发过近乎对等的功能,Python比C#/Java节省一个数量级的开发量这个真的不是吹牛。
那么,你用十分之一的工作量完成了功能开发,再用十分之一的时间写对应的test代码可不可以?
就算你在自己的代码里用doctest完成了自测,项目组用unit test和其它测试脚本完成单元测试和框架级的测试,信不信你的开发量还是比java/C#要少?相对来说,你获得了更可靠的保证,这个保证是来自开发人员明确的代码定义,而非IDE基于IDE开发者思路的通用校检,哪一个更严格更可靠?如果你定制的质量检测脚本居然不能达到通用功能的程度,是不是应该检讨一下自己,多学习学习?
具体到这位朋友的问题,我们可以发现这样几处值得讨论的地方:
这暴露了此项目缺少集成测试,无论你使用任何语言和技术,集成测试都非常重要。搭建一个友好、“正直”的集成测试环境,非常重要。这种事情不应该指望某一个人的IDE,哪怕是每一个人的。因为在团队协作中,每一个人的代码都可能不是最终发布的代码。
应该把提交和上线当做一件严肃的事,上线之前一定要集成测试,类似API变更冲突这种错误大多是可以避免的。
另一方面,每个人提交完以后,应该再update一次,然后在本地集成测试一次。这里IDE有支持的话应该积极使用,虽然不能完全避免错误,但是有做比没做好。
同时我们也应该知道,这个功能用IDE能完成,用脚本也一样可以,而且不会更麻烦。我在开发 socrates 项目时就是这样做的。事实上因为在python中写测试更简单,我用起来感觉要比在C#/CPP中爽很多。
所以这个问题不在于用不用IDE,而在于你有没有心去做这样的事。还是那句话,用python/ruby什么的,就算你加上写测试,还是省力的。
当然,我们应该承认,动态类型语言不检查传递的参数,确实会引发一些风险,但是在我接触过的项目中,真正要面对的总是资源管理问题和逻辑错误,不论哪一种语言哪一种应用,类型错误少之又少。一个数量级以上的性能提升,付出这样的代价相当值得。
静态语言现在也倾向于尽可能由编译器发现类型,越来越少的要求用户显式给出约束。包括类型系统最为严苛的haskell,它也鼓励用户编写出编译器可以自动感知类型的代码。如果想兼顾书写的便利和静态类型语言的安全感,Java程序员其实可以试试scala,最近我也在学习这个语言,是个非常有爱的好东西。
无论用哪一种语言,最终写代码的仍然是人。具体到这个贴子中出现的问题,我认为首先要检讨团队管理过程,语言的问题只是个表像。无论动态语言还是静态语言,积极建立测试体系才是正道,无论用Java还是Python,CPP还是ruby。尤其在线系统,要有一个集成测试的环境。传统的静态类型语言可以避免此类小概率错误的一部分发生可能,而运用动态语言或现代的,更为智能的静态语言,则可以将更多的时间省下来,建立完整的质量管理体系,在更高的层面上消灭这种错,在应用项目开发中,后者胜出。