2017-04-06 33 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