从Devops谈测试开发和product开发差异-【FAENWSI】

* 感谢来自于Pinterest, Amazon, Airbnb及微博的资深技术专家朋友们所提供的建议和讨论,保证了本文在内容和概念上的准确

研发效能,或者说Devops在近年来的国内颇受重视,大小公司都意识到严谨有效的研发体系才是战斗力/产出的最佳保障,并对此纷纷加大力度。

工欲善其事,必先利其器。对于Devops或者说研发效能体系的建设,首先就是要有合适的人,问题是,到底要招什么样的人,组建什么样的团队?

因为Devops基本上就是CI/CD的同义词,CI的目标是持续测试,所以国内过去的测试人员和测试开发人员往往成为了各公司负责Devops平台开发的主力,或者说项目启动时的初期主力。然而随着研发的深入,很多公司的相关负责人和HR都会产生疑惑:为什么产品开发人员总是抱怨这些CI/CD工具不是他们需要的呢?为什么产品开发人员说他们的需求和Devops所开发的东西不匹配呢?而同时国内Devops开发人员却列出一大堆各种测试工具,看起来又覆盖了方方面面呢?

这种问题,为什么在美国在硅谷没有出现呢?为什么在硅谷的产品开发几乎和Devops系统无缝衔接呢?

Devops系统对大型公司研发体系如何落地是非常复杂的事情,但我们在这里只针对文章最初提出的那个问题来讨论:测试开发为主的团队能否承担大型Devops平台的开发?还是应该由面向产品的后台开发/前端开发来主导?为什么?

….….

首先,要回答第一个问题:测试开发能否主导大型Devops平台开发?这需要定义另一个问题:Devops平台到底是一个什么系统?

  • 谈谈Devops平台

这里不做过多的技术分析,我们就从使用场景来谈。Devops平台的主要应用场景包括CI/CD,而在Kubernetes普及后,CI/CD的基本需求也很简单:

  • CI:能够动态拉起需要的容器,根据设定执行对应的代码构建及运行测试。实际上,CI需要对生产环境进行模拟(minic prod environment)

  • CD:根据需要,实时更新容器、调整相关设置并发布服务

从这两点来说,Devops平台实质上是一个资源管理服务,它的目的是根据需要创建对应的容器和相关配置,然后执行其中的程序(无论是执行单元测试还是产品应用)。而为了达到这个目的,devops平台需要合理组合基础架构(infrastructure)中的各种底层服务(k8s的容器资源、各种数据存储、消息队列、事件跟踪、日志分析、代码管理。。。),对这些底层服务根据不同需要进行组合搭配,形成合理的pipeline来完成CI/CD即日常开发所需要的调试环境服务。

为了更好地说明CI/CD、devops和infrastructure的关系,我们来看下面这张图:

上图从上到下分了三层,最上面就是从开发->CI->CD,中间是为了能够支持这样的流程,需要一些什么样的环境或者服务(也即是Devops平台所要提供的内容),最下面的Infrastructure则是提供公司各种最基础的技术服务平台,例如数据库、服务器、k8s的容器服务、消息队列等等。

注意我们在第一层流程开发->CI->CD流程中,强调的是在不同步骤到底在执行什么内容,或者说运行什么代码。因为Devops要为CI/CD提供运行环境,实质上就是要让不同阶段的需要执行的代码能正常运行。上图中我们归纳如下:

  • 开发阶段:运行本地开发中的代码和本地单元测试代码

  • 构建阶段:运行项目编译脚本、Docker构建文件抑或是其它项目发布相关脚本

  • 测试阶段:首先要运行对应的产品服务代码,然后执行对应的单元测试、集成测试或可能的end to end测试代码。

  • 预发布和生产环境:运行产品服务代码

注意测试阶段和预发布/正式发布阶段的相同处在于,两者都需要启动运行产品服务代码,只是前者是为了启动后作为测试对象存在,后者则是让用户使用。我们可以理解为测试阶段的产品调用者是自动测试代码预发布/正式发布阶段的产品调用者是真实用户。从技术上来说,前者(测试环境)的挑战在于如何灵活地根据不同需要进行部署,并尽量用较少的资源消耗来模拟后者(生产环境),而后者的挑战则是如何auto scaling如何保持高可用高并发等等。

一定要注意,要推行Devops流程,上面提到的“测试代码”就一定是产品开发人员自行开发,而不是QA/SDET的工作。因此我们也可以说Devops平台的所有工作都是为了提供让产品开发人员所编写的代码正常运行的环境。

在过去没有Devops这个概念,各个公司的产品开发流程相对简单,靠手工测试和部分本地测试就能满足需要的时候,Infrastructure的主要工作实际上只是支撑Production生产环境,无论是要部署Spark还是要上机器学习平台,他们只需要针对生产环境即可。

但随着现代应用越来越复杂而且后端各种服务依赖越来越强的时候,程序员们就发现越来越需要在发布之前就进行“尽可能真实”的测试(无论这个测试是自动化还是手动),那么对于Infra团队来说,要考虑的就不单单是面向生产环境的部署,而是如何也能面向公司内部不同开发/测试阶段的需要,来灵活构建对应的运行环境。

注意这里的“根据不同需要来灵活构建“,这种需要可以是来源于预定义的prod环境,可以是开发人员写在代码中的配置文件(如常见的dev-config.yaml, staging-config.yaml之类所谓infra as code的配置),也可以是专门提供某种工具来动态定义环境—–在国内,通常用“环境治理”来描述这种工作,实际上要治理的大类别也就是上图中的开发环境、构建环境、测试环境、预发布环境和生产环境(不过要注意,因为生产环境的特殊性和重要性,通常对它的部署和定义是独立的,Devops要做的是在内部去minic去模仿生产环境,而不是反过来强迫生产环境和内部对齐)。

因此对于硅谷的各大小公司,Devops往往是作为Infrastructure(基础架构)团队的一环。Infrastructure(基础架构)团队本来就是服务于产品研发的底层服务(如提供数据库、消息队列、日志平台等等),他们自身的研发流程和习惯和其他产品开发人员完全一体,因此他们和产品开发团队的交流和理解是无缝的。实际上,在硅谷的公司中,Infrastructure团队一开始就需要定义整个公司的核心底层技术栈体系,在这基础上衍生出如何基于底层技术栈来设计整个公司的研发流程,就再合理不过了。

知道了Devops本身实质是基础架构的衍生品,就很容易理解为什么硅谷的Devops系统能和产品开发流程完美衔接,因为其开发人员基本都是来自于做基础架构的相关人员。实际上这也就侧面回答了我们的问题:测试开发并不适合作为Devops系统的主导人员。

为什么?即便测试开发不熟悉公司的基础技术架构,这些技术问题可以合作解决吧?再说devops也是基于公司的基础架构来设计一套流程,是一个新的平台,为什么不能让测试开发来做呢?

这涉及到两个问题,也是测试开发和产品开发的核心差别。首先是工作环境带来的产品经验问题,其次是工作需要带来的开发技能问题。下面我们来分别解释。

  • 测试开发的产品经验问题

测试开发和产品开发的工作内容不同,所积累的经验必然不同。如果光从编程来说,有很多技术的确可以靠学习来弥补,但有一点是无法短期获得的:一个面向用户的产品设计开发全流程—–或者说,如何和产品经理、项目经理、前端开发等多个领域多个角色一起协作开发一个面向第三方用户的产品,并不断完善迭代,持续更新长期运营改进下去的产品,这是测试开发所不太可能具备的经验。

这其中的关键就是是否和真正的产品经理,在产品开发的节奏下长期合作过。这样才能经历从产品原型到MVP并根据用户反馈、监控数据等不断调整迭代,获得在满足产品需求的同时持续对技术架构进行调整优化重构的宝贵经验,在技术上认识到什么微服务什么消息队列什么设计模式什么A/B test及feature flag都是为快速可靠地实现不断变化的产品需求而服务,在思维上能养成一定的技术前瞻性和预见性,能够知道一个产品在不同阶段需要做哪些技术工作,知道不同技术实现的短期长期利弊取舍(注意必须要跟过长期大型项目才可能获得这种经验,这不是猜出来或者看书看出来的)。

有这些经历的产品开发人员,当开始负责Devops系统或者说基础架构服务的衍生应用时,即便没有了产品经理的引导,他们也能本能地根据产品开发的节奏和方式去设计开发,确保其稳定性并持续完善。加上这本来就是面向开发者的平台(开发者本身就是用户),因此在用户体验和流程设计上不会有太大问题。


而对于测试开发人员,要注意到测试开发的本职工作是编写自动化测试代码/脚本,他们并不和产品经理合作,因此也很少能体会到一个完整产品的研发过程。在近几年的devops抑或什么测试中台的讨论中,我们经常会看到抱怨说各种工具都有,就是非常零散,无法形成一个统一的体系。这就是缺乏产品开发习惯带来的后果:工作停留在“完成功能”的类似技术原型的层面上,能满足自己使用就行(因为本职工作是为了写自动化测试代码,完成自己或QA的测试需要,而不是为了提供给第三方用户使用)。

那么我们要问,是不是给测试开发配一个产品经理就能带他们把原先的简单工具变为可服务于复杂需求并整合为完善产品平台呢?

答案是非常困难,实际上很可能是NO(我们并不排除有这种可能性,但目前来看并没有任何这种案例)。这又涉及到另一个下面要谈的问题:开发技能问题。

  • 测试开发的开发技能问题

让测试开发去负责面向外部或者第三方用户的产品化项目,除了存在前面谈到的欠缺产品研发流程经验问题之外,另一个问题就是测试开发在开发技能,尤其是开发思维习惯上和其他的产品开发存在一些较大差异。

为什么这么说?因为测试开发的本职工作是写测试自动化,换句话说,他们的工作是把QA/Tester定义的手工测试案例转化为能自动执行的代码,因此他们日常工作中对接的并不是产品经理,甚至都不是产品开发程序员,而是负责手工测试的QA,从QA那里拿到需求,然后根据QA需求完成对应的自动化脚本。尽管有一些不错的测试开发能在此基础上做一些自动化框架来简化测试脚本的编写工作,但本质上这仍然是为了满足QA的测试需求。

一旦手工测试需求变为自动化代码,我们对这些自动化测试代码的要求就是“不要再去改动”,我们对测试脚本或者单元测试并没有经常重构或性能优化的需求(但是对测试代码有别的要求,例如清晰可读、简单易懂、直接明了等要求),因此对于测试开发人员来说,并不需要设计灵活的代码架构或者可扩展的底层架构来满足未来的用户/数据需求,更无须思考微服务松耦合等等为大型服务多团队合作开发准备的问题。这样会导致长期从事测试开发的人员对这些大型产品系统必备的技术问题缺乏足够思考和切身经验。

在这种情况下,如果让测试开发负责产品的技术架构,他们要么就是以较简化类似原型的方案去实施,称之为“已经能够满足当前需要”,要么过度设计一些脱离公司和团队现实的架构(通常是为了看上去漂亮,而经不起仔细推敲)。在实际工作中,测试开发通常缺乏规划产品不同阶段的后端架构改进计划能力,不能在充分利用现有资源的同时实现技术架构的逐步迭代(e.g. 常见的问题是因为没有做过面向用户的产品,对数据的价值认识不足,没有一开始就把事件跟踪/统计/回溯等问题作为可持续开发的重点去设计,最后头痛医头脚痛医脚,找不到研发方向)。

  • Final Words

测试开发,或者说国外对应的SDET,从本质上来讲是自动化QA工作。根据其所服务产品的不同,部分SDET对某些产品或技术仍然能有较深入的技术理解,例如针对数据库的自动化测试开发即QA,那么一定对所负责数据库(例如Oracle)有极深了解,称之为相关专家也不为过。

但这并不能掩盖SDET/测试开发本身在产品开发经验和技能上的一些缺陷。产品开发在过去要求的是完整的产品流程,在现代敏捷开发中则更是加入了迭代要求,同时有大量的用户事件跟踪、存储和分析的需求来用于产品改进,而这些都是测试开发的本质工作不需要的。

Devops系统本身是基础架构(Infrastructure)的一环。在传统的基础架构产品如数据服务、流计算服务等开发团队中,一定是专门的后台开发人员负责,而不会由测试开发牵头。然而因为Devops的CI包含有测试目的,而CI通常以持续测试为重点(尽管它本质是合理调度资源来执行单元测试代码),不少公司就因此让测试开发甚至是QA人员作为Devops CI系统的主导,这不能不说是一个极大的误区。

当然,我们并不是说测试开发/SDET就不能参与Devops或CI系统的开发工作,那当然是可以的。但更多的应该是负责提供CI系统的一些辅助工具实现,能够对CI流程起到完善作用,但CI本身的核心平台,仍然应由负责基础架构的核心后台开发人员负责。

同时我们也一定要意识到,Devops平台的开发,或者说研发效能系统的开发,其用户和服务对象是产品开发人员(因此实际上也可以用产品开发来做相关工作,因为用户最了解需求),不是QA。这跟测试开发/SDET的服务对象是完全不同的。不少公司以为一提到自动化测试/持续测试就本能以为这仍然是测试的事情,但他们忘了既然Devops强调开发负责质量,测试左移,那么面向用户就已经彻底改变,所要做的工作本质也完全不同,我们再总结一次:


服务对象 工作
目标
测试开发
QA/Tester/测试人员
编写代码将手工测试案例变为自动化执行的脚本 让QA工作更简单,能够直接执行脚本完成某些工作
Devops/CI系统开发
产品开发人员
建立完善的资源调度和代码执行平台,完善研发环境 方便业务产品开发人员搭建灵活的调试环境,定义并运行自己的测试

当然,也不是说在当今Devops发展的时代,测试开发就没有作用了。翻开Google/微软/Amazon等公司的招聘网站,对Test Automation/STE等岗位的需求仍然存在。哪怕是强调测试左移,由开发人员编写大量单元测试,但仍然有不少e2e test或者integration test是处于灰色地带,因为种种原因难以要求开发人员负责(通常对于e2e/ui test,对产品开发人员的要求是能写就写,不能写不强求),因此仍然对偏传统的QA/STE等等人员有一定需求。既然QA还有市场,那么为QA服务,对QA开发工具的SDET/测试开发自然也有需要—只是这些岗位,无论是QA还是SDET,随着Devops的完善,其作用也越来越小(直到完全外包)。

正如在Software Engineering at Google一书中所提到的:80%的测试是单元测试,由产品开发者完成,不间断运行在基础架构团队提供的Devops平台上。剩下的20%,少部分由开发者编写(如果能自动化),其它不能完全自动化的仍然需要传统的Test Engineer(QA)来手工执行,在执行过程中可以借助一些工具帮助,那么这些工具也许仍然是有专门的测试开发来做,也许就让QA自己完成(这其实是个很有趣的问题,在 https://learnseleniumtesting.com/dark-side-software-development-engineer-test-sdet/ 一文中有提到,测试开发不可避免地将同时负责QA工作,或者深度介入QA工作)。但无论如何,对QA提供什么样的测试工具来提供帮助,对于现代Devops平台来说,都不再是主要目标。

QA,已经成了一个外包的必然领域,我们不必去纠结。而测试开发在Devops、测试左移的趋势中何去何从,这则是另一个话题,我们在以后的文章中将再进行讨论。


Software Development(软件开发)是面向程序员和开发工程师的,而Software Engineering(软件工程)则是技术研发和工程管理的结合体,也是当前国内互联网企业在走向工业化转型阶段所需要跨越的难关。

特别声明:以上文章内容仅代表作者本人观点,不代表FAENWSI观点或立场。如有关于作品内容、版权或其它问题请于作品发表后的30日内与FAENWSI联系。
must
版权声明:本站原创文章,由 must2022-06-10发表,共计7057字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(没有评论)