2.1 编程语言和开源框架
软件开发的首要问题就是使用何种编程语言及软件的架构,任何软件项目在项目之初都需要进行编程语言选型、架构选型等,这些非常重要,并且直接决定了最终产品的开发难度、维护的方便程度,以及扩展能力等。所以本节中我们会花一些篇幅来介绍这些内容。
2.1.1 编程语言的选择
选择什么编程语言最好?这个问题好比在问,世界上最好的编程语言是什么?其实没有答案,关键是是否符合项目的需求。作为自动化测试的编程语言也一样。作者在以往的各种项目中,使用过各种平台和编程语言来进行自动化测试的开发,主要是根据产品的类型和企业的实际业务开展选型,甚至是按照“前辈”的个人习惯来决定使用什么编程语言。这里作者挑选几种比较经典的编程语言来介绍。
1.TCL
早期的很多通信设备制造厂商,包括一些非常有名的企业,在自动化测试开发中都使用TCL,因为TCL本身是一个跨平台的编程语言,并且有很强的字符串处理功能和一些方便的特性,深受通信业测试工程师的喜爱。比如,对命令行串行口进行操作只需要使用spawn和expect,就可以方便地下发命令,以及分析命令返回的结果,并且一些大的通信仪表厂提供了TCL的接口,以方便自动化测试用例的开发。不过同样是脚本语言,随着Python的逐渐流行,很多企业已经将TCL淘汰,转而使用更加强大的Python。
2.Java和.NET
面向对象编程语言也可以被用来开发测试平台,比较流行的是Java和.NET。用面向对象的编程语言来开发测试平台的好处就是,可以利用面向对象的特性来进行封装、多态描述和继承,这样可以极大地提高测试代码的复用能力和扩展能力。
Java和.NET还有很多原生的GUI(用户图形界面)的库可以选择,可以方便地开发图形化的工具,降低测试工程师的学习成本,同时增加测试执行的效率。
Java和.NET的一些社区内容非常丰富,可以找到很多开源的库来完善测试平台,而不需要自己从0开始开发。比如,一些报表插件可以用来生成测试报告,让测试结果变得非常酷炫。当然也有一些标准协议的实现,比如OpenSSH。
但是,.NET存在一个问题——平台限制,虽然说.NET已经开源,但其主要阵营还在Windows平台,并且MSDN的订阅号并不便宜。
当然,互联网的兴起使Java得到了空前的发展,在互联网领域,Java逐渐成为主流的开发语言。特别是云应用兴起后,在一些云原生、微服务的开发框架中,Java开发的基础设施(比如Spring Boot)占据了半壁江山,所以统一自动化测试平台的编程开发语言也是一种不错的选择,这样可以充分复用开发阶段的代码,简化一些中间件的开发。
3.强大的Python
目前来看,自动化测试的明星编程语言应该就是Python了。要说Python的优点那就太多了,面向对象、跨平台、优雅的语法、成千上万的库可供挑选和使用,等等。
Python从各个方面都展现出了容易上手及其易学性,不管是曾经习惯了面向过程编程的程序员,还是C++、C#、Java等面向对象编程的程序员,甚至是接触编程不久的菜鸟,都能很快掌握这门编程语言。
的确,这些优点足以让人们选择它。一个编程语言用的人多了,自然而然它的社区就会比较活跃,可用的资源就会比较丰富,功能也会越来越强大。相应地,开源工具就会越来越多。2019年,TIOBE公布的编程语言流行度调查榜单中,Python排名第三,并且有继续向上的趋势。排名第一、第二的分别是Java和C。C“霸榜”的原因是,随着物联网的发展,嵌入式开发的主力军为C。而互联网的火爆,直接让Java占领了冠军的宝座。
在自动化测试开发领域,随着互联网的兴起,Java和Python逐渐成为两大主力编程语言。针对传统的Web测试、互联网性能测试等领域,Java和Python都拥有非常丰富的开源工具和商业框架。当然,在传统的软件测试领域,Python也逐渐开始流行。
2.1.2 从零开发还是使用现有框架
目前市面上有很多现有的测试框架,比如IBM的Rational Functional Test,主要应用于Java原生的GUI的测试、Web测试等。Robot Framework,是一个基于关键字驱动的测试框架,提供了很多测试接口的扩展库,比如Web测试的Selenium,移动测试的Android库等。另外,Python自带的UnitTest也可以称作一个简单的测试框架。
那么既然有这么多测试框架,我们怎么选择,是使用这些现有的框架,还是从零开始自己开发呢?
首先,要看这些测试框架是否能够满足团队日常的测试需求。比如我们开发基于Java的管理软件,使用的是Swing或AWT图形界面,那么Rational Functional Test是一个不错的选择,可以基于Rational Functional Test进行自己产品的扩展。但是如果开发手机软件,那么这个框架显然就不合适了,我们可能会选择Robot Framework,外加Android库来进行测试用例的开发。
其次,要看这个框架是否有定制属性或扩展性。每个测试团队的功能需求是不同的,比如对测试团队输出报告的需求,A团队可能满足于开源框架的结果输出,而B团队可能有更复杂的需求,对此,他们就可能基于框架的模块自己进行修改。如果修改以后依旧不能满足需求,就只能重新设计了。
再次,如果框架本身出现了问题,团队是否能够找到绕过问题的方案。如果框架的底层代码不是自己实现的,定位问题可能会花费大量时间,即便我们可以在社区把问题提交给开发者,但是并不一定能立刻获得回应,所以这也是一个风险。
最后,是不是能够和自己团队的其他工具兼容,比如CI/CD的工具Jenkins等。
现有的框架可以作为开发的基础,开源的框架也能让我们不至于从地基开始盖高楼。但是,我们还是要基于以上分析来判断现有的这些框架能否满足你的需求。
2.1.3 跨越平台和编程语言的限制
虽然说大多数团队会统一操作系统的平台,但是事实是,在目前的工作环境中,不同操作系统还是会同时存在的,比如有些企业会部署MAC系统,但是实验室环境中的操作系统却是Ubuntu。有些企业的办公计算机系统是Windows,但是产品却是基于UNIX的,这种情况很多。
Java、Python这类编程语言,虽然本身带有虚拟机或解释器,可以工作在不同的操作系统上,但是在做跨平台的移植的时候会非常麻烦。试想一个经验不丰富的工程师在拼接路径的时候,没有使用path.join,而是自己写的字符串拼接,那么在Windows下开发的代码移到Linux下执行时,就会产生一些不可预料的结果。甚至一个换行符(不同的系统,有的是\r\n,而有的是\n),都可能会带来巨大的影响。
当然,即便我们能够注意到跨平台的这些差异,但在实际开发过程中,不可避免地还是会碰到一些诸如某个平台专有的特性等情况。举个例子,如果你的团队一直在Linux上开发测试用例,忽然产品里面加入了Windows PowerShell这样一个功能,你会不会特别抓狂?
跨平台的意义还在于测试平台的部署,很多测试团队开发的自动化工具其实并不一定是为自己服务的,也可能是为公司的其他人员服务的。比如,应用工程师在客户的现场希望使用你的自动化工具来配置脚本,他用的是装有Windows的笔记本电脑,而自动化平台开发在Linux之上,这就给该应用工程师提出了一个难题,除非安装虚拟机再安装Linux,否则他将不能运行自动化程序,这无疑是很糟糕的。
不过我们依旧可以通过一些方法来解决,比如通过容器实现发布和部署,不仅能解决跨平台的问题,还能广泛地应用于CI/CD中,这些我们在后面会讲到。
那么什么是跨越编程语言的限制呢?这有很多种情况,下面列举两种:
(1)在测试嵌入式设备时,嵌入式设备提供的SDK API是使用C开发的,但是测试用例是使用Python开发的,那么我们怎样测试这个设备呢?对于这种情况,我们可能会根据提供的SDK API使用C来写一个测试程序,然后使用Python把这个程序启动起来。
(2)某个团队使用Java开发了一个非常好用的工具,但是编程语言使用了Python,那么我们怎样使用这个工具呢?我们可能希望这个团队的程序是一个标准的命令行界面,这样就可以通过Python执行一个系统的terminal进程,从而来执行这个Java程序。
从上面两种情况可以知道,我们需要一种中间介质,在不同的编程语言之间进行通信。这其实很好理解,但在实际的操作过程中,这种通信协议会被定义得很含糊。比如在上面第(1)种情况下,这个测试脚本可能就是测试工程师在随便命名后,就在Python里面通过串行口直接调用了,而其他人并不知道这个测试用例名字的含义。
所以我们在碰到这种情况时,就需要定义跨编程语言模块之间的通信接口。比如在上面第(1)种情况下,我们可以用C写一个适配层,让Python可以通过命令行来调用嵌入式设备上的API,而在上面第(2)种情况下,我们可以在Java工具上封装一个SOAP或RPC,甚至是RESTful API的通信模块,再让Python去调用。
对一个测试平台来讲,其实并没有严格地规定一定要用某种编程语言或系统来实现。特别是目前在软件规模越来越庞大、功能越来越多的情况下,产品本身也会有跨平台集成的情况,所以我们要做好跨平台的准备。