运行时间太久
  功能测试一般都会模拟真正用户的行为,所以相对于单元测试来说,它们都很慢。如果对软件的所有行为编写功能测试,随着时间的推移,你会发现跑一边测试需要一个小时,那还会有谁在每次提交之前运行一遍测试?
  如何有效的做自动化测试
  为了有效地进行自动化测试,你需要考虑很多。
  选择正确的工具
  要知道如何选择工具,首先要了解自动化测试的层次:

  测试框架本身非常关键,一个好的测试框架本身可以帮助你编写出可维护的测试用例,并提高编写效率。你可以使用junit、rspec之类的工具可以达到目的。但Cucumber和Robotframe等工具可以提供更多更好的功能,详情可以参看笔者的另一篇文章:Cucumber和Robotframework对比。如果你在进行基于Rack的应用程序的测试,那Capybara是不二的选择。
  一个好的测试驱动同样可以大幅提升用例开发的效率。在对网络通信的测试中,如果没有Scapy这个库的支持,恐怕编写用例的成本要增加一个数量级。在Web测试的上下文中,不光要考虑测试库是否能够满足你的功能性需求,还要考虑运行速度。基于真实浏览器的测试是很慢的,所以出现了PhontamJS这样的headless driver。
  数据准备同样是编写测试中一个非常重要的步骤。你可以选择自己往数据库里面插数据,并进行清理,但如果有一个工具可以帮助你做类似的事情,岂不是很好?Ruby世界的FactoryGirl,和DatabaseCleaner可以在这方面提供很多帮助,节省你大量的时间。
  能找到合适的工具是一件很幸运的事情。很多时候也可能找不到很好的工具。但这也没关系,像编写产品代码一样,自己花时间写一个相应的库或者工具好。
  修复不稳定因素
  环境不稳定、测试代码本身不稳定等因素都会导致大家越来越不想去运行测试。所以要在第一时间修复这些问题。举两个例子:
  我工作过的一个软件系统会依赖与一个搜索引擎。由于搜索引擎是收费软件,为了节省成本,持续集成所使用的搜索引擎和手工测试使用的搜索引擎是同一个实例。所以有时候手工测试在其中注入数据时会导致自动化测试失败。后来又花钱买了一份liscense部署了一台新的实例,测试稳定性有了很大的提升。
  如果发现了不稳定的测试,要第一时间修复。如果一时半会修复不了怎么办呢?我所在的团队曾经采用过的一种方法是打一个@quarantine的标签给这个测试,然后修改运行脚本,跳过所有打了这个标签的测试。然后再慢慢修复这个测试。这样可以保证整个测试集是健康的,测试结果一定能够给你带来有效的信息。
  方便测试的运行
  如果我告诉你为了运行整个测试集,你需要手动重建数据库,然后feed一些测试数据到数据库中,然后启动应用程序A、B和C,然后再配置一系列的环境变量,然后再运行一串巨长的带着各种参数的命令,你是否还愿意跑这个测试?为何不把这些繁琐的工作写到一个脚本中,让别人简单地运行一个短短的命令可以完成这个工作?这个脚本可以是一个shell脚本,但如果能够集成到项目所使用的构建工具中更好了。在Ruby项目中可以集成到Rake中,在Node项目中可以集成到Gulp中,在Java项目中可以集成到Gradle中。
  好了,现在你可以方便地运行所有的测试了。但是别忘了开发人员大部分的时间是在编写和调试单个用例,所以请保证你选用的测试框架或者IDE能够支持单个用例的运行和调试。
  结合持续集成和PrePush
  自动化功能测试的运行速度是比较慢的。即使你已经采用了类似PhantomJS这样的驱动,所有测试的整体运行时间还是不可避免的会很长。在持续集成服务器上可以采用并行的方式让多台机器来同时运行测试。但在本地如何并行运行呢?答案是挑选其中一部分我们觉得非常重要的测试来运行,而不是全部。具体的做法是在我们认为很重要的用例上打上@prePush之类的标签,然后修改启动测试的脚本来只运行打了这些标签的测试。经验值是运行prePush的时间不要超过5分钟。
  有了这个prePush脚本,可以把它嵌在git push的hook中(假设你使用的是git),以保证每个人在提交代码的时候都能够运行一遍这些测试,从而确保自己的修改没有破坏别人的功能。
  自动化测试不能解决什么问题
  当然了,自动化测试也不是的。举个例子,强哥对自己能够想到的功能进行了完备的测试,但是有些异常场景如果没有考虑到,自然也没法编写相应的测试。所以需求分析和用例设计其实是一个单独的、但也同等重要的课题。
  上文提到了很多次功能测试运行时间太久的问题,这个问题除了使用prePush和并行运行之外还有什么办法可以解决吗?答案是自动化单元测试和测试金字塔!当然本文不对这个话题展开讨论。
  不忘初心
  自动化功能测试本身并不是目的,并不是你跟别人说:“看,我的测试覆盖率超过90%”,你的项目成功了。代码没bug、开发可以快速交付、市场认可才是终目的,而自动化功能测试只是实现这些的目标的一个手段而已。即不是的手段,也不是必不可少的手段。