2011-07-16 14 views
6

Mam dynamiczną stronę zbudowaną z jQuery. Fragmenty HTML są ładowane z szablonów mustache. Szablony te są pobierane z adresu URL, i chciałbym, aby przetestować urządzenie ogólną budowę HTML:Jak przetestować wywołania jquery i ajax za pomocą JsTestDriver?

Test JsTestDriver jest:

AppTest = TestCase("AppTest") 

AppTest.prototype.test = function() { 
    var actualHtml = ""; 

    getHtml({ "title": "title", "header": "header", "text": "text", "authors": [ {"firstname": "firstname", "lastname": "lastname"} ] }, function(html) { 
     actualHtml = html; 
    }); 

    assertEquals("expected html", actualHtml); 
}; 

I kod:

function getHtml(json, resultFunc) { 
    jQuery.ajax({ 
      url: "url/to/mustache/template", 
      success: function(view) { 
        resultFunc(mergeArticleModelAndView(json, view)); 
      }, 
      error: function(jqXHR, textStatus, errorThrown) { 
        resultFunc(textStatus + " errorThrown: " + errorThrown); 
      }, 
      dataType: 'text', 
      async: false 
    }); 
} 

Potem uruchom Testy i wynik:

$ java -jar JsTestDriver-1.3.2.jar --port 9876 --browser /usr/bin/firefox --tests all 
F 
Total 1 tests (Passed: 0; Fails: 1; Errors: 0) (8,00 ms) 
    Firefox 5.0 Linux: Run 1 tests (Passed: 0; Fails: 1; Errors 0) (8,00 ms) 
    AppTest.test failed (8,00 ms): AssertError: expected "expected html" but was "error errorThrown: [Exception... \"Component returned failure code: 0x80004005 (NS_ERROR_FAILURE)\" nsresult: \"0x80004005 (NS_ERROR_FAILURE)\" location: \"JS frame :: http://localhost:9876/test/main/js/jquery.min.js :: <TOP_LEVEL> :: line 16\" data: no]" 
()@http://localhost:9876/test/test/js/app_test.js:25 

Tak więc wywołanie zwrotne błędu zostało wywołane, nd Nie rozumiem dlaczego zrywa z JsTestDriver, a kod działa, gdy ręcznie wywołanie aplikacji z poziomu przeglądarki

Ostatnia rzecz, jsTestDriver.conf:

server: http://localhost:9876 

load: 
    - test/js/app_test.js 
    - main/js/jquery.min.js 
    - main/js/jquery.mustache.js 
    - main/js/app.js 

Dziękuję za porady. Bardziej ogólnie, jakie platformy testów jednostkowych używasz do testowania javascript i wiersza poleceń z DOM i jQuery?

+0

użyć [jaśmin] (https://github.com/pivotal/jasmine). Nie wykonuję ich za pomocą wiersza poleceń, ale istnieje kilka wtyczek do tego. To, co podoba mi się w Jasmine, generuje kod testowy prozą. I możesz zagnieździć swoje testy. Istnieje również wtyczka do jQuery, ale bez niej wszystko jest w porządku. –

Odpowiedz

3

Tak to jest możliwe, aby zrobić to samo z jQuery:

kod testowy (tylko setup test jest taki sam):

TestCase("AppTest", { 
    setUp: function() { 
     this.xhr = Object.create(fakeXMLHttpRequest); 
     this.xhr.send=function() { 
      this.readyState = 4; 
     }; 
     this.xhr.getAllResponseHeaders=stubFn({}); 
     this.xhr.responseText="<expected data>"; 
     jQuery.ajaxSettings.isLocal=stubFn(true); 
     jQuery.ajaxSettings.xhr=stubFn(this.xhr); 
    }, 
// same test method 

a kod produkcji:

function getHtml(model, resultFunc) { 
     $.get("/url/to/template", function(view) { 
       resultFunc(mergeArticleModelAndView(model, view)); 
     }); 
} 

To rozwiązanie, które wybraliśmy.

4

Znalazłem sposób, aby to zrobić: jest wyśmiewać wywołania ajax. Na http://tddjs.com/ jest przykładem na to w rozdziale 12, a repozytorium git jest tutaj: http://tddjs.com/code/12-abstracting-browser-differences-ajax.git

Więc kod test jest:

TestCase("AppTest", { 
    setUp: function() { 
     tddjs.isLocal = stubFn(true); 
     var ajax = tddjs.ajax; 
     this.xhr = Object.create(fakeXMLHttpRequest); 
     this.xhr.send=function() { 
      this.readyState = 4; 
      this.onreadystatechange(); 
     }; 
     this.xhr.responseText="<expected data>"; 
     ajax.create = stubFn(this.xhr); 
    }, 


    "test article html ok": function() { 
     var actualHtml = ""; 

     getHtml({ "title": "title", "header": "header", "text": "text", "authors": [ {"firstname": "firstname", "lastname": "lastname"} ] }, function(html) { 
      actualHtml = html; 
     }); 

     assertEquals("<expected html>", actualHtml); 
    } 
}); 

I kod produkcja:

function getHtml(model, resultFunc) { 
     tddjs.ajax.get("http://url/to/template", { 
       success: function (xhr) { 
         resultFunc(mergeArticleModelAndView(model, xhr.responseText)); 
       } 
     }); 
} 

Po przeczytaniu kodu jQuery, myślę, że możliwe jest wyśmiać żądanie jQuery ajax. Por także jquery 1.5 mock ajax

5

Alternatywą byłoby pobranie JsTestDriver do obsługi szablonu i niektórych danych testowych JSON. Poniższa konfiguracja pozwala umieścić statyczne dane testowe JSON (np. My_data.json) w src/test/webapp/json i szablony wąsów w src/main/webapp/templates. Możesz to zmienić tak, aby pasowało do twojego układu źródłowego, jeśli jest to zbyt Maven-y dla twoich upodobań.

Należy zauważyć, że JsTestDriver udostępnia zasoby z/test/pre-pending do identyfikatora URI określonego w atrybucie serve, więc src/test/webapp/json/my_data.json jest faktycznie obsługiwany z http:// localhost: 9876/test/src/test/webapp/json/my_data.json.

server: http://localhost:9876 

serve: 
- src/main/webapp/templates/*.html 
- src/test/webapp/json/*.json 

load: 
- src/main/webapp/js/*.js 
- src/main/webapp/js/libs/*.js 

test: 
- src/test/webapp/js/*.js 

Następnie w walizce testowej można z łatwością załadować szablon i dane JSON.

testLoadTemplateAndData : function() { 

     // Variables 
     var onComplete, template, data, expected, actual, templateLoaded, dataLoaded; 
     dataLoaded = false; 
     templateLoaded = false; 
     expected = "<h2>Your expected markup</h2>"; 

     // Completion action 
     onComplete = function() { 
      if (dataLoaded && templateLoaded) { 

       // Render the template and data 
       actual = Mustache.to_html(template, data); 

       // Compare with expected 
       assertEquals('Markup should match', expected, actual); 

      } 
     }; 

     // Load data with jQuery 
     $.ajax({ 
      url : '/test/src/test/webapp/json/demo.json', 
      success : 
       function (result) { 
        data = result; 
        dataLoaded = true; 
      }, 
      error : 
       function() { 
        fail("Data did not load."); 
      }, 
      complete : 
       function() { 
        onComplete(); 
       } 
      } 
     ); 

     // Load the template with jQuery 
     $.get('/test/src/main/webapp/templates/demo.html', 
      function(result) { 
       template = result; 
       templateLoaded = true; 
      } 
     ) 
     .error(function() { fail("Template did not load."); }) 
     .complete(function() { 
      onComplete(); 
     }); 

    } 

Kiedy zarówno jQuery Callbacki kompletne, Wąsy powinny przeanalizować szablonu z danymi JSON i renderowanie oczekiwany wynik.

0

z sinon.js jest jeszcze prostsze:

TestCase("AppTest", { 
setUp: function() { 
    this.server = sinon.fakeServer.create(); 
}, 
tearDown: function() { 
    this.server.restore(); 
}, 

"test article html ok": function() { 
    this.server.respondWith("mustache template"); 
    this.server.respond(); 
    var actualHtml = ""; 

    getHtml({ "title": "title", "header": "header", "text": "text", "authors": [ {"firstname": "firstname", "lastname": "lastname"} ] }, function(html) { 
     actualHtml = html; 
    }); 

    assertEquals("<expected html>", actualHtml); 
}