2015-03-29 1 views
28

Ho molta instabilità con il goniometro, e sono sicuro che c'è qualcosa che non capisco. A volte ho bisogno di usare il .then() quando si fa clic su un pulsante prima di continuare, a volte non ha alcun impatto e non dovrei usare .then() o il test non è riuscito.Quando dovremmo usare. Poi con Protractor Promise?

Mi chiedo quando dovrei usare il callback .then() durante il test in Goniometro? Esempio:

createAccountForm = $('#form-create-account'); 
submitButton = createAccountForm.$('button[type=submit]'); 

browser.wait(EC.elementToBeClickable(submitButton), 5000); 
submitButton.click(); // .then(function(){ <-- uncomment in the .then form 

// find the confirmation message 
var message = $('.alert-success'); 
browser.wait(EC.visibilityOf(message), 5000); 
log.debug('After visibilityOf'); 

expect(message.isPresent()).to.be.eventually.true; 
// }); --> uncomment when in .then form 

Quando uso questa forma di prova (senza .then()) che vedo sul browser che il clic sul pulsante non è fatto, il test di continuare con il seguente aspettano e poi fermarsi .

Se Io uso il modulo .then(), il clic sul pulsante è fatto e il test continua senza errori.

In altri test, non è necessario utilizzare il callback then() quando si fa clic sul pulsante.

Quindi, quando dovrei usare il .then() e quando no?

Jean-Marc

risposta

36

La risposta di questa domanda si può trovare in questo post: http://spin.atomicobject.com/2014/12/17/asynchronous-testing-protractor-angular/

Cioè:

  1. goniometro accodare tutti i comandi del driver nel ControlFlow,
  2. quando hai bisogno del risultato di un comando driver che dovresti usare. poi,
  3. quando non hai bisogno del risultato di un driver puoi vuoto ma poi tutte le istruzioni devono essere accodate nel ControlFlow altrimenti saranno eseguite prima dei comandi nella coda che portano al risultato imprevedibile di . Pertanto, se si desidera eseguire un comando di test non del driver, è necessario aggiungerlo alla callback .then oppure avvolgere il test in Promise e accodare il test in ControlFlow. Vedi l'esempio qui sotto.

Ecco un esempio del mio test di lavoro senza .then:

log.debug('test0'); 

// enqueue the click 
submitButton.click(); 
var message = $('.alert-success'); 

// enqueue the wait for message to be visible 
browser.wait(EC.visibilityOf(message), 5000); 

log.debug('test1'); 

// enqueue a test 
expect(message.isPresent()).to.be.eventually.true; 
log.debug('test2'); 

// a function returning a promise that does an async test (check in MongoDB Collection) 
var testAccount = function() {   
    var deferred = protractor.promise.defer(); 

    // Verify that an account has been created 
    accountColl.find({}).toArray(function (err, accs) { 
     log.debug('test5'); 
     expect(err).to.not.exist; 
     log.debug('test6'); 
     expect(accs.length).to.equal(1); 
     return deferred.fulfill(); 
    }); 
    return deferred.promise; 
}; 

log.debug('test3'); 

// Enqueue the testAccount function 
browser.controlFlow().execute(testAccount); 
log.debug('test4'); 

uscita è ora quello che ci aspettiamo:

test0 

test1 

test2 

test3 

test4 

test5 

test6 
+0

Come sarebbe l'uscita testX essere diverso se si chiama Testaccount () direttamente (senza le risorse browser.controlFlow)? – Mike

+0

Inoltre, perché la necessità di browser.wait? – Mike

+0

Se testAccount viene chiamato direttamente, a volte si ha l'ordine corretto e talvolta non dipende dalla velocità del browser o della macchina. Potresti avere qualcosa come 0, 1, 2, 3, 5, 6, 4 o il test expect (message.isPresent()). To.be.eventually.true può essere valutato dopo che il testAccount chiama – jmcollin92