在 Cucumber 中,回调函数虽然被调用但超时。已经增加默认超时但仍然错误

In Cucumber, callback function getting timedout though callback is called. Already increased DefaultTimeout but still error

下面是 Cucumber Given Step 定义,在这个 callback() 函数中成功命中并且能够看到控制台行,即 "This is a callback function"

const assert = require('assert')
const {
 Before,
 Given,
 When,
 Then
} = require('cucumber');

var {
 setDefaultTimeout
} = require('cucumber');

setDefaultTimeout(6 * 1000);


Given('This has only one word {string}', function (string, callback) {
 console.log(string);

 function callback() {}
 callback();
});

但是这一步没有终止,抛出错误"function timed out, ensure the callback is executed within 6000 milliseconds"

C:\Users\Mohit.Garg\Desktop\Cucumber practice\example5>protractor conf.js
[17:14:55] I/launcher - Running 1 instances of WebDriver
[17:14:55] I/local - Starting selenium standalone server...
[17:14:57] I/local - Selenium standalone server started at http://10.200.3.79:55733/wd/hub
(node:27784) [DEP0005] DeprecationWarning: Buffer() is deprecated due to security and usability issues. Please use the Buffer.alloc(), Buffer.allocUnsafe(), or Buffer.from() methods instead.
Feature: Login

  Scenario: Login
    Given This has only one word "hi"
This is a callback function
    × failed
      Error: function timed out, ensure the callback is executed within 6000 milliseconds
          at Timeout._onTimeout (C:\Users\Mohit.Garg\Desktop\Cucumber practice\example5\node_modules\cucumber\src\user_code_runner.js:61:18)
          at ontimeout (timers.js:436:11)
          at tryOnTimeout (timers.js:300:5)
          at listOnTimeout (timers.js:263:5)
          at Timer.processTimers (timers.js:223:10)

我认为这与 DefaultTimeout 无关,因为如果我使用以下具有相同超时值的代码,它会完美运行。我用不同的名称 "newcallback" 替换了 Given 中的 "callback" 并在最后调用了内部回调函数。见下文

Given('This has only one word {string}', function (string, newcallback) {
 console.log(string);

 function callback() {
  newcallback()
 }
 callback();
});

我希望我的问题很清楚,非常感谢您的帮助。

1)当step函数内部没有Async代码时,不需要使用callback参数。

Then(/^the response status is (.*)$/, function (status) {
  // Synchronous code
  assert.equal(this.responseStatus, status)
});

2) 但是如果step函数里面有任何Async代码,你需要使用callback参数或者return一个promise。

例如:

Given('This has only one word {string}', function (string, callback) {
   // the `callback` is specified by argument: callback

   ... do other things
   // when step done invoke the `callback`
   callback()
}

Given('This has only one word {string}', function (string, abc) {
   // the `callback` is specified by argument: abc

   ... do other things
   // when step done invoke the `callback`
   abc()
}

Given('This has only {amount} word {string}', function (amount, string, xyz) {
   // the `callback` is specified by argument: xyz

   ... do other things
   // when step done invoke the `callback`
   xyz()
}

重要:Cucumber 会将函数的最后一个参数作为 callback,无论您将参数名称指定给任何字符串。

// Asynchronous - callback
// Take a callback as an additional argument to execute when the step is done
Then(/^the file named (.*) is empty$/, function (fileName, callback) {

  fs.readFile(fileName, 'utf8', function(error, contents) {
    if (error) {
      callback(error);
    } else {
      assert.equal(contents, '');
      callback();
    }
  });
});

// Asynchronous - promise
// Return a promise. The step is done when the promise resolves or rejects
When(/^I view my profile$/, function () {
  // Assuming this.driver is a selenium webdriver
  return this.driver.findElement({css: '.profile-link'}).then(function(element) {
    return element.click();
  });
});

返回您的代码:

Given('This has only one word {string}', function (string, callback) {
    console.log(string);
    // the `callback` specified by argument: callback   

    function callback() {} 
    // you define a function, named 'callback' too, which overwrite the
    // real `callback`

    callback();
    // you invoked the function you defined, not the real `callback`,
    // so cucumber wait the real `callback` be invoked, until reach
    // the timeout, then report timeout exception. 
});