javascript – 使用异步forEach循环磁带“test out out without ending”错误

前端之家收集整理的这篇文章主要介绍了javascript – 使用异步forEach循环磁带“test out out without ending”错误前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我在做什么

编辑:我创建了一个repo,我的问题的简化版本重现了这个问题.

我正在尝试使用browserstack,selenium-webdrivertape设置自动前端测试.

> More about tape

我们的想法是定义多个浏览器和设备,这些浏览器和设备必须使用X量的给定测试一个接一个地进行测试.在下面的示例中,我在OSX上只定义了一个测试和两个浏览器.

为了只定义浏览器一次并处理测试,我创建了一个repo test-runner,它应该作为dev-dependency添加到需要在给定设备和浏览器上测试的repos.
测试运行器获得所有需要的测试通过,启动第一个浏览器,在该浏览器上运行测试,一旦完成所有测试,浏览器关闭quit(),下一个浏览器启动并再次测试.

测试亚军

/index.js

  1. const webdriver = require( 'selenium-webdriver' )
  2.  
  3. // ---
  4. // default browser configs
  5. // ---
  6. const defaults = {
  7. "os" : "OS X","os_version" : "Mojave","resolution" : "1024x768","browserstack.user" : "username","browserstack.key" : "key","browserstack.console": "errors","browserstack.local" : "true","project" : "element"
  8. }
  9.  
  10. // ---
  11. // browsers to test
  12. // ---
  13. const browsers = [
  14. {
  15. "browserName" : "Chrome","browser_version" : "41.0"
  16. },{
  17. "browserName" : "Safari","browser_version" : "10.0","os_version" : "Sierra"
  18. }
  19. ]
  20.  
  21. module.exports = ( tests,url ) => {
  22.  
  23. // ---
  24. // Asynchronous forEach loop
  25. // helper function
  26. // ---
  27. async function asyncForEach(array,callback) {
  28. for (let index = 0; index < array.length; index++) {
  29. await callback(array[index],index,array)
  30. }
  31. }
  32.  
  33. // ---
  34. // runner
  35. // ---
  36. const run = async () => {
  37.  
  38. // ---
  39. // Iterate through all browsers and run the tests on them
  40. // ---
  41. await asyncForEach( browsers,async ( b ) => {
  42.  
  43. // ---
  44. // Merge default configs with current browser
  45. // ---
  46. const capabilities = Object.assign( {},defaults,b )
  47.  
  48. // ---
  49. // Start and connect to remote browser
  50. // ---
  51. console.info( '-- Starting remote browser hang on --',capabilities.browserName )
  52. const browser = await new webdriver.Builder().
  53. usingServer( 'http://hub-cloud.browserstack.com/wd/hub' ).
  54. withCapabilities( capabilities ).
  55. build()
  56.  
  57. // ---
  58. // Navigate to page which needs to be checked (url)
  59. // ---
  60. console.log('-- Navigate to URL --')
  61. await browser.get( url )
  62.  
  63. // ---
  64. // Run the tests asynchronously
  65. // ---
  66. console.log( '-- Run tests --- ' )
  67. await asyncForEach( tests,async ( test ) => {
  68. await test( browser,url,capabilities,webdriver )
  69. } )
  70.  
  71. // ---
  72. // Quit the remote browser when all tests for this browser are done
  73. // and move on to next browser
  74. // Important: if the browser is quit before the tests are done
  75. // the test will throw an error beacause there is no connection
  76. // anymore to the browser session
  77. // ---
  78. browser.quit()
  79.  
  80. } )
  81.  
  82. }
  83.  
  84. // ---
  85. // Start the tests
  86. // ---
  87. run()
  88.  
  89. }

如果您想知道这个asyncForEach函数是如何工作的,我从here开始.

我的回购

/test/front/index.js

  1. const testRunner = require( 'test-runner' )
  2. const url = ( process.env.NODE_ENV == 'development' ) ? 'http://localhost:8888/element/...' : 'https://staging-url/element/...'
  3.  
  4. // tests to run
  5. const tests = [
  6. require('./test.js')
  7. ]
  8.  
  9. testRunner( tests,url )

/test/front/test.js

  1. const tape = require( 'tape' )
  2.  
  3. module.exports = async ( browser,driver ) => {
  4.  
  5. return new Promise( resolve => {
  6.  
  7. tape( `Frontend test ${capabilities.browserName} ${capabilities.browser_version}`,async ( t ) => {
  8.  
  9. const myButton = await browser.wait( driver.until.elementLocated( driver.By.css( 'my-button:first-of-type' ) ) )
  10.  
  11. myButton.click()
  12.  
  13. const marked = await myButton.getAttribute( 'marked' )
  14. t.ok(marked == "true",'Button marked')
  15.  
  16. //---
  17. // Test should end now
  18. //---
  19. t.end()
  20.  
  21. resolve()
  22.  
  23. } )
  24.  
  25. })
  26.  
  27. }

/package.json

  1. {
  2. ...
  3. "scripts": {
  4. "test": "NODE_ENV=development node test/front/ | tap-spec","travis": "NODE_ENV=travis node test/front/ | tap-spec"
  5. }
  6. ...
  7. }

当我想运行测试时,我在my-repo中执行npm run test

请记住,我们只有一个测试(但也可能是多个测试),并且定义了两个浏览器,因此行为应该是:

>启动浏览器1并导航(Chrome)
>浏览器1(Chrome)上的一项测试
>关闭浏览器1(Chrome)
>启动浏览器2并导航(Safari)
>浏览器2上的一项测试(Safari)
>关闭浏览器2(Safari)
>完成

问题

异步的东西似乎工作得很好,浏览器按照预期一个接一个地启动.问题是,即使我调用t.end()并且没有进行第二次测试(第4次测试失败),第一次测试也没有完成.

我尝试了什么

我尝试使用t.pass()并使用NODE_ENV =开发磁带测试/ front / |运行CLI tap-spec但它没有帮助.
我也注意到,当我在test.js中没有解析()时,测试结束就好了,但当然我没有进入下一个测试.

我也尝试调整我的代码,如this issue解决方案,但没有设法让它工作.

与此同时,我还在磁带github页面上打开了一个issue.

因此,我希望这个问题不是一个痛苦的阅读,任何帮助将不胜感激.

解决方法

似乎磁带在异步代码中不能很好地工作.在他们的Github问题页面上查看这些讨论:

https://github.com/substack/tape/issues/223
https://github.com/substack/tape/issues/160

解决方案似乎是在调用任何异步代码之前,在开头使用tape.add声明测试.

如果您只是按顺序打开浏览器,我还会尝试重构一些可能不需要的异步代码.

猜你在找的JavaScript相关文章