故事和动机:
我们有一个相当庞大的端到端Protractor测试代码库。有时,测试会等待实现特定修复 - 通常作为TDD方法的一部分,并演示如何重现问题以及预期的行为是什么。我们目前正在做的是使用Jasmine的pending()
里面有一个Jira问题编号。例如:
pending("Missing functionality (AP-1234)", function () {
// some testing is done here
});
现在,我们想知道何时可以将pending()
重命名为it()
并运行测试。或者,换句话说,当问题AP-1234
被解决或发送到测试时。
当前方法:
目前,我正在尝试使用custom ESLint
rule,jira
NodeJS module和Q
解决此问题。自定义ESLint
规则会搜索至少包含一个参数的pending()
个调用。以AP-
后跟4位数的格式提取故障单编号,并使用jira.findIssue()
检查其在Jira中的状态。如果状态为Resolved
- 报告错误。
这是我到目前为止所得到的:
"use strict";
var JiraApi = require("jira").JiraApi,
Q = require('q');
var jira = new JiraApi("https",
"jira.url.com",
"443",
"user",
"password",
"2");
module.exports = function (context) {
var jiraTicketRegex = /AP\-\d+/g;
return {
CallExpression: function (node) {
if (node.callee.name === "pending" && node.arguments.length > 0) {
var match = node.arguments[0].value.match(jiraTicketRegex);
if (match) {
match.forEach(function(ticket) {
console.log(ticket); // I see the ticket numbers printed
getTicket(ticket).then(function (status) {
console.log(status); // I don't see statuses printed
if (status === "Resolved") {
context.report(node, 'Ticket {{ticket}} is already resolved.', {
ticket: ticket
})
}
});
});
}
}
}
}
};
getTicket()
定义为:
function getTicket(ticket) {
var deferred = Q.defer();
jira.findIssue(ticket, function(error, issue) {
if (error) {
deferred.reject(new Error(error));
} else {
deferred.resolve(issue.fields.status.name);
}
});
return deferred.promise;
}
问题是:目前,它成功从pending()
电话中提取票号,但不打印票证状态。虽然没有错误。
问题:
我想,一般的问题是:我可以使用异步代码块,等待回调,解决自定义ESLint
规则中的承诺吗?如果没有,我的选择是什么?
更具体的问题是:我做错了什么以及如何将Node.js jira
模块与ESLint
一起使用?
会欣赏任何见解或替代方法。
答案 0 :(得分:5)
简短的回答是 - 不,你不能在规则中使用异步代码。 ESLint是同步的,并且在它走过AST时严重依赖EventEmitter
。将ESLint代码修改为异步非常困难,但同时保证事件将以正确的顺序发出。
我认为您唯一的选择可能是编写一个同步规则,将足够的信息输出到错误消息中,然后使用其中一个可解析的格式化程序,如JSON
或UNIX
,然后创建另一个可以管道ESLint的应用程序根据错误消息输出到Jira并在Jira中执行异步查找。
答案 1 :(得分:2)
这些答案在2018年仍然有效。
有关eslint开发者的一些见解,请参阅我们在邮件列表中的this conversation。
对于一个工作示例,在我的"pseudo eslint plugin"中,我选择使用昂贵但同步的API,并警告用户如何最好地在其CI流程中使用“插件”。
答案 2 :(得分:1)
注意:它没有回答有关在ESLint自定义规则中支持异步代码的原始问题,但提供了该问题的替代解决方案。
在这种情况下,我个人不会使用 ESLint ,它应该用于检查您的代码是否写得正确以及是否遵循样式指南;从我的观点来看,缺少测试不是代码检查的一部分,它更像是团队内部流程。此外,这种请求可能会显着减慢您的 ESLint 执行速度,如果有人在他们的编辑器中实时运行它,则会经常进行调用并且会减慢整个检查速度。我会让 JIRA 检查 Protractor 流程的一部分,因此如果故障单已解决,您将获得一个失败的 Protractor 规范。 (从comment复制以完成答案)
Jasmine 允许使用xit()
将规范标记为待处理。我不确定pending()
,但它在 Protractor 中很奇怪。此外, Jasmine 允许在规范中调用pending()
,因此它将被标记为暂挂,但尚未为 Protractor 实现({{3} })。知道这一点,我会使用自定义助手来定义“待定规范”,应该检查 JIRA 问题状态。我猜你仍然可以使用 Q 来处理promises,我只是使用 WebDriver promises发布一个替代方案而没有外部依赖。以下是getTicket()
的修改版本:
function getTicketStatus(ticket) {
// Using WebDriver promises
var deferred = protractor.promise.defer();
jira.findIssue(ticket, function(error, issue) {
if (error) {
deferred.reject(new Error(error));
} else {
deferred.fulfill(issue.fields.status.name);
}
});
return deferred.promise;
}
然后有一个自定义帮助函数:
function jira(name) {
// Display as pending in reporter results, remove when pending() is supported
xit(name);
// Using Jasmine Async API because Jira request is not a part of Control Flow
it(name, function (done) {
getTicketStatus().then(function (status) {
if (status === 'Resolved') {
done.fail('Ticket "' + name + '" is already resolved.');
} else {
done();
// pending() is not supported yet https://github.com/angular/protractor/issues/2454
// pending();
}
}, function (error) {
done.fail(error);
});
});
}
用法示例:
jira('Missing functionality (AP-1234)', function () {
//
});
jira('Missing functionality (AP-1235)');
如果对 JIRA 的请求失败或问题状态已解决,您将获得失败的规范(使用 Jasmine {{3 }})。在所有情况下,您仍然会在报告结果中将此规范重复为待处理。我希望当规范中的pending()
功能为see issue时,可以对其进行改进。