javascript – 摩卡:以编程方式创建和确定测试

我想要在其他环境中实时运行代理测试结果.

这里是一些伪代码,我想要真正的:

  var test = proxy.getCurrentTest(); 
  // => {slow: 200, timeout: 2000, duration: 235, result: 'error'};

  var tmpIt = it('test1', function(){
      this.slow(test.slow);
      this.timeout(test.timeout);
  });
  tmpIt.close({
      duration: test.duration,
      result: test.result
  });
  // this should make this test red in the output, 
  // because the `result` is not 'success'

无论如何可以设置测试的结果和持续时间,而不“真的”运行它?并将所有可视摩卡输出到终端?

编辑:这个问题不是关于如何将变量与子进程的测试结果传递给主进程.它已经为我工作了.

最佳答案
希望我的理解正确.我实现的是一个测试结果转发到摩卡车,摩卡车.

要与mocha集成,该实现描述了一个custom mocha interface,用于通过在另一个环境中执行的测试来代理测试结果.

要使用此界面,在运行摩卡时,必须将-u参数传递给mocha

> mocha -u ./path/to/proxy-interface ...

请注意./path/to/proxy-interface是mocha在require调用中需要使用接口模块的路径.

代理接口负责将proxyTest函数暴露给全局上下文,例如摩卡的BDD接口,它会调用传递的函数来获取测试结果并转发测试结果,同时保留测试运行程序显示的测试次数.

var Mocha = require('mocha');

var Suite = Mocha.Suite;
var Test = Mocha.Test;
var escapeRe = require('escape-string-regexp');

module.exports = function(suite) {
  var suites = [suite];

  suite.on('pre-require', function(context, file, mocha) {
    // A bit hacky since we require mocha internal common interface module
    var common = require('mocha/lib/interfaces/common')(suites, context);

    context.run = mocha.options.delay && common.runWithSuite(suite);

    context.proxyTest = function(title, fn) {
      var suite = suites[0];
      if (suite.pending) {
        fn = null;
      }
      var test = new ProxyTest(title, fn);
      test.file = file;
      suite.addTest(test);
      return test;
    };
  });
};

var Runnable = Mocha.Runnable;
var inherits = require('util').inherits;

function ProxyTest(title, fn) {
  Runnable.call(this, title, null);
  this.pending = !fn;
  this.type = 'test';
  this.body = (fn || '').toString();

  this.fn = fn;
}

inherits(ProxyTest, Runnable);

ProxyTest.prototype.run = function(done) {
  var proxiedTestResult = this.fn();

  this.duration = proxiedTestResult.duration;
  this.timedOut = this.timeout() > proxiedTestResult.timeout;

  done(proxiedTestResult.result);
};

ProxyTest.prototype.clone = function() {
  var test = new ProxyTest(this.title, this.fn);
  test.timeout(this.timeout());
  test.slow(this.slow());
  test.enableTimeouts(this.enableTimeouts());
  test.retries(this.retries());
  test.currentRetry(this.currentRetry());
  test.globals(this.globals());
  test.parent = this.parent;
  test.file = this.file;
  test.ctx = this.ctx;
  return test;
};

上面的代码覆盖了摩卡的Runnable运行实现,并运行传递的函数来获取测试结果,并将ProxyTest界面中必需的字段设置为与摩卡测试兼容.

用法

在您的测试中,使用proxyTest全局注册一个新的测试与摩卡

var proxy = {
  getErrorTestResult() {
    return {slow: 200, timeout: 2000, duration: 50, result: 'error'};
  },

  getTimeoutTestResult() {
    return {slow: 200, timeout: 2000, duration: 3000 };
  },

  getSlowTestResult() {
    return {slow: 200, timeout: 2000, duration: 235 };
  },

  getSuccessTestResult() {
    return {slow: 200, timeout: 2000, duration: 50 };
  }
}

proxyTest('error', proxy.getErrorTestResult);
proxyTest('timeout', proxy.getTimeoutTestResult);
proxyTest('slow', proxy.getSlowTestResult);
proxyTest('success', proxy.getSuccessTestResult);

产量

Mocha Output

启示

这种方法的缺点是必须将自定义界面传递给摩卡,并且您不能使用摩卡BDD词汇,如描述.如果您“延长”(在这种情况下:复制一些代码),可以消除第二个缺点:摩卡的BDD接口:

var Mocha = require('mocha');
/**
 * Module dependencies.
 */

var Suite = Mocha.Suite;
var Test = Mocha.Test;
var escapeRe = require('escape-string-regexp');

/**
 * BDD-style interface - extended with proxy functionality:
 *
 *      describe('Array', function() {
 *        describe('#indexOf()', function() {
 *          it('should return -1 when not present', function() {
 *            // ...
 *          });
 *
 *          it('should return the index when present', function() {
 *            // ...
 *          });
 *        });
 *      });
 *
 * @param {Suite} suite Root suite.
 */
module.exports = function(suite) {
  var suites = [suite];

  suite.on('pre-require', function(context, file, mocha) {
    // A bit hacky since we require mocha internal common interface module
    var common = require('mocha/lib/interfaces/common')(suites, context);

    context.before = common.before;
    context.after = common.after;
    context.beforeEach = common.beforeEach;
    context.afterEach = common.afterEach;
    context.run = mocha.options.delay && common.runWithSuite(suite);
    /**
     * Describe a "suite" with the given `title`
     * and callback `fn` containing nested suites
     * and/or tests.
     */

    context.describe = context.context = function(title, fn) {
      var suite = Suite.create(suites[0], title);
      suite.file = file;
      suites.unshift(suite);
      fn.call(suite);
      suites.shift();
      return suite;
    };

    /**
     * Pending describe.
     */

    context.xdescribe = context.xcontext = context.describe.skip = function(title, fn) {
      var suite = Suite.create(suites[0], title);
      suite.pending = true;
      suites.unshift(suite);
      fn.call(suite);
      suites.shift();
    };

    /**
     * Exclusive suite.
     */

    context.describe.only = function(title, fn) {
      var suite = context.describe(title, fn);
      mocha.grep(suite.fullTitle());
      return suite;
    };

    /**
     * Describe a specification or test-case
     * with the given `title` and callback `fn`
     * acting as a thunk.
     */

    var it = context.it = context.specify = function(title, fn) {
      var suite = suites[0];
      if (suite.pending) {
        fn = null;
      }
      var test = new Test(title, fn);
      test.file = file;
      suite.addTest(test);
      return test;
    };

    /**
     * Exclusive test-case.
     */

    context.it.only = function(title, fn) {
      var test = it(title, fn);
      var reString = '^' + escapeRe(test.fullTitle()) + '$';
      mocha.grep(new RegExp(reString));
      return test;
    };

    /**
     * Pending test case.
     */

    context.xit = context.xspecify = context.it.skip = function(title) {
      context.it(title);
    };

    /**
     * Number of attempts to retry.
     */
    context.it.retries = function(n) {
      context.retries(n);
    };

    context.proxyTest = function(title, fn) {
      var suite = suites[0];
      if (suite.pending) {
        fn = null;
      }
      var test = new ProxyTest(title, fn);
      test.file = file;
      suite.addTest(test);
      return test;
    };
  });
};

var Runnable = Mocha.Runnable;
var inherits = require('util').inherits;

function ProxyTest(title, fn) {
  Runnable.call(this, title, null);
  this.pending = !fn;
  this.type = 'test';
  this.body = (fn || '').toString();

  this.fn = fn;
}

inherits(ProxyTest, Runnable);

ProxyTest.prototype.run = function(done) {
  var proxiedTestResult = this.fn();

  this.duration = proxiedTestResult.duration;
  this.timedOut = this.timeout() > proxiedTestResult.timeout;

  done(proxiedTestResult.result);
};

ProxyTest.prototype.clone = function() {
  var test = new ProxyTest(this.title, this.fn);
  test.timeout(this.timeout());
  test.slow(this.slow());
  test.enableTimeouts(this.enableTimeouts());
  test.retries(this.retries());
  test.currentRetry(this.currentRetry());
  test.globals(this.globals());
  test.parent = this.parent;
  test.file = this.file;
  test.ctx = this.ctx;
  return test;
};

转载注明原文:javascript – 摩卡:以编程方式创建和确定测试 - 代码日志