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

const webdriver = require( 'selenium-webdriver' )

// ---
// default browser configs
// ---
const defaults = {
  "os" : "OS X","os_version" : "Mojave","resolution" : "1024x768","browserstack.user" : "username","browserstack.key" : "key","browserstack.console": "errors","browserstack.local" : "true","project" : "element"
}

// ---
// browsers to test
// ---
const browsers = [
  {
    "browserName" : "Chrome","browser_version" : "41.0"
  },{
    "browserName" : "Safari","browser_version" : "10.0","os_version" : "Sierra"
  }
]

module.exports = ( tests,url ) => {

  // ---
  // Asynchronous forEach loop
  // helper function
  // ---
  async function asyncForEach(array,callback) {
    for (let index = 0; index < array.length; index++) {
      await callback(array[index],index,array)
    }
  }

  // ---
  // runner
  // ---
  const run = async () => {

    // ---
    // Iterate through all browsers and run the tests on them
    // ---
    await asyncForEach( browsers,async ( b ) => {

      // ---
      // Merge default configs with current browser
      // ---
      const capabilities = Object.assign( {},defaults,b )

      // ---
      // Start and connect to remote browser
      // ---
      console.info( '-- Starting remote browser hang on --',capabilities.browserName )
      const browser = await new webdriver.Builder().
        usingServer( 'http://hub-cloud.browserstack.com/wd/hub' ).
        withCapabilities( capabilities ).
        build()

      // ---
      // Navigate to page which needs to be checked (url)
      // ---
      console.log('-- Navigate to URL --')
      await browser.get( url )

      // ---
      // Run the tests asynchronously
      // ---
      console.log( '-- Run tests --- ' )
      await asyncForEach( tests,async ( test ) => {
        await test( browser,url,capabilities,webdriver )
      } )

      // ---
      // Quit the remote browser when all tests for this browser are done
      // and move on to next browser
      // Important: if the browser is quit before the tests are done
      // the test will throw an error beacause there is no connection
      //  anymore to the browser session
      // ---
      browser.quit()

    } )

  }

  // ---
  // Start the tests
  // ---
  run()

}

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

我的回购

/test/front/index.js

const testRunner = require( 'test-runner' )
const url = ( process.env.NODE_ENV == 'development' ) ? 'http://localhost:8888/element/...' : 'https://staging-url/element/...'

// tests to run
const tests = [
  require('./test.js')
]

testRunner( tests,url )

/test/front/test.js

const tape = require( 'tape' )

module.exports = async ( browser,driver ) => {

  return new Promise( resolve => {

    tape( `Frontend test ${capabilities.browserName} ${capabilities.browser_version}`,async ( t ) => {

      const myButton = await browser.wait( driver.until.elementLocated( driver.By.css( 'my-button:first-of-type' ) ) )

      myButton.click()

      const marked = await myButton.getAttribute( 'marked' )
      t.ok(marked == "true",'Button marked')

      //---
      // Test should end now
      //---
      t.end()

      resolve()

    } )

  })

}

/package.json

{
  ...
  "scripts": {
    "test": "NODE_ENV=development node test/front/ | tap-spec","travis": "NODE_ENV=travis node test/front/ | tap-spec"
  }
  ...
}

当我想运行测试时,我在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相关文章