为什么优秀的程序员喜欢命令行

by admin on 2020年4月22日

程序员的日常工作

The three chief virtues of a programmer are: Laziness, Impatience and
Hubris. – Larry Wall

懒惰这个特点位于程序员的三大美德之首:唯有懒惰才会驱动程序员尽可能的将日常工作自动化起来,解放自己的双手,节省自己的时间。而GUI,不得不说,天然就是为了让自动化变得困难的一种设计。GUI更强调的是与人类的直接交互:通过视觉手段将信息以多层次的方式呈现,使用视觉元素进行指引,最后系统在后台进行实际的处理,并将最终结果以视觉手段展现出来。

这种更强调交互过程的设计初衷使得自动化变得非常困难。另一方面,由于GUI是为人类设计的,它的响应就不能太快,至少要留给操作者反应时间(甚至有些用户操作需要人为的加入一些延迟,以提升用户体验)。

程序员除了写代码之外,还有很多事情要做,比如自动化测试,基础设施的配置和管理,持续集成/持续发布环境,甚至有些团队好需要做一些与运维相关的事情(线上问题监控,环境监控等)。

  • 开发/测试

  • 基础设施管理

  • 持续集成/持续发布

  • 运维(监控)工作

  • 娱乐

文/邱俊涛

软件自动化测试,作为手工测试的替代,越来越受到关注。Pekka
Klärck,作为Robot
Framework的创建者和核心开发者,按照系统级别,介绍了几种不同的自动化测试方法的区别。

UNIX编程哲学

关于UNIX哲学,其实坊间有多个版本,这里有一个比较详细的清单。虽然有不同的版本,但是有很多一致的地方:

  1. 小即是美

  2. 让程序只做好一件事

  3. 澳门新葡亰平台官网,尽可能早地创建原型(然后逐步演进)

  4. 数据应该保存为文本文件

  5. 避免使用可定制性低下的用户界面

这里列举一些小的例子,我们来看看命令行工具是如何通过应用这些哲学来简化工作,提高效率的。一旦你熟练掌握这些技能,就再也无法摆脱它,也再也忍受不了低效而难用的各种GUI工具了。

优秀的程序员

要给优秀的程序员下一个明确的定义无疑是一件非常困难的事情。擅长抽象思维、动手能力强、追求效率、喜欢自动化、愿意持续学习、对代码质量有很高的追求等等,这些维度都有其合理性,不过又都略显抽象和主观。

澳门新葡亰平台官网 1

(图片来自:http://t.cn/R6I1yhJ)

我对于一个程序员是否优秀,也有自己的标准,那就是TA对命令行的熟悉/喜爱程度。这个特点可以很好的看出TA是否是一个优秀的(或者潜在优秀的)程序员。我周围就有很多非常牛的程序员,无一例外都非常擅长在命令行中工作。那什么叫熟悉命令行呢?简单来说,就是90%的日常工作内容可以在命令行完成。

当然,喜欢/习惯使用命令行可能只是表象,其背后包含的实质才是优秀的程序员之所以优秀的原因。

一、记录回放的方式流行于商业工具之中,无需编程技能即可快速上手。然而这种方法相对脆弱,一旦UI变化测试就会受到影响,分散的脚本不可重用且难以维护,而且系统在测试前必须可用(也就意味着无法使用A-TDD方法)。因此这种方法并不适合大型自动化测试。

命令行如何帮助程序员提升效率

自动化

Perl语言的发明者Larry Wall有一句名言:

The three chief virtues of a programmer are: Laziness, Impatience and
Hubris. – Larry Wall

懒惰(Laziness)这个特点位于程序员的三大美德之首:唯有懒惰才会驱动程序员尽可能的将日常工作自动化起来,解放自己的双手,节省自己的时间。相比较而言,不得不说,GUI应用天然就是为了让自动化变得困难的一种设计(此处并非贬义,GUI有着自己完全不同的目标群体)。

澳门新葡亰平台官网 2

(图片来自:http://t.cn/R6IBgYV)

GUI更强调的是与人类的直接交互:通过视觉手段将信息以多层次的方式呈现,使用视觉元素进行指引,最后系统在后台进行实际的处理,并将最终结果以视觉手段展现出来。

这种更强调交互过程的设计初衷使得自动化变得非常困难。另一方面,由于GUI是为交互而设计的,它的响应就不能太快,至少要留给操作者反应时间(甚至有些用户操作需要人为的加入一些延迟,以提升用户体验)。

二、线性脚本允许使用各种语言来编写非结构化脚本,脚本直接与被测系统交互。能够快速上手,灵活性强。但是编写脚本需要编程技能,系统中一个改动会影响所有脚本,没有经过模块化或重用的大量脚本难以维护。因此这种方法适合简单任务,不适合大型自动化。

一个高阶计算器

在我的编程生涯的早期,读过的最为振奋的一本书是《UNIX编程环境》,和其他基本UNIX世界的大部头比起来,这本书其实还是比较小众的。我读大二的时候这本书已经出版了差不多22年(中文版也已经有7年了),有一些内容已经过时了,比如没有返回值的main函数,外置的参数列表等等,不过在学习到HOC(High
Order Calculator)的全部开发过程时,我依然被深深的震撼到了。

简而言之,这个HOC语言的开发过程需要这样几个组件:

  • 词法分析器lex

  • 语法分析器yacc

  • 标准数学库stdlib

另外还有一些自定义的函数等,最后通过make连接在一起。我跟着书上的讲解,对着书把所有代码都敲了一遍。所有的操作都是在一台很老的IBM的ThinkPad
T20上完成的,而且全部都在命令行中进行(当然,还在命令行里听着歌)。

这也是我第一次彻底被UNIX的哲学所折服的体验:

  • 每个工具只做且做好一件事

  • 工具可以协作起来

  • 一切面向文本

下面是书中的Makefile脚本,通过简单的配置,就将一些各司其职的小工具协作起来,完成一个编程语言程序的预编译、编译、链接、二进制生成的动作。

YFLAGS = -d
OBJS = hoc.o code.o init.o math.o symbol.o
hoc5: $(OBJS)
  cc $(OBJS) -lm -o hoc5
hoc.o code.o init.o symbol.o: hoc.h
code.o init.o symbol.o: x.tab.h
x.tab.h: y.tab.h
  -cmp -s x.tab.h y.tab.h || cp y.tab.h x.tab.h
pr:   hoc.y hoc.h code.c init.c math.c symbol.c
  @pr $?
  @touch pr
clean:
  rm -f $(OBJS) [xy].tab.[ch]

虽然现在来看,这本书的很多内容已经过期(特别是离它第一次出版已经过去了近30年),有兴趣的朋友可以读一读。这里有一个Lex/Yacc的小例子,有情趣的朋友可以看看。

程序员的日常工作

程序员除了写代码之外,还有很多事情要做,比如自动化测试、基础设施的配置和管理、持续集成/持续发布环境,甚至有些团队还需要做一些与运维相关的事情(线上问题监控,环境监控等)。

  • 开发/测试
  • 基础设施管理
  • 持续集成/持续发布
  • 运维(监控)工作
  • (娱乐)

而这一系列的工作背后,都隐含了一个自动化的需求。在做上述工作时,优秀的程序员会努力将其自动化,如果有工具就使用工具;如果没有,就开发一个新的工具。这种努力让一切都尽可能自动化起来的哲学起源于UNIX世界。

而UNIX哲学的实际体现则是通过命令行来完成的。

Where there is a shell, there is a way.

三、模块化脚本由两部分组成:驱动脚本执行测试,测试库函数完成与被测系统交互。驱动脚本编写起来非常简单,这样可以更快地建立新测试,容易维护。然而需要花时间和编程技能建立测试库,并将测试数据嵌入脚本,建立新测试就需要新的测试脚本。因此,只要拥有编程技能,这种方法还是适合大型项目,但不适合非编程人员。

基础设施自动化

开发过程中,工程师还需要关注的一个问题是:软件运行的环境。我在上学的时候,刚开始学习Linux的时候,会在Windows机器上装一个虚拟机软件VMWare,然后在VMWare中安装一个Redhat Linux 9。这样当我不小心把Linux玩坏了之后,只需要重装一下就行了,不影响我的其他数据(比如课程作业,文档之类)。不过每次重装也挺麻烦,需要找到iso镜像文件,再挂载到本地的虚拟光驱上,然后再用VMWare来安装。

而且这些动作都是在GUI里完成的,每次都要做很多重复的事情:找镜像文件,使用虚拟光驱软件挂载,启动VMWare,安装Linux,配置个人偏好,配置用户名/密码等等。熟练之后,我可以在30分钟
– 60分钟安装和配置好一个新的环境。

UNIX编程哲学

关于UNIX哲学,其实坊间有多个版本,这里有一个比较详细的清单。虽然有不同的版本,但是有很多一致的地方:

  1. 小即是美
  2. 让程序只做好一件事
  3. 尽可能早地创建原型(然后逐步演进)
  4. 数据应该保存为文本文件
  5. 避免使用可定制性低下的用户界面

审视这些条目,我们会发现它们事实上促成了自动化一切的可能性。这里列举一些小的例子,我们来看看命令行工具是如何通过应用这些哲学来简化工作、提高效率的。一旦你熟练掌握这些技能,就再也无法离开它,也再也忍受不了低效而复杂的各种GUI工具了。

四、数据驱动方法,将数据与测试脚本分离,基于模块化的测试库,一个驱动脚本可以执行多个相似测试,这样非常容易建立新测试。维护工作可以分离,测试人员负责数据,程序员负责写测试库。然而,不同类型测试仍需要新的驱动脚本,初始建立数据解析器和重用组件需要花人力。这种方法适合大型项目,只需要较少的编程技能。

Vagrant

后来我就发现了Vagrant,它支持开发者通过配置的方式将机器描述出来,然后通过命令行的方式来安装并启动,比如下面这个配置:

VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.box = "precise64"
  config.vm.network "private_network", :ip => "192.168.2.100"
end

它定义了一个虚拟机,使用Ubuntu Precise 64的镜像,然后为其配置一个网络地址192.168.2.100,定义好之后,我只需要执行:

$ vagrant up

我的机器就可以在几分钟内装好,因为这个动作是命令行里完成的,我可以在持续集成环境里做同样的事情

只需要一条命令。定义好的这个文件可以在团队内共享,可以放入版本管理,团队里的任何一个成员都可以在几分钟内得到一个和我一样的环境。

命令行如何提升效率

五、关键字驱动,将数据与关键字结合来描述如何使用数据执行测试。这种方法具备数据驱动的优势,同时非编程人员也能建立新类型测试。所有测试由同一个框架来执行,无需不同的驱动脚本。然而初始成本很大,但是可以使用开源方案!因此非常适合大型项目。

Ansible

一般而言,对于一个软件项目而言,一个全新的操作系统基本上没有任何用处。为了让应用跑起来,我们还需要很多东西。比如Web服务器,Java环境,cgi路径等,除了安装一些软件之外,还有大量的配置工作要做,比如apache httpd服务器的文档根路径,JAVA_HOME环境变量等等。

这些工作做好了,一个环境才算就绪。我记得在上一个项目上,不小心把测试环境的Tomcat目录给删除了,结果害的另外一位同事花了三四个小时才把环境恢复回来(包括重新安装Tomcat,配置一些JAVA_OPTS,应用的部署等)。

不过还在我们有很多工具可以帮助开发者完成环境的自动化准备,比如:Chef, Puppet, Ansible。只需要一些简单的配置,然后结合一个命令行应用,整个过程就可以自动化起来了:

- name: setup custom repo
  apt: pkg=python-pycurl state=present
- name: enable carbon
  copy: dest=/etc/default/graphite-carbon content='CARBON_CACHE_ENABLED=true'
- name: install graphite and deps
  apt: name= state=present
  with_items: packages
- name: install graphite and deps
  pip: name= state=present
  with_items: python_packages
- name: setup apache
  copy: src=apache2-graphite.conf dest=/etc/apache2/sites-available/default
  notify: restart apache
- name: configure wsgi
  file: path=/etc/apache2/wsgi state=directory

上边的配置描述了安装graphite-carbon,配置apahce等很多手工的劳动,开发者现在只需要执行:

$ ansible

就可以将整个过程自动化起来。现在如果我不小心把Tomcat删了,只需要几分钟就可以重新配置一个全新的,当然整个过程还是自动的。这在GUI下完全无法想象,特别是有如此多的定制内容的场景下。

一个高阶计算器

在我的编程生涯早期,读过的最为振奋的一本书是《UNIX编程环境》,和其他基本UNIX世界的大部头比起来,这本书其实还是比较小众的。我读大二的时候这本书已经出版了差不多22年(中文版也已经有7年了),有一些内容已经过时了,比如没有返回值的main函数、外置的参数列表等等,不过在学习到HOC(High
Order Calculator)的全部开发过程时,我依然被深深的震撼到了。

简而言之,这个HOC语言的开发过程需要这样几个组件:

  • 词法分析器lex
  • 语法分析器yacc
  • 标准数学库stdlib

另外还有一些自定义的函数等,最后通过make连接在一起。我跟着书上的讲解,对着书把所有代码都敲了一遍。所有的操作都是在一台很老的IBM的ThinkPad
T20上完成的,而且全部都在命令行中进行(当然,还在命令行里听着歌)。

这也是我第一次彻底被UNIX的哲学所折服的体验:

  • 每个工具只做且做好一件事
  • 工具可以协作起来
  • 一切面向文本

下面是书中的Makefile脚本,通过简单的配置,就将一些各司其职的小工具协作起来,完成一个编程语言程序的预编译、编译、链接、二进制生成的动作。

YFLAGS = -d
OBJS = hoc.o code.o init.o math.o symbol.o

hoc5:    $(OBJS)
  cc $(OBJS) -lm -o hoc5

hoc.o code.o init.o symbol.o: hoc.h

code.o init.o symbol.o: x.tab.h

x.tab.h: y.tab.h
  -cmp -s x.tab.h y.tab.h || cp y.tab.h x.tab.h

pr:  hoc.y hoc.h code.c init.c math.c symbol.c
  @pr $?
  @touch pr

clean:
  rm -f $(OBJS) [xy].tab.[ch]

虽然现在来看,这本书的很多内容已经过期(特别是离它第一次出版已经过去了近30年),有兴趣的朋友可以读一读。这里有一个Lex/Yacc的小例子的小例子,有兴趣的朋友可以看看。

当然,如果你使用现在最先进的IDE(典型的GUI工具),其背后做的事情也是同样的原理:生成一个Makefile,然后在幕后调用它。

Pekka对以上五种方法的介绍其实也是对自动化测试发展史的介绍,同时也体现了RobotFramework背后的设计思想。

持续集成/持续发布

日常开发任务中,除了实际的编码和环境配置之外,另一大部分内容就是持续集成/持续发布了。借助于命令行,这个动作也可以非常高效和自动化。

基础设施自动化

开发过程中,工程师还需要关注的一个问题是:软件运行的环境。我在学生时代刚开始学习Linux的时候,会在Windows机器上装一个虚拟机软件VMWare,然后在VMWare中安装一个Redhat Linux 9

澳门新葡亰平台官网 3

(图片来自:http://t.cn/R6IBSAu)

这样当我不小心把Linux玩坏了之后,只需要重装一下就行了,不影响我的其他数据(比如课程作业、文档之类)。不过每次重装也挺麻烦,需要找到iso镜像文件,再挂载到本地的虚拟光驱上,然后再用VMWare来安装。

而且这些动作都是在GUI里完成的,每次都要做很多重复的事情:找镜像文件,使用虚拟光驱软件挂载,启动VMWare,安装Linux,配置个人偏好,配置用户名/密码等等。熟练之后,我可以在30
- 60分钟内安装和配置好一个新的环境。

除了测试框架的选择,要想做好自动化测试,还要关注其他方面。

Jenkins

持续集成/持续发布已经是很多企业IT的基本配置了。各个团队通过持续集成环境来编译代码、静态检查、执行单元测试、端到端测试、生成报告、打包、部署到测试环境等等。

澳门新葡亰平台官网 4

比如在Jenkins环境中,在最前的版本中,要配置一个构建任务需要很多的GUI操作,不过在新版本中,大部分操作都已经可以写成脚本。

这样的方式,使得自动化变成了可能,要复制一个已有的pipline,或者要修改一些配置、命令、变量等等,再也不需要用鼠标点来点去了。而且这些代码可以纳入项目代码库中,和其他代码一起被管理,维护,变更历史也更容易追踪和回滚(在GUI上,特别是基于Web的,回滚操作基本上属于不可能)。

node {
   def mvnHome
   stage('Preparation') { // for display purposes
      git 'https://github.com/jglick/simple-maven-project-with-tests.git'
      mvnHome = tool 'M3'
   }
   stage('Build') {
      sh "'${mvnHome}/bin/mvn' -Dmaven.test.failure.ignore clean package"
   }
   stage('Results') {
      junit '**/target/surefire-reports/TEST-*.xml'
      archive 'target/*.jar'
   }
}

上面这段groovy脚本定义了三个Stage,每个Stage中分别有自己的命令,这种以代码来控制的方式显然比GUI编辑的方式更加高效,自动化也编程了可能。

Vagrant

后来我就发现了Vagrant,它支持开发者通过配置的方式将机器描述出来,然后通过命令行的方式来安装并启动,比如下面这个配置:

VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.box = "precise64"
  config.vm.network "private_network", :ip => "192.168.2.100"
end

它定义了一个虚拟机,使用Ubuntu Precise 64的镜像,然后为其配置一个网络地址192.168.2.100,定义好之后,我只需要执行:

$ vagrant up

我的机器就可以在几分钟内装好,因为这个动作是命令行里完成的,我可以在持续集成环境里做同样的事情

只需要一条命令。定义好的这个文件可以在团队内共享,可以放入版本管理,团队里的任何一个成员都可以在几分钟内得到一个和我一样的环境。

自动化测试需要关注可测性。自动化最难的部分是与被测系统交互,特别是GUI层。确保系统容易被测试,比如给GUI元素增加标识、输出易于解析的文本、提供自动化接口等。

运维工作

Ansible

一般,对于一个软件项目而言,一个全新的操作系统基本上没有任何用处。为了让应用跑起来,我们还需要很多东西。比如Web服务器、Java环境、cgi路径等,除了安装一些软件之外,还有大量的配置工作要做,比如apache httpd服务器的文档根路径,JAVA_HOME环境变量等等。

澳门新葡亰平台官网 5

(图片来自:http://t.cn/R6IBZKm)

这些工作做好了,一个环境才算就绪。我记得在上一个项目上,不小心把测试环境的Tomcat目录给删除了,结果害的另外一位同事花了三四个小时才把环境恢复回来(包括重新安装Tomcat,配置一些JAVA_OPTS,应用的部署等)。

不过好在我们有很多工具可以帮助开发者完成环境的自动化准备,比如:Chef、
Puppet、Ansible。只需要一些简单的配置,然后结合一个命令行应用,整个过程就可以自动化起来了:

- name: setup custom repo
  apt: pkg=python-pycurl state=present

- name: enable carbon
  copy: dest=/etc/default/graphite-carbon content='CARBON_CACHE_ENABLED=true'

- name: install graphite and deps
  apt: name={{ item }} state=present
  with_items: packages

- name: install graphite and deps
  pip: name={{ item }} state=present
  with_items: python_packages

- name: setup apache
  copy: src=apache2-graphite.conf dest=/etc/apache2/sites-available/default
  notify: restart apache

- name: configure wsgi
  file: path=/etc/apache2/wsgi state=directory

上边的配置描述了安装graphite-carbon、配置apahce等很多手工的劳动,开发者现在只需要执行:

$ ansible 

就可以将整个过程自动化起来。现在如果我不小心把Tomcat删了,只需要几分钟就可以重新配置一个全新的,当然整个过程还是自动的。这在GUI下完全无法想象,特别是在有如此多的定制内容的场景下。

系统一般可以分为GUI层以及GUI之下的业务层。GUI层测试需要调用与普通用户同样的接口,但是某些GUI技术缺乏好的工具支持,会使测试变得脆弱,而且执行相对较慢。从业务层开始测试相对容易,执行快。但GUI层仍然需要被测试,以保证GUI正确连接到了业务层,甚至有时GUI层也具有业务功能。Pekka建议考虑对业务层进行完全测试,而部分地对GUI层实行端到端测试。
不是所有系统都具有GUI层,却可能具有API、数据库、服务器、命令行等。自动化测试框架可以调用不同驱动来进行测试。这些非GUI层相对容易测试,只要把测试用例看作另一个客户端而已。

自动化监控

Graphite是一个功能强大的监控工具,不过其背后的理念倒是很简单:

  • 存储基于时间线的数据

  • 将数据渲染成图,并定期刷新

用户只需要将数据按照一定格式定期发送给Graphite,剩下的事情就交给Graphite了,比如它可以消费这样的数据:

instance.prod.cpu.load 40 1484638635
instance.prod.cpu.load 35 1484638754
instance.prod.cpu.load 23 1484638812

第一个字段表示数据的名称,比如此处instance.prod.cpu.load表示prod实例的CPU负载,第二个字段表示数据的,最后一个字段表示时间戳。

这样,Graphite就会将所有同一个名称下的值按照时间顺序画成图。

澳门新葡亰平台官网 6

图片来源

默认地,Graphite会监听一个网络端口,用户通过网络将信息发送给这个端口,然后Graphite会将信息持久化起来,然后定期刷新。简而言之,只需要一条命令就可以做到发送数据:

echo "instance.prod.cpu.load 23 `date +%s`" | nc -q0 graphite.server 2003

date +%s会生成当前时间戳,然后通过echo命令将其拼成一个完整的字符串,比如:

instance.prod.cpu.load 23 1484638812

然后通过管道|将这个字符串通过网络发送给graphite.server这台机器的2003端口。这样数据就被记录在graphite.server上了。

持续集成/持续发布

日常开发任务中,除了实际的编码和环境配置之外,另一大部分内容就是持续集成/持续发布了。借助于命令行,这个动作也可以非常高效和自动化。

那么自动化测试应该在什么阶段进行?如果开发完成后单独做自动化,这是典型的瀑布式过程,不同团队之间存在沟通障碍,反馈周期慢,产品在后期难以获得可测性,从而导致复杂和脆弱的测试方案。相反,典型敏捷式过程中,程序员和测试人员协同完成自动化。把自动化看作团队开发的一部分,可测性不再是问题,团队做技术决定时就可以考虑可测性和工具选择,程序员可以提前加入提供可测性的钩子特性。

定时任务

如果我们要自动的将数据每隔几秒就发送给graphite.server,只需要改造一下这行命令:

  1. 获取当前CPU的load

  2. 获取当前时间戳

  3. 拼成一个字符串

  4. 发送给graphite.server2003端口

  5. 每隔5分钟做重复一下1-4

获取CPU的load在大多数系统中都很容易:

ps -A -o %cpu

这里的参数:

  • -A表示统计所有当前进程

  • -o %cpu表示仅显示%cpu列的数值

这样可以得到每个进程占用CPU负载的数字:

%CPU
  12.0
  8.2
  1.2
  ...

下一步是将这些数字加起来。通过awk命令,可以很容易做到这一点:

$ awk '{s+=$1} END {print s}'

比如要计算1 2 3的和:

$ echo "1n2n3" | awk '{s+=$1} END {print s}'
6

通过管道可以讲两者连起来:

$ ps -A -o %cpu | awk '{s+=$1} END {print s}'

我们测试一下效果:

$ ps -A -o %cpu | awk '{s+=$1} END {print s}'
28.6

看来还不错,有个这个脚本,通过crontab来定期调用即可:

#!/bin/bash
SERVER=graphite.server
PORT=2003
LOAD=`ps -A -o %cpu | awk '{s+=$1} END {print s}'`
echo "instance.prod.cpu.load ${LOAD} `date +%s`" | nc -q0 ${SERVER} ${PORT}

当然,如果使用Grafana等强调UI的工具,可以很容易的做的更加酷炫:

澳门新葡亰平台官网 7

图片来源

想想用GUI应用如何做到这些工作。

Jenkins

持续集成/持续发布已经是很多企业IT的基本配置了。各个团队通过持续集成环境来编译代码、静态检查、执行单元测试、端到端测试、生成报告、打包、部署到测试环境等等。

澳门新葡亰平台官网 8

比如在Jenkins环境中,在最前的版本中,要配置一个构建任务需要很多的GUI操作,不过在新版本中,大部分操作都已经可以写成脚本。

这样的方式,使得自动化变成了可能,要复制一个已有的pipline,或者要修改一些配置、命令、变量等等,再也不需要用鼠标点来点去了。而且这些代码可以纳入项目代码库中,和其他代码一起被管理、维护,变更历史也更容易追踪和回滚(在GUI上,特别是基于Web的,回滚操作基本上属于不可能)。

node {
   def mvnHome

   stage('Preparation') { // for display purposes
      git 'https://github.com/jglick/simple-maven-project-with-tests.git'
      mvnHome = tool 'M3'
   }

   stage('Build') {
      sh "'${mvnHome}/bin/mvn' -Dmaven.test.failure.ignore clean package"
   }

   stage('Results') {
      junit '**/target/surefire-reports/TEST-*.xml'
      archive 'target/*.jar'
   }
}

上面这段groovy脚本定义了三个阶段,每个阶段中分别有自己的命令,这种以代码来控制的方式显然比GUI编辑的方式更加高效,自动化也变成了可能。

自动化测试需要版本控制和持续集成来支持。将测试和代码放在一起,像管理代码一样管理测试脚本,那么多可用工具,SVN、GIT、Mercurial,没道理不用。持续集成是全方位自动化的关键,当测试或代码有所改动立即执行测试。如果测试运行时间比较长,也可以定期运行。使用Jenkins、Hudson、Cruise
Control、 BuildBot吧,自己写定时脚本或Cron Job可以休矣。

娱乐

运维工作

选择商业自动化工具还是开源工具?好东西肯定贵,但是贵的不见得好,再便宜的许可证也会阻止整个团队的协作。而且商业化工具难以和其他自动化工具(特别是其他厂商的)或版本控制、持续集成进行整合和定制化。另外,产品终止或公司关门是潜在的风险。开源工具可供选择余地很大,当然也是良莠不齐。开源工具通常容易与其他工具整合,关键是免费,谁都可以随意使用和定制化,还永远不会消失。至于免费软件,越来越少了,很多自由软件都已经开源。免费软件同样不能定制化,且存在中止的风险。

命令行的MP3播放器

最早的时候,有一个叫做mpg123的命令行工具,用来播放MP3文件。不过这个工具是商用的,于是就有人写了一个工具,叫mpg321,基本上是mpg123的开源克隆。不过后来mpg123自己也开源了,这是后话不提。

将我的所有mp3文件的路径保存成一个文件,相当于我的歌单:

$ ls /Users/jtqiu/Music/*.mp3 > favorites.list
$ cat favorites.list
...
/Users/jtqiu/Music/Rolling In The Deep-Adele.mp3
/Users/jtqiu/Music/Wavin' Flag-K'Naan.mp3
/Users/jtqiu/Music/蓝莲花-许巍.mp3
...

然后我将这个歌单交给mpg321去在后台播放:

$ mpg321 -q --list favorites.list &
[1] 10268

这样我就可以一边写代码一边听音乐,如果听烦了,只需要将这个后台任务切换到前台fg,然后就可以关掉了:

$ fg
[1]  + 10268 running    mpg321 -q --list favorites.list

自动化监控

Graphite是一个功能强大的监控工具,不过其背后的理念倒是很简单:

  • 存储基于时间线的数据
  • 将数据渲染成图,并定期刷新

用户只需要将数据按照一定格式定期发送给Graphite,剩下的事情就交给Graphite了,比如它可以消费这样的数据:

instance.prod.cpu.load 40 1484638635
instance.prod.cpu.load 35 1484638754
instance.prod.cpu.load 23 1484638812

第一个字段表示数据的名称,比如此处instance.prod.cpu.load表示prod实例的CPU负载,第二个字段表示数据的,最后一个字段表示时间戳。

这样,Graphite就会将所有同一名称下的值按照时间顺序画成图。

澳门新葡亰平台官网 9

(图片来自:http://t.cn/R6IxKYL)

默认地,Graphite会监听一个网络端口,用户通过网络将信息发送给这个端口,然后Graphite会将信息持久化起来,然后定期刷新。简而言之,只需要一条命令就可以做到发送数据:

echo "instance.prod.cpu.load 23 `date +%s`" | nc -q0 graphite.server 2003

date +%s会生成当前时间戳,然后通过echo命令将其拼成一个完整的字符串,比如:

instance.prod.cpu.load 23 1484638812

然后通过管道|将这个字符串通过网络发送给graphite.server这台机器的2003端口。这样数据就被记录在graphite.server上了。

做自动化需要哪些技能?一般来说,包括Python、Ruby、Perl、JavaScript、正则表达式、XPath和CSS定位、SQL语句、版本控制等。

小结

综上,优秀的程序员借助命令行的特性,可以成倍(有时候是跨越数量级的)地提高工作效率,从而有更多的时间进行思考、学习新的技能,或者开发新的工具帮助某项工作的自动化。这也是优秀的程序员之所以优秀的原因。而面向手工的,原始的图形界面会拖慢这一过程,很多原本可以自动化起来的工作被淹没在“简单的GUI”之中。

最后补充一点,本文的关键在于强调优秀的程序员与命令行的关系,而不在GUI应用和命令行应用的优劣。GUI应用当然有其使用场景,比如做3D建模,GIS系统,设计师的创作,图文并茂的字处理软件,电影播放器,网页浏览器等等。

稿源:icodeit

定时任务

如果我们要自动的将数据每隔几秒就发送给graphite.server,只需要改造一下这行命令:

  1. 获取当前CPU的load
  2. 获取当前时间戳
  3. 拼成一个字符串
  4. 发送给graphite.server2003端口
  5. 每隔5分钟做重复一下1-4

获取CPU的load在大多数系统中都很容易:

 ps -A -o %cpu 

这里的参数:

  • -A表示统计所有当前进程
  • -o %cpu表示仅显示%cpu列的数值

这样可以得到每个进程占用CPU负载的数字:

<pre>%CPU
12.0
8.2
1.2
…</pre>

下一步是将这些数字加起来。通过awk命令,可以很容易做到这一点:

$ awk '{s+=$1} END {print s}'  

当然,如果使用Grafana等强调UI的工具,可以很容易的做的更加酷炫:

澳门新葡亰平台官网 10

想想用GUI应用如何做到这些工作。

有了自动化,手工测试还需要吗?当然需要!!
不过,要避免手工执行脚本来测试,还是将其完全自动化吧,测试人员可以更多关注于探索性测试。
记住,机器擅长回归测试,人类善于寻找Bug。

娱乐

命令行的MP3播放器

最早的时候,有一个叫做mpg123的命令行工具,用来播放MP3文件。不过这个工具是商用的,于是就有人写了一个工具,叫mpg321,基本上是mpg123的开源克隆。不过后来mpg123自己也开源了,这是后话不提。

将我的所有mp3文件的路径保存成一个文件,相当于我的歌单:

<pre>$ ls /Users/jtqiu/Music/<span
class=”pl-k”>*</span>.mp3 <span
class=”pl-k”>></span> favorites.list
$ cat favorites.list

/Users/jtqiu/Music/Rolling In The Deep-Adele.mp3
/Users/jtqiu/Music/Wavin<span class=”pl-s”><span
class=”pl-pds”>'</span> Flag-K<span
class=”pl-pds”>'</span></span>Naan.mp3
/Users/jtqiu/Music/蓝莲花-许巍.mp3
…</pre>
然后我将这个歌单交给mpg321去在后台播放:
<pre>$ mpg321 -q –list favorites.list <span
class=”pl-k”>&</span>
[1]
10268</pre>这样我就可以一边写代码一边听音乐,如果听烦了,只需要将这个后台任务切换到前台fg,然后就可以关掉了:
<pre>$fg
[1] + 10268 running mpg321 -q –list favorites.list</pre>

欢迎加群:680748947一起进行软件测试的交流分享~

小结

综上,优秀的程序员借助命令行的特性,可以成倍(有时候是跨越数量级的)提高工作效率,从而有更多的时间进行思考、学习新的技能,或者开发新的工具帮助某项工作的自动化。这也是优秀的程序员之所以优秀的原因。而面向手工的、原始的图形界面会拖慢这个过程,很多原本可以自动化起来的工作被淹没在“简单的GUI”之中。

澳门新葡亰平台官网 11

最后补充一点,本文的关键在于强调优秀的程序员与命令行的关系,而不在GUI程序和命令行的优劣对比。GUI程序当然有其使用场景,比如做3D建模、GIS系统、设计师的创作、图文并茂的字处理软件、电影播放器、网页浏览器等等。

应该说,命令行优秀的程序员之间更多是关联关系,而不是因果关系。在程序员日常的工作中,涉及到的更多的是一些需要命令行工具来做支持的场景。如果走极端,在不适合的场景中强行使用命令行,而置效率于不顾,则未免有点矫枉过正,南辕北辙了。


更多精彩洞见,请关注微信公众号:思特沃克

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图