在IDE界有句话"JB出品,必属精品!"。 JetBrains以其高质量的IDE在广大程序员中赢得了口碑。那么我们不禁要问,JB的高质量工具究竟是如何开发测试出来的?
对这个问题虫虫和大家一样也倍感好奇,最近JB博客揭露了其TeamCity UI前端团队软件测试的做法给我们给出了些许端倪,见微知类,从此我们终于了解了其打造精品软件的方法那就是:"像造飞机一样开发软件"。
概述
开发精品软件不容易,就像建造飞机一样,需要有天才程序员、开发流水线和测试框架。如果这一切未能就绪,检查并不断检查确认之后,软件才能发布,飞机也才能起飞。
在JetBrains,采用和造飞机同样的理念来构建软件。严格的测试可帮助最终产品发布之前发现错误和问题。就像建造飞机一样,软件开发是一个包含多个阶段的过程。产品越大,步骤和模块就越多。为了确保的软件已准备就绪,每个模块都必须经过测试并与其他模块完美集成。
CI/CD流程可以帮助自动执行此过程。最重要的是,它们消除因为人为的粗心大意而导致的故障。
与人们通常的看法相反,测试在前端开发也非常重要。就像是一架飞机,它不仅需要飞行,而且还必须坐着舒适。此外,它的外观会大大影响飞机的飞行方式。软件的前端UI也一样,必须测试其可用性、交互性和功能。
UI测试不仅涉及单元测试。还有截屏、行为、可访问性、性能、安全性和感知测试。
测试系统和CI/CD可帮助我们专注于真正重要的事情。
问题分类
在JetBrains中,它可以在多个级别上运行,并且大多数都基于CI/CD。每个测试,每个部门,每个级别都在揭示和问题报告过程中发挥作用。下面一张图表,其中Y轴表示应用程序可能存在的问题数,图上的蓝条。在X轴上显示了过滤器,问题的种类。该图反映了不同的层如何影响问题数量。
捕获的大量UI问题都属于截屏测试阶段。少部分的问题属于Linters/Unit/Render测试。当然这并不意味着这些测试就没有意义。相反,这意味着在这些领域开展了足够的工作以防止大量问题。
此处的显示关键点:质量保证部门仅面临三分之一的问题。通过使用CI/CD,可以帮助节省检查容易预测的问题的时间,这些问题可以由组织良好的测试系统发现。
当然该图表并非100%具代表性,并且发行版本之间也会变化很大,某个级别可以消除更多的问题。但是它也表明测试系统非常重要,即使单独的测试仅涵盖一种情况。
其次数量不等于质量:测试可能仅仅发现了唯一的一个错误,但是如果不引起重视,该唯一的错误可能会导致整个应用程序崩溃。
Linters, typings和单元测试
我们常说代码应该干净且一致,但这是有问题的。每个人对干净代码都有自己的理解。JetBrains内部有200多个规则,以确保其代码保持客观清晰。当Linters探测到一个问题时候,就会在IntelliJ Idea中发出告警。TypeScript,Flow,Kotlin或Reason的静态类型并不是多余的,对复杂应用程序来说是必需的。TeamCity团队使用了Flow,用于构建前端的第一个测试只是eslint/stylelint检查。其目的不光是查找代码样式问题,而且还包括变量丢失,import,non-cheap/safe操作(比如无依赖的React Hooks)等等方面问题。
当然,还有单元测试。单元测试很简单:编写纯原子函数,然后assert其输出。如果输出正常,TeamCity将其标记为绿色,并让CI管道继续执行。
截屏测试
在多个设备和平台上显示一致的UI是主要目标之一。团队需要在不使用浏览器的情况下,确保所有组件均正确显示,包括布局或视口大小。所以要测试如何以不同的配置直观显示组件。这就是截屏测试的主要工作。
其中一项更新之后,注释部分会添加到未授权代理列表中。没关系,这种测试可以揭示元素的消失。它不时就会发生,团队发现该测试非常有用。
测试步骤如下:
1. 启动呈现组件的服务器(在本例中为Storybook)。
2. 使用WebDriver API连接到服务器;API允许在没有真实用户的情况下以自动模式与网站进行交互。
3. WebDriver调用相关组件。
4. Yandex的实用工具Hermione使用WebDriver连接到Storybook,并在每个浏览器中获取所选区域的多个屏幕截图。
5. 然后将这些屏幕截图放到文件夹中,Hermione使用Mocha将其与默认屏幕截图进行比较。
6. 如果有什么变化,就发出通知。差异也以在可视化方式高亮显示。
React和渲染
通过减少不必要的渲染量可以提高接口的性能。对此, React非常擅长。但是,在某些情况下,需要注意:如果更改组件中的某些内容,React会创建一个新组件,而不是修改原始组件。
想象一下,将新的道具传递到组件中。为了节省重新渲染所需的资源,React检查所传递的道具是否与先前版本不同。如果它们相同,则不会进行任何重新渲染。然而,很多人可能会忘记在JavaScript中,两个数组或内容相同的对象是不同的实体(因为这些对象/数组将具有不同的引用)。结果,会导致不必要地对同样的组件进行了渲染。
为了解决此问题,可以对React Developer工具启用React Updates Highlighting。这样会显示应用中的所有重新渲染。例如,在光标移到趋势页面的组件上时会重新渲染。
但是如果真将这些添加应用程序将可能会触发一百次以上的渲染!
可以定使用why-did-you-render
(github/welldone-software/why-did-you-rendertests)检查冗余渲染。该组件帮助发现了很多效率低下的情况。具体步骤:
1. 创建了一个虚拟动作:它会触发对商店的更改。
2. 如果更改存储中的某些内容,将使所有组件(订阅此存储)再次收集数据。它发生在mapStateToProps回调中。
3. 收集数据后,将其传递给组件并启动比较功能以检查道具是否已更改。
4. 同时,虚拟动作实际上不会更改存储中的任何值,这样实际不会将新的道具传递给组件。
5. 如果新的道具导致组件重新渲染,就知道在不应该创建的地方创建了新的对象/数组。
为了解决这个问题的技巧,两个技巧:重新选择库和不变的数据结构。
重新选择库:
使用重新选择库,如果生成函数的所有参数都相同,则可以记住结果。如果传递的参数等于先前的参数,将不会收到新的对象,而会收到对旧对象的引用。不会进行任何重新渲染。
不变的数据结构:
可以通过冻结将对象或数组预定义为不可变的。下次,只要想返回一个预设值,就会返回该不可变对象。它保证了对该对象的引用始终是相同的,因此该组件不会被重新渲染。
快照测试
快照测试可验证是否对重要组件的结构进行了任何更改。拿飞机来类比。想象有一个飞机结构的快照:它有一个机身,一个机翼和四个喷气发动机。现在需要拆除其中一台喷气发动机,并用涡轮机代替。尽管这可能是个好主意,但它不再匹配快照。因此,就会收到通知。
如在上图中,变更是是主动的,有明显的后果。想象一下由数百个组件组成的飞机快照:跟踪所有交互非常困难。
JavaScript项目和这类似。对一个组件进行很小的更改可能会对整个项目的结构造成不良后果。可以通过创建快照来保护结构。每当打印错误,更改HTML类或添加新组件时,都会破坏结构。快照测试将通知是否这样做。
检查以下示例:
创建一个重要结构的快照,假定为IL-76LL引擎:
始终希望将未来的飞机与都会和前面的快照进行比较。
将发动机类型从涡轮风扇更改为涡轮螺旋桨发动机。只是为了测试它是如何工作的。由于新引擎不再匹配的快照,因此测试失败。将会创建一份报告,通知工程师检查该问题。
React组件与此相同:
E2E端测试
E2E测试与飞机试飞非常相似。与飞机一样,必须确保界面在现实世界中实际可用。由于成千上万的组件相互影响,永远无法在飞行员实际将飞机升空之前知道飞机是否可以起飞。
E2E测试旨在从头到尾测试应用程序流程。这些测试模拟了一个真实的用户,该用户一次又一次地通过相同的特定用例。
E2E测试流程如下:
1. 创建一个用户POV(用户故事)关键方案列表。
2. 为每个列出的方案创建一个自动化测试。
3. 这些测试中的每一个用例都描述Selenium应该如何与UI交互。
详细步骤描述:
打开浏览器。
登录。
转到第X页。
按下按钮Y。
确保显示窗口Z。
声明式描述:
"确保用户在转到页面X并开始过程Y之后获得窗口Z。"
4. 使用最后一个TeamCity实例启动Docker容器。
5. 启动测试;这些测试使用Selenium连接到Docker并执行算法。
其他测试
团队还实施了其他的一些测试,比如依赖安全审计(Dependencies Security Audit),可访问性测试,以及一些新测试类别也会陆续加入。
TeamCity和构建链
TeamCity使可以创建无限复杂的逻辑来启动测试和部署构建。这就是TeamCity如何显示其自己的UI的构建链/时间表的方式。
如图所见,TeamCity并行运行测试,因此,一些构建正在等待其他构建成功完成。而且,如果出现问题,则可能会中断整个流程,这只是为了防止浪费肯定会失败的测试资源。
下面是TeamCity如何可视化像大型项目的方式(以自己为例子):
重点是,TeamCity仅可以构建复杂的管道,而且可以良好地使它们复杂,复杂。例如,流水线的某些部分必须基于OS X代理构建,而某些则必须在Linux系统上构建,而其中的某些将要使用Amazon Cloud Agents构建。
结论
本文阐明了前端测试的基本原理和JB实践过程,包括Linters, typings,单元测试,截屏测试,React和渲染,快照测试,E2E端测试等一系列的自动化测试,像建造飞机一样,软件项目也是一项系统工程,需要严格的系统性流水线的自动测试来保证其质量,精品软件打造更是如此。