编辑:我创建了一个repo,我的问题的简化版本重现了这个问题.
我正在尝试使用browserstack,selenium-webdriver和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.
因此,我希望这个问题不是一个痛苦的阅读,任何帮助将不胜感激.
解决方法
https://github.com/substack/tape/issues/223
https://github.com/substack/tape/issues/160
解决方案似乎是在调用任何异步代码之前,在开头使用tape.add声明测试.
如果您只是按顺序打开浏览器,我还会尝试重构一些可能不需要的异步代码.