同时测试两个不同的npm包版本

时间:2017-11-22 04:22:07

标签: javascript node.js reactjs testing npm

当我创建一个npm包时,有时候它需要反向旧的依赖包版本。

如果新版本有新的api,我可以用这种模式编写代码:

import pkg from 'some-pkg';
const isNewVersion = pkg.newVersionApi !== 'undefined';

if (isNewversion) {
  pkg.newVersionApi();
} else {
  pkg.oldVersionApi(); // backward compatible api
}

使用这种模式,当我想编写测试时,我只能测试installed version代码。其他版本的代码无法测试。

例如,在React v15和v16中,React v16具有新的API Portal。在Portal发布之前,v15具有unstable_renderSubtreeIntoContainer api以实现类似功能。

所以React的代码就像:

import ReactDOM from 'react-dom';
const isV16 = ReactDOM.createPortal !== 'undefined';

if (isV16) {
  ReactDOM.createPortal(...);
} else {
  ReactDOM.unstable_renderSubtreeIntoContainer(...);
}

所以我想问一下是否有任何方法可以使用different dependency version进行测试?

目前,我想到的一种方法是再次安装另一个版本并进行测试。但它只能在当地做。它无法在ci上工作,也无法统计覆盖范围。

我认为这不仅仅是反应测试。它可能面向node.js测试。任何建议都可以讨论。

更新

这个问题可能与在npm中安装two versions dependency有关。但我知道目前安装两个版本依赖是不可行的。

4 个答案:

答案 0 :(得分:5)

这可能是一个解决方案,不确定它是否会按预期工作。但是,你将有一个向前发展的方向。

<强>的package.json

{
  "name": "express-demo",
  "version": "0.0.0",
  "private": true,
  "scripts": {
    "start": "node ./bin/www"
  },
  "dependencies": {
    "cookie-parser": "~1.4.3",
    "debug": "~2.6.3",
    "express": "~4.15.2",
    "jade": "~1.11.0",
    "morgan": "~1.8.1",
    "serve-favicon": "~2.4.2",
    "webpack": "^3.8.1",
    "webpack-dev-middleware": "^1.12.0",
    "webpack-hot-middleware": "^2.20.0"
  },
  "customDependecies": {
    "body-parser": [
      "",
      "1.18.1",
      "1.18.0"
    ]
  }
}

请注意上面的package.json文件,我添加了一个新密钥customDependecies,我将用它来安装多个依赖项。在这里,我使用body-parser包进行演示。接下来,您需要文件,可以阅读此key并安装deps。

安装-deps.js

const {spawnSync} = require('child_process');
const fs = require('fs');

const customDependencies = require('./package.json').customDependecies;

spawnSync('mkdir', ['./node_modules/.tmp']);

for (var dependency in customDependencies) {
  customDependencies[dependency].forEach((version) => {
    console.log(`Installing ${dependency}@${version}`);
    if (version) {
      spawnSync('npm', ['install', `${dependency}@${version}`]);
      spawnSync('mv', [`./node_modules/${dependency}`, `./node_modules/.tmp/${dependency}@${version}`]);
    } else {
      spawnSync('npm', ['install', `${dependency}`]);
      spawnSync('mv', [`./node_modules/${dependency}`, `./node_modules/.tmp/${dependency}`]);
    }
  });

  customDependencies[dependency].forEach((version) => {
    console.log(`Moving ${dependency}@${version}`);
    if (version) {
      spawnSync('mv', [`./node_modules/.tmp/${dependency}@${version}`, `./node_modules/${dependency}@${version}`]);
    } else {
      spawnSync('mv', [`./node_modules/.tmp/${dependency}`, `./node_modules/${dependency}`]);
    }
  });
}
spawnSync('rm', ['-rf', './node_modules/.tmp']);
console.log(`Installing Deps finished.`);

在这里,我在tmp文件夹中逐个安装deps,一旦安装,我将它们移动到./node_modules文件夹。

一旦安装了所有内容,您可以查看以下版本

<强> index.js

var bodyParser = require('body-parser/package.json');
var bodyParser1181 = require('body-parser@1.18.1/package.json');
var bodyParser1182 = require('body-parser@1.18.0/package.json');

console.log(bodyParser.version);
console.log(bodyParser1181.version);
console.log(bodyParser1182.version);

希望,这将符合您的目的。

答案 1 :(得分:0)

创建3个单独的项目(包含package.json的文件夹)和共享文件夹:

  1. 包含测试模块(my-test)的共享文件夹。导出函数以运行测试;
  2. 导入my-test和依赖项v1的客户端项目。导出在my-test
  3. 中调用测试函数的函数
  4. 导入my-test和依赖关系v2的客户端项目。导出在my-test
  5. 中调用测试函数的函数
  6. 导入两个客户端项目的主项目。运行每个导出的函数。

答案 2 :(得分:0)

您必须单独运行它们。为每个依赖项版本创建单独的项目文件夹。防爆。 React10,React11,React12。每个都有自己的package.json,为正确的版本指定。当您运行integration和/或versioned测试时,您将在每个版本上运行标准单元测试,但也可以将任何特定于版本的单元测试添加到该文件夹​​。

创建make文件可以让您在运行完整的测试套件时更轻松。如果这样做,您可以轻松地将其集成到CI中。

答案 3 :(得分:0)

除了其他建议之外,您还可以尝试 Testing multiple versions of a module dependency 中描述的方法。

以下是使用此方法针对多个 webpack 版本进行测试的示例:

npm install --save-dev module-alias
npm install --save-dev webpack-v4@npm:webpack@4.46.0
npm install --save-dev webpack-v5@npm:webpack@5.45.1

module-alias package 处理了在包版本之间切换的魔力,同时仍然支持正常的 require('webpack')(或任何您的模块)调用。

其他 install 将创建您的依赖项的两个版本,每个版本在您的本地 node_modules/ 中都有一个不同的目录名称。

然后,在您的测试代码中,您可以通过以下方式设置依赖项别名:

const path = require('path');
require('module-alias').addAlias(
  'webpack',
  path.resolve('node_modules', 'webpack-v4'),
);

// require('webpack') will now pull in webpack-v4

您会在不同的测试工具中为 'webpack-v5' 做同样的事情。

如果您的任何子依赖项在它们自己的代码中的任何位置都有硬编码的 require('webpack'),这将确保它们也拉入正确的 webpack 版本。