2012-11-12 29 views
12

Sto testando un'applicazione Web utilizzando Mocha e WebDriverJS, più o meno come indicato here. Quando i test passano, tutto va bene. Tuttavia, se un test fallisce, il resto dei test nella suite scadrà e il corridore uscirà alla fine della suite, senza chiudere l'istanza di Webdriver. Esempio test case:Node.js + mocha + webdriverjs: Test fallito kill suite

var assert = require('assert'), 
    client = require("webdriverjs").remote({ 
     logLevel: 'silent' 
    }); 

describe('Self-test', function() { 

    before(function(done) { 
     client 
      .init() 
      .url('http://www.wikipedia.org/', function() { 
       done(); 
      }); 
    }); 

    after(function(done) { 
     client.end(function() { 
      done(); 
     }); 
    }); 

    // tests 

    it('should fail properly', function(done) { 
     client.getTitle(function(result) { 
      assert(false, 'This should fail'); 
      done(); 
     }); 
    }); 

    it('should pass afterwards', function(done) { 
     client.getTitle(function(result) { 
      assert(true, 'This should still pass'); 
      done(); 
     }); 
    }); 

}); 

uscita:

~> mocha test/self-test.js 

    Self-test 
    1) should fail properly 
    2) should pass afterwards 
    3) "after all" hook 

✖ 3 of 2 tests failed: 

1) Self-test should fail properly: 
    AssertionError: This should fail 
    at null.<anonymous> (./test/self-test.js:24:17) 
    at QueueItem (./node_modules/webdriverjs/lib/webdriverjs.js:242:15) 
    at null.<anonymous> (./node_modules/webdriverjs/lib/commands/getTitle.js:12:6) 
    at QueueItem (./node_modules/webdriverjs/lib/webdriverjs.js:242:15) 
    at IncomingMessage.WebdriverJs.proxyResponse (./node_modules/webdriverjs/lib/webdriverjs.js:782:6) 
    at IncomingMessage.EventEmitter.emit (events.js:115:20) 
    at IncomingMessage._emitEnd (http.js:366:10) 
    at HTTPParser.parserOnMessageComplete [as onMessageComplete] (http.js:149:23) 
    at Socket.socketOnData [as ondata] (http.js:1366:20) 
    at TCP.onread (net.js:402:27) 

2) Self-test should pass afterwards: 
    Error: timeout of 10000ms exceeded 
    at Object.<anonymous> (./node_modules/mocha/lib/runnable.js:158:14) 
    at Timer.list.ontimeout (timers.js:101:19) 

3) Self-test "after all" hook: 
    Error: timeout of 10000ms exceeded 
    at Object.<anonymous> (./node_modules/mocha/lib/runnable.js:158:14) 
    at Timer.list.ontimeout (timers.js:101:19) 

Per quanto posso dire, questo è perché la coda WebDriverJS viene bloccato quando un test fallisce. C'è un modo per risolvere questo problema? Non ottimale anche per il test della riga di comando locale e rende i test in esecuzione automatica e/o in background difficili da eseguire.

Aggiornamento: credo di poter risolvere il guasto coda di istanziando un nuovo client per ogni test, ma questo renderebbe le cose molto più lenti (come istanza WebDriver avrebbe bisogno di iniziare da zero ogni volta) e lascerebbe I processi di WebDriver restano impunturati in caso di fallimento del test. Idealmente, mi piacerebbe qualcosa di simile alla struttura offerta da Soda, in cui un errore da qualche parte nella coda salta alla fine della coda e poi genera l'errore per il framework di test da catturare.

risposta

2

è necessario impostare e abbattere con beforeEach() e afterEach() invece di before() e after() se ogni test dipende lo stato della coda di WebDriverJS.

+0

L'unica differenza con questo approccio è che il test si blocca dopo il primo test, il timeout su "afterEach" e il secondo test non viene mai eseguito. Il problema è lo stesso. – nrabinowitz

+0

Cosa succede quando non usi 'after()' e invece aggiungi semplicemente '.end() 'chiama all'oggetto' client' in ogni test? Essenzialmente sei incappato in un inferno asincrono tra le due API, ma dovrebbe essere risolvibile con alcune modifiche minori. – srquinn

+0

Vorrei poterti aiutare di più, ma senza accesso al server Selenium non riesco a eseguire test. – srquinn

2

Il modo in cui webdriverjs è scritto ogni test dovrebbe essere una sessione separata, quindi iniziare con init() e end with end(). Un'eccezione nel test comparirà a mocha e rovinerà la coda di webdriverjs. Stai quindi provando a noi webdriverjs in un modo che non è supportato.

Osservando il codice sorgente della soda, anche questo sembra essere il caso. In client.js:223 vengono gestite le eccezioni e l'errore viene restituito al callback. Questo callback è la funzione impostata con .end() e quindi non avere un .end() per ogni test salterà semplicemente tutti i seguenti test della stessa sessione fino a chiamare il callback dell'ultimo test .end().

È questo che intendi per "un errore da qualche parte nella coda salta alla fine della coda"? Se questo è il comportamento che si desidera, è necessario includere webdriver.js:244 con un tentativo di intercettazione e quando viene rilevata un'eccezione, chiamare il comando .end().

+0

Non c'è alcun motivo particolare per cui i test devono essere eseguiti in sessioni diverse e rende i test eseguiti molto più lentamente se si scrivono i test in questo modo (ad esempio se l'app richiede l'autenticazione, è necessario eseguire il login per ogni test). Anche se hai seguito questo approccio, '.end()' non verrebbe mai chiamato per il test corrente una volta fallito un passaggio, quindi avresti ancora il problema delle istanze di WebDriver non chiuse. – nrabinowitz

+0

Wrapping line 244 con 'try/catch' funzionerebbe, ma non mi piace l'opzione" then call '.end()' ", in quanto ucciderà ulteriori test che si basano su un client aperto e non getterebbero l'errore (anche se suppongo che potresti lanciare perfettamente dopo aver chiamato '.end()'). – nrabinowitz

+0

Inoltre, chiamare manualmente .end() non funzionerà qui - questo lo aggiungerebbe alla coda, che probabilmente non è più in esecuzione. Dovrei chiamare direttamente il comando API, immagino. – nrabinowitz

0

si avrebbe bisogno di un listner per catturare l'eccezione non rilevata

webdriver.promise.controlFlow().on('uncaughtException', function(e) { 
    console.error('Unhandled error: ' + e); 
    driver.quit(); 
}); 

questo è quello che sto facendo. L'unico problema con questo è anche prendere errore di asserzione. spero che questo aiuti.