2017-04-06 86 views
0

我运行前先完成以下事项:它完成的sql异步调用之前量角器 - 等待异步调用执行期望

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查询看起来是这样的:

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查询以获得失败之前的所有失败列表的测试。

回答

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; 

的这个解决方案的主要问题是它迫使它同步运行而不是运行异步,这将导致它运行得更长,因为一些查询需要一段时间才能完成。

0

首先,这是一个很好的例子,说明为什么我不喜欢在测试中使用多个expect ......因为我无法分辨您的哪个expect s失败。

这就是说,假设它不是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(); 
}); 
+0

是的,我通常会评论一下'expect'和'testsCompleted'这一行基本上只是为了调试代码,以确保它在执行期望前完成所有事情。无论是否有任何sql错误,测试总是会成功,只需要“成功”一行。 – Corey

+0

我只是试着用这个来运行,它在应该成功时仍然失败,在失败时成功(IE第一次期望会导致失败,第二次会导致它成功,即使存在错误),所以它在运行第一个sql之前仍然运行期望值。 – Corey