量角器 - 在执行expect之前等待异步调用完成

时间:2017-04-06 21:08:19

标签: protractor

我正在运行以下内容:

it('should be able to run sql', function () {
    var success = true;
    var testsCompleted;
    for (var i = 0; i < sqlToRun[1].length; i++) {
        sql.runEtlQuery(config, sqlToRun, i).then(function () {
            testsCompleted++;
        }).catch(function (err) {
            console.log(err);
            success = false;
        });
    }
    expect(testsCompleted == sqlToRun[1].length).toBeTruthy();
    expect(success).toBeTruthy();
});

但是,在完成sql异步调用之前,它正在运行期望查询并且未通过测试,并且测试将在开始打印出sql查询的结果之前失败。

sql查询如下所示:

runEtlQuery: function (config, sqlToRun, i) {
    var defer = protractor.promise.defer();
    var connection = new sql.ConnectionPool(config, function (err) {
        var request = new sql.Request(connection);
        request.query(sqlToRun[1][i], function (err, recordset) {
            if (err) defer.reject("#" + i + ": " + sqlToRun[0][i] +"\x1b[31m Error: \x1b[0m" + err);
            else {
                console.log("#" + i + ": " + sqlToRun[0][i] + " - \x1b[32mPassed\x1b[0m");
                defer.fulfill();
                connection.close();
            }
        });
    });
    return defer.promise;
},

控制台输出如下:

[13:12:42] I/launcher - Running 1 instances of WebDriver
[13:12:42] I/local - Starting selenium standalone server...
[13:12:43] I/local - Selenium standalone server started at http://10.197.244.125:62251/wd/hub
Started
..F

Failures:
1) ETL tests should be able to run sql
  Message:
    Expected false to be truthy.
  Stack:
    Error: Failed expectation
---<removed stacktrace>---

3 specs, 1 failure
Finished in 270.903 seconds

#17: CDW_Test - Passed
#15: CDW_LabTestName - Passed
#4: CDW_removed - Passed
#5: CDW_removed - Passed
#1: CDW_moreremoved - Passed
#30: CDW_Stuff - Passed
<ect>

我试图弄清楚如何让它等待所有sql查询完成,然后再检查测试是否失败或通过。

我曾经拥有它所以它会在第一次错误时失败,但是想要更改它以便继续处理sql查询以获得所有失败的列表,然后再进行测试。

2 个答案:

答案 0 :(得分:1)

我确实找到了使其正常工作的方法,即使它不是最优雅的解决方案:

it('should be able to run sql', function (done) {
    sql.recursiveRunEtlQuery(config, sqlToRun, sqlToRun[1].length - 1).then(function () {
        done();
    }).catch(function (err) {
        success = false;
        done.fail(err);
    });

然后recursiveRunEtlQuery函数如下所示:

recursiveRunEtlQuery: function (config, sqlToRun, i) {
    var defer = protractor.promise.defer();
    if (i >= 0) {
        module.exports.recursiveRunEtlQuery(config, sqlToRun, i - 1).then(function () {
            module.exports.runEtlQuery(config, sqlToRun, i).then(function () {
                defer.fulfill();
            }).catch(err => {
                defer.reject(utilities.stringFormat("Error Running ETL: \x1b[36m{0}\x1b[0m:\nSQL:\n\x1b[33m{1}\x1b[0m\nError:\n\x1b[31m{2}\x1b[0m", sqlToRun[0][i], sqlToRun[1][i], err));
            });
        }).catch(err => {
            module.exports.runEtlQuery(config, sqlToRun, i).then(function () {
                defer.reject(err);
            }).catch(err2 => {
                defer.reject(utilities.stringFormat("Error Running ETL: \x1b[36m{0}\x1b[0m:\nSQL:\n\x1b[33m{1}\x1b[0m\nError:\n\x1b[31m{2}\x1b[0m\n{3}", sqlToRun[0][i], sqlToRun[1][i], err2, err));
            });
        });
    }
    else defer.fulfill();
    return defer.promise;

此解决方案的主要问题是它强制它同步运行而不是运行Async,这将导致它运行更长时间,因为某些查询需要一段时间才能完成。

答案 1 :(得分:0)

首先,这是一个很好的例子,说明为什么我不喜欢测试中的多个expect ...因为我不知道你的expect哪个失败了。

那就是说,假设不是你runEtlQuery方法失败,你可能会遇到infamous looping with promises issue

TLDR;您可以使用Immediately-Invoked Function Expression来确保索引按预期绑定。

it('should be able to run sql', function () {
    var success = true;
    var testsCompleted;
    for (var i = 0; i < sqlToRun[1].length; i++) {
        (funciton(index) {
            sql.runEtlQuery(config, sqlToRun, index).then(function () {
                testsCompleted++;
            }).catch(function (err) {
                console.log(err);
                success = false;
            });
        })(i);
    }
    expect(testsCompleted == sqlToRun[1].length).toBeTruthy();
    expect(success).toBeTruthy();
});