Do tej pory testy jednostkowe dla javascriptu były dla mnie trochę jak YETI - niby tu i tam się o nich mówi ale trudno mi było znaleźć dowód na ich istnienie. Można oczywiście użyć Selenium i tak też zrobiliśmy ale musiało, poprostu musiało istnieć "lżejsze" rozwiązanie...
Jasmine
No i znalazło się. Jasmine to Javascript napisany do testowania Javascriptu i wio :
1. Pliki źródłowe oraz przykłady zastosowań biblioteki Jasmine można znaleźć tutaj --> http://pivotal.github.com/jasmine/.
2. Generalnie jedyny sposób jaki znalazłem na testowanie zmian w drzewie DOM to odpalenie testów w ramach samej strony. Poniższy kod odpala testy tylko jeśli dołączony jest określony parametr, którego nazwę określimy wcześniej. Czy powinniśmy z tym kodem iść na produkcję? - a dlaczego nie!
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Home</title>
<link rel="stylesheet" type="text/css" href="/resources/jasmine/jasmine.css" />
<script type="text/javascript" src="/resources/jquery.js"></script>
<script type="text/javascript" src="/resources/example.js"></script>
<c:if test="${not empty param.tests}">
<script type="text/javascript" src="/resources/jasmine/jasmine.js"></script>
<script type="text/javascript" src="/resources/jasmine/jasmine-html.js"></script>
<script type="text/javascript" src="/resources/tests.js"></script>
<script type="text/javascript" src="/resources/runJasmine.js"></script>
</c:if>
</head>
<body>
<div id="result"></div>
<div id="clickMe">Click me</div>
</body>
</html>
3. Możemy się nawet pobawić w TDD - tworzymy pierwszy test :
describe("A suite", function() {
it("has a blue background after click", function() {
//given
var clickMe=$($("#clickMe"));
//when
clickMe.click();
//then
expect(clickMe.css("background-color")).toBe("rgb(0, 0, 255)");
});
});
Który oczywiście nie przechodzi : 4. Implementujemy funkcję :
$(document).ready(function() {
$("#clickMe").click(function() {
$(this).css("background-color", "blue");
});
});
I działa : Możemy sobie teraz zmieniać, ciąć i modyfikować javascript bez bólu, że znowu ni z ch.. ni z owego wszystko przestanie działać. (i tak przestanie ale teraz przynajmniej dokładnie kontrolujemy co psujemy)
Da się? Da się!.
A co z Ajaxem
A co jeśli chcemy przetestować wywołanie asynchroniczne? Też nie ma z tym problemu.
1. Kod na serwerze :
@RequestMapping(value = "/add", produces = "application/json", method = GET)
public @ResponseBody
Integer add(@RequestParam Integer firstNumber,
@RequestParam Integer secondNumber) throws IOException {
return firstNumber + secondNumber;
}
2. W teście trzeba dodać trochę rzeźby aby upewnić się, że wywołanie asynchroniczne się zakończyło. Funkcje runs oraz waitsFor są z Jasmine :
it("adding two positive numbers uusing ajax", function() {
//given
var firstNumber=1;
var secondNumber=2;
//when
runs(function() {
add(firstNumber,secondNumber);
});
waitsFor(function() {
var result=$("#result").text();
return result.length>0;
}, "Async call to long", 1000);
//then
runs(function() {
expect($("#result").text()).toBe('3');
});
});
3. Implementacja :
$.get("add", {firstNumber : first,secondNumber : second},
function(data) {
$("#result").text(data);
});
Ogólna ocena
Moja produktywność pracy z Javascriptem skoczyła o jakieś 69% gdyż już nie trzeba się przeklikiwać przez wszystkie przypadki użycia interfejsu po każdej zmianie w skrypcie. Biblioteka godna polecenia.
Brak komentarzy:
Prześlij komentarz