为什么单元测试难以落实

因为混淆了单元测试和集成测试,导致单元测试代码中有太多mock!!!
如,需要服务启动才能执行的代码,就不是单元测试了。

  • 单元测试,是针对一个单元,即单一的功能
  • 单元测试,是针对一段逻辑,有If..else逻辑的,平铺直叙的代码不需要单元测试。

如果单元没有被拆分,要拆分出来,再做单元测试,这也是非常好的代码重构。

  1. //改造之前的。不容易进行单元测试,因为有request ,需要启动 http服务,单元测试就需要Mock
  2. public OrderDTO getUserOrder(HttpRequest request) {
  3. String userId = request.getParameter("userId" );
  4. string orderId = request.getParameter("orderId");
  5. UserDTO user = userManager.getUser(userId) ;
  6. OrderDTO order = orderManager.getOrder(orderId);
  7. if (order != null && order.getUserId != null && order.getUserId.equals(userId)){
  8. order.setUser(user) ;
  9. return order;
  10. }
  11. return null;
  12. }
  13. // -------------------- 我是分割线 --------------------
  14. // 平铺直叙的代码不需要单元测试
  15. public OrderDTO getUserOrder(HttpRequest request) {
  16. String userId = request.getParameter( "userId");
  17. String orderId = request.getParameter( "orderId");
  18. UserDTO user = userManager.getUser(userId) ;
  19. OrderDTO order = orderManager.getOrder(orderId);
  20. return checkUser(order, user, userId);
  21. }
  22. //逻辑单元,单独抽离出来,测试输入输出即可,不用Mock
  23. public orderDTO chetkUser(OrderDTO orderUserDTO user,String userId) {
  24. if (order != null && order.getUserId != null && order.getUserId.equals(userId)) {
  25. order.setUser(user) ;
  26. return order;
  27. }
  28. return null;
  29. }

另外,测试覆盖率,应该看抽离出来的单元模块,而非所有代码的。因为有些代码根本就不需要、或者不适合单元测试。

另一个原因

除了以上代码和技术方面的原因,阻碍单元测试开展的还有另外的原因∶研发流程不规范。

  • 研发团队和测试团队分离
  • 如果项目延期,测试团队就抱怨提测延期了,测试时间不够
  • 研发团队也想多一事不如少一事,反正有人做测试,也不用我们写单元测试了

上述情况,有工作经验的人相信很熟悉。这种情况,没有太好的解决办法,只能规范研发流程,规范各个流程的产出。这也是架构师的职责之一。

所以,很多现代公司也在做组织架构的转型,特别是现代互联网公司。

  • 以不信任软件工程师为基础。传统软件公司、大公司多采用。特点是︰文档规范详细,具有较大规模的测试团队,研发流程正规且冗长。职责分工明确,程序员就照着文档写代码即可,写完了就交付测试。
  • 以信任软件工程师为基础。现代互联网中下公司多采用,推荐程序员去理解业务,去承担测试。这样文档简单,执行效率高。但是要求团队必须敏捷管理,高效沟通,以及要求程序员要了解业务。