2013-05-08 9 views
5

Mam uproszczony test QUnit składający się z 2 prostych testów, które zawodzą losowo/naprzemiennie bez żadnego uzasadnienia (oba są atomowe, co oznacza, że ​​jeden test niczego nie zmienia z drugiego elementu)QUnit nieudanie testuje niekonsekwentnie/naprzemiennie

proszę zobaczyć this jsFiddle spróbuj run wielokrotnie

module("Basic actionBind"); 
//two simple tests 
test("action1", function() { 
    ok(ele2.trigger("click").hasClass("clicked"), "basic click action"); 
}); 

test("action2", function() { 
    ok(ele1.click().hasClass("clicked"), "basic click action"); 
}); 
+0

Co robi drugi test? Nie jestem pewien, co robi funkcja "kliknij" bez żadnych argumentów. –

+0

sama funkcja kliknięcia bez argumentów "trigger" to kliknięcie – adardesign

+0

Bardzo dziwne. Uaktualniłem dwa razy, aby uwzględnić te dwa testy i uczyniłem je asynchronicznymi z przypadkowymi pauzami, ale tylko jeden test został uruchomiony. To tak, jakby kliknięcie/spust rzuciło się po pierwszym. http://jsfiddle.net/bAbNd/1/. –

Odpowiedz

8

Problem polega na buforowaniu obiektów jQuery w kontekście globalnym w czasie wykonywania. Oto dwa fragmenty z kodu (od ogniwo zapytanie: http://jsfiddle.net/adardesign/aZRK7/12/):

HTML:

<div id="qunit-fixture"> 
    <span id="ele1" class="action" data-action="action1"></span> 
    <span id="ele2" class="action" data-action="action2" ></span> 
</div> 

JS:

// caching elements 
var $ele1 = $('#ele1'), 
    $ele2 = $('#ele2'); 

test('action1', function() { 
    ok($ele2.trigger('click') .... 


test('action2', function() { 
    ok($ele1.trigger('click') .... 

Rzeczywiste elementy są wewnątrz #qunit-fixture który jest resetuj i ponownie analizuj dla każdego testu, dlatego zdarzenia kliknięcia, które wystrzeliłeś z testów, zostały uruchomione na elementach, które nie są już w wersji document. Zamiast tego elementy te zostały odłączone i zostały ponownie przetworzone z oryginalnego tekstu HTML, tworząc w ten sposób nowe elementy DOM.

Mam rozwidlony swoją jsFiddle i poprawione to odpowiednio: http://jsfiddle.net/aZRK7/15/

Choć oczyścić różne części zanim zauważył, zasadniczą zmianą jest przeniesienie kwerendy dla elementu do wewnątrz testu:

test('foo', function() { 
    var $foo = $('#ele1'); 
    ok($foo.trigger('click') .... 


test('bar', function() { 
    var $bar = $('#bar'); 
    ok($bar.trigger('click') .... 
+1

+1 dziękuję bardzo! Chciałbym, żeby to było w dokumentacji przed spędzeniem godzin ... jeszcze raz dzięki. – adardesign

+1

@adardesign: "QUnit zresetuje elementy wewnątrz # elementu qunit-fixture po każdym teście, usuwając wszelkie zdarzenia, które mogły istnieć. Dopóki używasz elementów tylko wewnątrz tego urządzenia, nie musisz ręcznie czyścić po twoje testy, aby utrzymać je atomowo. " http://qunitjs.com/cookbook/ –

+1

Problemem może być nie tylko buforowanie elementów w zasięgu globalnym, ale także ** okablowanie zdarzenia poprzez skrypt w innym miejscu **. Mam przycisk, do którego dołączyłem program obsługi kliknięć w skrypcie ('$ (" # equalsButton ") .Kliknij (...);'). Z powodu czyszczenia urządzenia, jednak * bez ponownego uruchamiania okablowania zdarzeń w 'default.js' *, program obsługi był naprzemiennie lub nie był dołączony do przycisku, co powodowało niepowodzenie testu lub jego powodzenie. Rozwiązano problem polegający na łączeniu zdarzenia "kliknięcie" przed każdym uruchomieniem testu (lub w procedurze konfiguracji testowej). –

0

EDIT: Wygląda OP wyjął część asynchronicznego kodu, pozostawiając odpowiedź w przypadku jakichkolwiek potyka na to, ale to nie odpowiada teraz na pytanie.

Cóż, nie jestem pewien, jakie problemy możesz mieć sam test, ale każdy AsyncTest musi mieć gdzieś połączenie start();. Więc z skrzypce:

asyncTest("action1", delay.bind(null, function() { 
    console.log("test1"); 
    ok(ele2.trigger("click").hasClass("clicked"), "basic click action"); 

    start(); 

}, 2000*Math.random())); 

Z QUnit asyncTest documentation, zobaczyć ich przykłady.

+0

Dzięki, To nie jest operacja asynchroniczna, jest to? Poza tym spróbowałem twojego kodu i nadal się nie udaje http://jsfiddle.net/adardesign/bAbNd/3/ – adardesign

+0

W twoim skrzypcach używasz 'asynTest()', a wykonanie tego wymaga poinformowania QUnit, kiedy część asynchroniczna testu jest wykonywana i kontynuowana (to wywołanie funkcji 'start();)). Jak już wspomniałem, nie jestem w 100% pewna, dlaczego otrzymujesz porażki, bardziej odpowiadała na drugą część. Spróbuję sprawdzić, czy uda mi się wymyślić cokolwiek innego. – jakerella