写点什么

Docker 引领测试革新

  • 2017-02-22
  • 本文字数:4892 字

    阅读完需:约 16 分钟

随着 Docker 技术被越来越多的人所认可,其应用的范围也越来越广泛。本文将从测试类型、Devops、自动化测试、测试场景、测试实践等方面介绍 Docker 对软件测试技术的影响。我假设读者在看这篇文章时已经对 Docker 和其所依赖的核心技术有了一定的了解。如果读者还不了解,可以先阅读《深入浅出Docker(一):Docker 核心技术预览》这篇文章。

1. 传统软件开发流程的痛点

在传统软件开发流程中,开发团队在完成功能代码编写后,会首先进行自测,之后将代码提交到 Git 仓库中。在每一次迭代转测试时,开发团队会首先构建转测试的二进制文件,之后由测试团队对版本进行验证,验证通过后会将版本提交给运维团队。之后再由运维团队将产品发布件部署到运维服务器中以提供给客户使用。

在这个流程中会有如下痛点:

(1) 开发、测试和运维环境不统一。

这导致了有些本该在开发阶段发现的软件缺陷可能会遗漏到测试或运维阶段才能发现。有时发布件在开发环境中运行的很稳定,而在运维环境中刚刚运行就挂掉了。这时运维团队不得不找开发团队来救火,导致了整个团队工作效率下降。

(2) 无法准确获取客户的软件环境。

我们往往不能直接复现客户报的软件缺陷,不得不去客户现场进行调试,滞后了解决问题的时间。

(3) 开发者在提交代码前往往未做充分的测试。

开发自验工作取决于开发者的责任心,而没有一种机制来保证自验工作的进行。导致了很多低级的软件缺陷遗漏到测试和运维团队。

(4) 开发团队无法复现测试团队报出的软件缺陷,导致两个团队出现相互推诿的现象。

(5) 配置测试环境的时间较长,测试自动化成本高。

传统环境往往使用虚拟机,而其消耗资源高、部署速度慢,导致自动化的效率不高。

2. 当前测试技术面临的挑战

主要的挑战如下所示:

(1) 配置一致的测试环境。

(2) 快速部署软件。

(3) 并行执行测试,在并行的同时还需确保测试任务各自的环境不被污染。

(4) 成功的复现软件缺陷。

(5) 创建清洁的测试环境。

(6) 正确配置测试工具。同一个工具需要适配到不同的 linux 发行版中。

(7) 快速部署多个测试主机。

(8) 快速导入测试数据。

(9) 快速清理测试环境。

(10) 快速保留、复制、恢复测试环境。

3.Docker 对测试技术的革命性影响

(1) 更早的发现单元测试中的软件缺陷。

测试驱动开发是软件工程中一个具有里程碑意义的创新,即开发者在提交开发代码的同时也要提供对应的测试代码,在代码提交后系统会自动进行一轮自动化测试。通过 Docker 可以快速部署测试环境,可以有力的支撑自动化测试,从而确保在第一时间发现单元测试中的软件缺陷。

(2) 为功能测试和集成测试提供清洁的测试环境。

很多公司由于成本问题,不得不在一个虚拟机中运行不同类型的测试任务。而这些任务在运行时往往会导致环境污染。通过 Docker 技术的隔离性,可以有效地解决测试环境的污染问题。

(3) 让测试团队和客户丢掉冗长的配置文档。

开发转测试时往往带有较长的环境部署文档,而在这些文档中往往存在部署过程跳步的问题,测试团队很难一次准确的将环境部署成功。而现在可以通过 Docker 镜像将配置环境的过程简化,测试团队省去了查阅文档的过程,只需要基于开发团队提供的 Docker 镜像就可以轻松的配置测试环境。

(4) 便于复现客户报告的软件缺陷。

当客户使用软件发现缺陷时,可以将其所使用的环境打包成镜像提供给开发团队。开发团队通过镜像即可获取与客户一致的软件环境。

(5) 通过 Dockerfile 可以梳理好测试镜像制作的流程。

如果流程步骤需要微调时 (如将安装 gcc3.4 改为安装 gcc4.3),可以将 Dockerfile 中对应的信息进行修改并重新创建新的镜像,不必手动重新配置运行环境。

(6) 可以将成熟的测试套或测试工具通过镜像共享。

这样可以支持软件在不同 linux 发行版中成功的运行,软件提供商可以将主要精力放在完善功能上,不必投入过多时间将软件适配到不同的 linux 发行版中。

(7) 利用 Docker 生态中的工具可以快速创建可伸缩的测试环境,大大减少了测试所消耗的时间。

可以在短时间内快速集中资源来完成一项测试任务,在任务完成后又可以快速的对资源 进行回收,有利于提升资源使用效率。

(8) 优越的性能指标。

通过优于虚拟机的性能,Docker 可以提升测试效率。通过“-v”选项可以将主机的目录快速映射到容器中,可以实现测试文件的快速共享。通过“–rm”选项可以在测试完成后第一时间删除容器,以便释放系统资源。

(9) 轻松的恢复测试环境(包括内存)-CRIU 技术 Checkpoint Restore In Userspace

结合 CRIU 技术,可以实现容器运行状态的保存,这项技术也是容器热迁移的基础。

4.DevOps 与 Docker

DevOps 一词的来自于 Development 和 Operations 的组合,突出重视软件开发人员和运维人员的沟通合作,通过自动化流程来使得软件构建、测试、发布更加快捷、频繁和可靠。

在 DevOps 出现之前,软件经过开发、测试后由运维团队将发布件部署到公司的基础设施上,并将服务提供给客户使用。然而,开发、测试、运维三个团队缺少有效协同工作的机制,导致部门墙严重。开发团队往往关注新功能开发和快速迭代,而运维团队关注的是发布件的稳定性,他们不希望版本频繁的更替。往往在这两个团队间会爆发激烈的斗争。

在 DevOps 出现之后,团队通过协作和自动化的方式打通了开发、测试、运维团队之间的壁垒。当有新的代码提交时,系统在第一时间会触发自动化测试,依次在开发自验环境、测试环境、运维环境中验证软件,确保可以第一时间发现软件缺陷。然而,当出现业务峰值时,传统的基础设施中的虚拟机就无法有效的应对了。

在后 Devops 时代,随着云计算的普及,很多云平台提供了应用引擎,如果你的应用符合引擎的规范,云平台就可以自动检测业务负载量。当业务出现峰值时,平台可以利用底层容器技术的快速部署、资源快速扩展伸缩等特性来应对,从而有效的支撑了业务的正常运行。

5.Docker 与自动化测试

对于重复枯燥的手动测试任务,可以考虑将其进行自动化改造。自动化的成本在于自动化程序的编写和维护,而收益在于节省了手动执行用例的时间。简而言之,如果收益大于成本,测试任务就有价值自动化,否则受益的只是测试人员的自动化技能得到了提升。利用 Docker 的快速部署、环境共享等特性,可以大大减少自动化的成本,使很多原本没有价值自动化的测试任务变为了有价值自动化的任务,大大提升了项目效率。

那么如果自动化测试已经运行在了虚拟机中,是否有必要使用 Docker 技术将其进行改造?这个就要具体问题具体分析了。笔者并不赞同将所有测试任务一刀切的进行容器化改造。如果当前虚拟机已经满足测试需求,你就需要评估一下引入 Docker 进行改造所需的成本,其中包含学习 Docker 技术所需要的时间成本。反之,如果虚拟机无法满足当前的测试需求,可以考虑尽快引入 Docker 进行改造。

6.Docker 的约束

Build, Ship, and Run Any App, Anywhere. 这是 Docker 公司高调宣称的口号,即在任何平台都可以构建、部署、运行任何应用。然而,由于 Docker 自身的特点,其使用场景有一些约束:

(1) 因为容器与主机共享内核,如果容器中应用需要不同的内核版本,就不得不更换主机内核。但如果主机内核变更后又会影响到其它容器的运行。变通的方法是将应用源码的编写与内核特性解耦。

(2)Docker 使用时需要 3.10 或以上版本的内核,这是最低的限制。如果你需要使用更高级的 Docker 特性,如 user namespace,那么还需要更高版本的内核。

(3) 使用“–privileged”选项后可以在容器内加载或卸载内核模块,但这个操作会影响到主机和其它容器。

(4) 无法模拟不同平台的运行环境,例如不能在 x86 系统中启动 arm64 的容器。

(5) 因为 Docker 采用了 namespace 的方案来实现隔离,而这种隔离属于软件隔离,安全性不高。不适合安全性高的测试任务。

(6) 因为目前没有 time namespace 技术,修改某个容器时间时就不得不影响到主机和其它容器。

7. 适用于 Docker 的测试场景

由于容器与主机共享内核使用,凡是和内核无强相关的测试任务是适合引入 Docker 进行改造的,例如源码编译测试、软件安装测试、互联网应用测试、数据库测试等。而与内核强相关的测试任务是不适合使用 Docker 进行改造的,如内核网络模块测试、内核 namespace 特性测试等。

8.Docker 测试实践

8.1. 容器化编译系统测试

早期我们将 linux 发行版安装到物理机中进行测试。当需要重新进行全量测试时不得不手动还原测试环境。之后改用了虚拟机,虽然能够通过自动化的方式实现环境还原,但虚拟机的损耗较大,效率不高。

之后我们尝试将环境制作成 Docker 镜像,同时进行了如下的改进:

(1) 通过 Docker 的“-v”选项,将主机目录映射到容器中,实现多个容器共享测试代码。测试代码部署时间从 2 分钟减少到 10 秒。

(2) 将大粒度的执行时间较长的用例拆分成为若干个小用例。

(3) 利用容器并发执行测试。

(4) 使用 Dockerfile 梳理产品依赖包和编译软件的安装。

编译系统测试是用户态的测试,非常适合使用 Docker 进行加速。如果需要针对某一个 linux 发行版进行测试,可以通过 Docker 快速部署的特点,将所有的资源快速利用起来,从而达到加速测试执行的目的。

8.2.linux 外围包测试

外围包包含动态链接库文件和常用的命令行工具,属于 linux 操作系统的中间层,其上运行着应用程序,其下由 linux 内核支撑。起初的外围包测试采用串行执行,效率不高。同时受到环境污染的影响,容易产生软件缺陷的误报。在改进方面,我们首先通过 Dockerfile 基于 rootfs 制作一个 Docker 镜像,然后通过 Docker-compose 工具实现测试用例的并发执行。

以下是改进前后的对比。

改进前

改进后

每套环境独占一台主机,主机利用率不高。 多套环境可以在同一主机上部署,可以更有效利用主机资源。特别是在主机资源昂贵的情况下,可以节省很多成本。 测试串行执行,因为环境污染问题测试任务不易并发。 通过 Docker 进行测试任务隔离,可以并行执行测试,提高了 cpu 利用率。 环境释放时清理工作依赖于程序员的技能。在每个测试用例中有一个 cleanup 函数,负责资源回收和环境恢复。如果程序员编程技巧不高的话,可能会造成资源回收不彻底,测试环境会受到污染。 环境释放时清理工作由 Docker 接管,当执行完任务后,可以删除容器。即使不写 cleanup 函数,也可以实现资源的回收。 无法解决多个外围包的环境污染问题。当连续执行多个测试时,有部分测试无法通过,而单独执行这些测试时又能够通过。这通常是由于测试环境污染造成的。 容器可快速启动与关闭,每次都是清洁的环境。 外围包编译环境不易统一,导致测试结果不一致。 通过镜像保存编译环境,确保环境统一。 测试网络包时需要至少两台主机,分别部署服务端和客户端。 测试网络包时只需要在同一台主机中启动两个容器来部署服务端和客户端。## 9. 通过 Docker 进行测试加速的原理

Docker 本身并不会直接加速测试执行。在串行执行测试时,在容器中执行测试反而会带来约 5% 左右的性能衰减。但我们可以充分利用 Docker 快速部署、环境共享等特性,同时配合容器云来快速提供所需的测试资源,以应对测试任务的峰值。如果忽略环境部署时间,当每个测试用例粒度无限小并且提供的测试资源无限多时,测试执行所需的时间也就无限小。

10. 总结

很多测试任务可以利用 Docker 进行改造,读者可以根据项目自身的特点,因地制宜的使用 Docker 进行测试能力的改造。如果想进一步了解容器云,可以参考《网易云的实践之路:谈谈容器云的机会与挑战》这篇文章。

作者简介

孙远,华为中央软件研究院资深工程师,硕士毕业,9 年软件行业经验。目前在华为从事容器Docker 项目的测试工作。工作涉及到功能测试、性能测试、压力测试、稳定性测试、安全测试、测试管理、工程能力构建等内容。参与编写了《Docker 进阶与实战》的Docker 测试章节。先前曾经就职于美国风河系统公司,作为team lead 从事风河Linux 产品测试工作。活跃于Docker 社区和内核测试ltp 社区,目前有大量测试用例被开源社区接收。

研究方向:容器技术、Docker、Linux 内核、软件测试、自动化测试、测试过程改进


感谢木环对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ @丁晓昀),微信(微信号: InfoQChina )关注我们。

2017-02-22 16:348086

评论

发布
暂无评论
发现更多内容

知识也会生宝宝?

史方远

个人成长 随笔杂谈

# LeetCode 215. Kth Largest Element in an Array

liu_liu

算法 LeetCode

Python 自动化办公之"你还在手动操作“文件”或“文件夹”吗?"

JackTian

Python 自动化

互联网时代的界限管理

非著名程序员

程序员 职场 提升认知 界限管理

数据产品经理实战-数据门户搭建(上)

第519区

数据中台 开发数据

你不知道的SSD那些事

焱融科技

分布式 存储 SSD nvme

从 0 到 1 搭建技术中台之发布系统实践:集泳道、灰度、四端和多区域于一体的设计与权衡

伴鱼技术团队

架构 系统设计 系统架构 系统性思考 架构设计

程序员修炼的务实哲学

博文视点Broadview

程序员 软件 编程思维 工程师 编程之路

线程池续:你必须要知道的线程池submit()实现原理之FutureTask!

一枝花算不算浪漫

源码分析 并发编程

每个人都是领导者的工程团队

hongfei

工程能力 项目实践

ARTS - Week Two

shepherd

js algorithm

【Java 25周年有奖征文获奖名单公布!!!】关于Java,你最想赞扬、吐槽、期待的变化是什么?

InfoQ写作社区官方

写作平台 Java25周年 热门活动

原创 | 使用JUnit、AssertJ和Mockito编写单元测试和实践TDD (十三)编写测试-生命周期方法

编程道与术

Java 编程 TDD 单元测试 JUnit

美团可能会强势涉足 ToB

罗小布

创业 互联网巨头 深度思考 互联网

奈学:传授“带权重的负载均衡实现算法”独家设计思路

奈学教育

分布式

patroni 通过服务启动报错

hobson

数据库 高可用 AntDB

情绪的力量:如何使用情绪来达成目标

董一凡

情绪

这是一个测试文档

Geek_073cad

Vue生态篇(二)

shirley

Vue

杂谈-JSONP探索

卡尔

Java jsonp

我为什么开始技术写作?

架构精进之路

技术创作

# LeetCode 863. All Nodes Distance K in Binary Tree

liu_liu

算法 LeetCode

Redis持久化了解一波!

不才陈某

redis 程序员 后端

我常用的浏览器插件

彭宏豪95

chrome 效率工具 浏览器 插件

一个人,沿着童年的路究竟可以走多远?

zhoo299

童年 NASA 航天

我的 Windows 利器

玄兴梦影

工具 Win

Vue生态篇(一)

shirley

Java Vue

开源分布式文件系统大检阅

焱融科技

开源 sds 存储 焱融科技 文件存储

MySQL的各种日志

超超不会飞

MySQL

Go语言分布式系统配置治理

田晓亮

微服务

ARTS 第二周打卡

陈文昕

Docker引领测试革新_软件工程_孙远_InfoQ精选文章