2012-11-12 15 views
12

Testuję aplikację internetową przy użyciu Mocha i WebDriverJS, mniej więcej tak jak opisano w artykule here. Kiedy testy mijają, wszystko jest w porządku. Jeśli jednak jeden test się nie powiedzie, pozostałe testy w pakiecie przekroczą limit czasu, a biegacz zakończy pracę po zakończeniu zestawu, bez zamykania instancji Webdriver. Przykład testowy przypadek:Node.js + mocha + webdriverjs: testy zakończone niepowodzeniem zabezpieczyły pakiet

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(); 
     }); 
    }); 

}); 

wyjściowa:

~> 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) 

O ile mogę powiedzieć, to dlatego, że kolejka WebDriverJS zostaje wstrzymane, gdy próba nie powiedzie się. Czy istnieje sposób, aby to naprawić? To nie jest optymalne nawet dla lokalnych testów linii poleceń, i sprawia, że ​​testowanie automatyczne i/lub w tle jest trudne do niemożliwego.

Aktualizacja: myślę, że mogę naprawić awarię kolejka o uruchamianiu nowego klienta dla każdego testu, ale byłoby to zrobić rzeczy znacznie wolniej (jako instancja WebDriver musiałaby rozpocząć się od nowa za każdym razem) i zostawi Procesy WebDriver zawieszają się wokół nierozliczonych w przypadku niepowodzenia testu. Idealnie, chciałbym coś podobnego do struktury oferowanej przez Soda, gdzie awaria gdzieś w kolejce przeskakuje na koniec kolejki, a następnie zgłasza błąd dla szkieletu testowego do przechwycenia.

Odpowiedz

2

Powinieneś setup i zburzyć z beforeEach() i afterEach() zamiast before() i after() jeśli każdy test jest zależny od stanu kolejki WebDriverJS.

+0

Jedyna różnica w tym podejściu polega na tym, że test zawiesza się po pierwszym teście, limit czasu na "afterEach", a drugi test nigdy nie działa. Problem jest taki sam. – nrabinowitz

+0

Co się stanie, gdy nie użyjesz 'po()' i zamiast tego po prostu dodasz '.end() 'wywołanie obiektu' client' w każdym teście? Zasadniczo natknąłeś się na asynchroniczne piekło pomiędzy dwoma interfejsami API, ale powinno być możliwe do poprawienia dzięki drobnym poprawkom. – srquinn

+0

Chciałbym pomóc, ale bez dostępu do serwera Selenium nie mogę uruchomić testów. – srquinn

2

Sposób zapisywania każdego testu przez webdriverjs powinien być oddzielną sesją, a zatem zaczynać od init() i kończyć do końca(). Wyjątek w teście będzie dymić do mokki i zepsuć kolejkę webdriverjs. Dlatego próbujesz nam webdriverjs w sposób, który nie jest obsługiwany.

Wygląda na to, że wygląda na kod źródłowy sody. W przypadku obsługi wyjątków client.js:223 błąd jest przekazywany do wywołania zwrotnego. To wywołanie zwrotne jest funkcją ustawioną za pomocą .end() i dlatego nie posiadanie .end() dla każdego testu po prostu pominie wszystkie kolejne testy tej samej sesji, aż do wywołania wywołania zwrotnego last.

Czy to masz na myśli przez "awaria gdzieś w kolejce przeskakuje do końca kolejki"? Jeśli takie zachowanie jest pożądane, należy dołączyć webdriver.js:244 z próbnym haczykiem, a po złapaniu wyjątku wywołać komendę .end().

+0

Nie ma żadnego szczególnego powodu, dla którego testy muszą odbywać się w różnych sesjach, i sprawia, że ​​testy przebiegają znacznie wolniej, jeśli napiszesz testy w ten sposób (np. Jeśli twoja aplikacja wymaga uwierzytelnienia, musisz się zalogować przy każdym teście). Nawet gdybyś zastosował to podejście, '.end()' nigdy nie zostałoby wywołane dla bieżącego testu, gdy jeden krok się nie powiódł, więc nadal masz problem z niezainstalowanymi instancjami WebDriver. – nrabinowitz

+0

Zawijanie wiersza 244 z 'try/catch' będzie działało, ale nie podoba mi się opcja" wtedy wywołaj '.end()' ", ponieważ zabije dalsze testy, które polegają na otwartym kliencie i nie rzuci błąd (chociaż przypuszczam, że możesz doskonale rzucić po wywołaniu '.end()'). – nrabinowitz

+0

Ręczne wywoływanie .end() nie będzie tu działało - wystarczyłoby dodać je do kolejki, która prawdopodobnie już nie działa. Będę musiał zadzwonić bezpośrednio do polecenia API, tak myślę. – nrabinowitz

0

potrzebny jest listner złapać przechwycony wyjątek

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

to właśnie to robię. Jedynym problemem z tym jest to, że przechwytuje również błąd asercji. mam nadzieję, że to pomoże.

Powiązane problemy