使用Docker跨Node.js版本测试

杆Vagg
分享

问题:测试

是一个旨在帮助构建原生(c++) Node.js插件的项目,同时保持与Node和V8的兼容性,从Node版本0.8起。V8正在进行中主要内部变化使得附加组件的开发非常困难。NAN的目的是抽象这种痛苦。而不是必须保持你的代码在Node/V8版本之间的兼容性,NAN为你做这件事,这不是一个简单的任务。这意味着我们必须确保对NAN进行测试并与之兼容所有它声称支持的版本。这不是一个简单的练习!

特拉维斯CI我能帮上点忙。这是可以使用的nvm可以测试不同版本的Node.js,甚至超出官方支持的版本。我们已经在NAN上尝试过了,但没有取得很大的成功。理想情况下,您应该有更好的Node版本选择,但Travis已经有了一些困难保持。此外,由于npm安装问题,旧版本Node.js附带的历史npm错误往往会导致很高的失败率。出于这个原因,我们甚至没有在NAN README上发布Travis徽章,因为它根本不起作用。

特拉维斯的另一个问题是CI解,不是一个合适的测试解决方案。即使它工作得很好,它在开发过程中也没有多大帮助,因为你需要快速反馈你的代码在目标平台上工作(这就是为什么我更喜欢后端开发而不是前端开发的原因之一!)

解决方案:Docker

输入码头工人而且二硝基酚.Docker是一个工具,它简化了Linux容器的使用,以创建轻量级、隔离的计算“实例”。Solaris及其变体多年前就以“zone”的形式实现了这一功能,但对于Linux来说,这是一个相对较新的概念,Docker使整个过程更加友好。Dockers的相对简单性意味着最近几个月在Linux容器领域有了惊人的活动,它几乎在一夜之间成为了一个巨大的生态系统。

DNT: Docker节点测试器

Docker Node Test,或DNT,是一个非常简单的实用程序,包含两个用于使用Docker和Node.js的工具。一个工具帮助设置用于测试的容器,另一个工具在这些容器中运行项目的测试。

DNT包括setup-dnt脚本,它设置运行Node.js应用程序所需的最基本的Docker映像,没有其他东西。它首先创建一个名为dev_base它使用默认的Docker“ubuntu”镜像,并添加编译和安装Node.js所需的构建工具

接下来它创建了一个node_dev包含Node.js的完整副本的映像源库.最后,它将创建要运行的测试所需的一系列映像。对于每个Node版本,它都会创建一个安装了Node并可以使用的映像。

建立一个项目就是创建一个.dntrc文件在项目的根目录。该配置文件设置一个NODE_VERSIONS变量,其中包含要测试的所有Node版本的列表。该列表可以包括“master”,用于测试Node存储库中的最新代码。你还设置了TEST_CMD变量,其中包含设置、编译和执行测试所需的一系列命令。的setup-dnt命令可以针对.dntrc文件,以确保适当的Docker映像已经准备好。的二硝基酚命令可用于对指定的所有Node版本执行测试。

由于Docker容器是完全隔离的,因此只要机器有资源,DNT就可以并行运行测试。默认情况下,使用计算机上的核数作为并发级别,但如果不适合要运行的测试类型,则可以配置此选项。

还可以自定义基本测试映像,以包括项目所需的其他外部工具和库,尽管这是设置过程中的手动步骤。

目前DNT被设计为通过将最后一行读取为“ok”或“not ok”来解析TAP测试输出,从而在命令行上报告测试状态。它是可配置的,但是您需要提供一个命令,将测试输出转换为“ok”或“not ok”(sed拯救?)Mocha TAP报告器的非标准输出也得到开箱即用的支持。

当前使用的

我的主要用例是测试NAN。能够在编码时针对所有不同的V8和Node api进行测试是非常有用的,特别是当测试运行得非常快的时候!我的奶奶.dntrc针对master的文件测试,0.11.4以来的许多0.11版本(0.11.0到0.11.3明显不受NAN支持,0.11.11和0.11.12完全不支持本机插件),以及0.10和0.8系列的最后五个版本。目前,Node总共有18个版本,在我的计算机上,测试套件大约需要20秒才能完成所有这些版本。的南.dntrc文件如下所示。

NODE_VERSIONS="\ master \ v0.11.10 \ v0.11.9 \ v0.11.8 \ v0.11.7 \ v0.11.6 \ v0.11.5 \ v0.11.4 \ v0.10.26 \ v0.10.25 \ v0.10.24 \ v0.10.23 \ v0.10.22 \ v0.8.26 \ v0.8.25 \ v0.8.24 \ v0.8.23 \ v0.8.22 \ TEST_CMD="\ cd /dnt/test/ && \ npm install && \ node_modules/.bin/node-gyp——nodedir /usr/src/node/ rebuild && \ node_modules/.bin/tap js/*-test.js;\”

接下来,我进行配置LevelDOWN二硝基酚。LevelDOWN是一个原始的c++绑定,它将LevelDB暴露给Node.js。它的主要用途是用于后台项目.需求要简单得多,因为测试只需要进行编译并运行大量的节点点击测试。的LevelDOWN.dntrc如下面的代码示例所示。

NODE_VERSIONS="\ master \ v0.11.10 \ v0.11.9 \ v0.10.26 \ v0.10.25 \ v0.8.26 \ " OUTPUT_PREFIX="leveldown-" TEST_CMD="\ cd /dnt/ && \ npm install && \ node_modules/.bin/node-gyp——nodedir /usr/src/node/ rebuild && \ node_modules/.bin/tap test/*-test.js;\”

我用DNT设置的另一个本地Node附加组件是我的libssh Node.js绑定.这个稍微复杂一些,因为在编译之前需要安装一些非标准库。我的.dntrc增加一些额外的apt-get获取并安装这些包。这意味着测试要花更长的时间,但这并不是禁止的。一种替代方法是配置node_dev将这些包添加到我的所有版本化映像。的node-libssh.dntrc如下所示。

NODE_VERSIONS="master v0.11.10 v0.10.26" OUTPUT_PREFIX="libssh-" TEST_CMD="\ apt-get install -y libkrb5-dev libssl-dev && \ cd /dnt/ && \ npm install && \ node_modules/.bin/node-gyp——nodedir /usr/src/node/ rebuild——debug && \ node_modules/.bin/tap test/*-test.js;\”

项目它不是一个本地插件,但它使用LevelDOWN,这需要编译。对于我要删除的DNT配置node_modules leveldown /之前npm安装因此,对于每个新版本的Node,它都会被重新构建。的项目.dntrc如下所示:

NODE_VERSIONS="\ master \ v0.11.10 \ v0.11.9 \ v0.10.26 \ v0.10.25 \ v0.8.26 \ " OUTPUT_PREFIX="levelup-" TEST_CMD="\ cd /dnt/ && \ rm -rf node_modules/leveldown/ && \ npm install——nodedir=/usr/src/node && \ node_modules/.bin/tap test/*-test.js——stderr;\ #”

未来的工作

不难想象,这将构成本地CI系统以及通用测试工具的基础。速度之快甚至让人忍不住在每次git提交,甚至每次保存时都运行测试。已经,New RelicNode.js代理团队正在使用DNT的内部分支来进行非常复杂的工作,即针对许多版本的Node.js测试他们的代理,并结合各种通用服务器框架的测试。

我一直渴望有贡献者,如果你有特殊的需求和技能来实现新功能,那么我很乐意听到你的声音。我通常对我的开源项目非常开放,并且很乐意加入那些添加了有价值的东西的贡献者。

看到二硝基酚GitHub回购安装和详细的使用说明。

罗德是今年的演讲者之一网页方向代码将于5月1日和2日在墨尔本举行。使用折扣代码SITEPOINT获得最必威西盟体育网页登录低价格的网页方向代码门票!

Baidu