24 marraskuuta, 2014

Osa 3. Unit testausta JavaScript 'strict mode'

Unit testing

Global on nyt undefined

Kun aloitat koodaamaan 'strict mode'ssa, olet varmaankin aloittamassa projektia aivan alusta, kesken ei kannata yrittää. Strict modessa on täysin uudet säännöt. Ensimmäiseksi esimerkiksi vaikkapa tämä: funktion this muuttuja ei enää sisällä global objektia [window object], vaan se on undefined. Tämä tieto sattumalta mahdollistaa helpon boolean -testin minkä tahansa funktion sisällä, jos this on true, se on global object, ja strict mode ei ole päällä. Jos this on false, eli undefined, strict mode on päällä. 

var varmista = function varmista(testi, msg) { 
     if (!testi) { 
          put("Debug:\n" + msg); 
     };
}; // varmista = itse tehty unit testi

var strictMode = function (){ // palautusarvo Boolean
        return !this;
} // strictMode(); 

varmista (strictMode(), "strict mode: " + strictMode()); 
   // testaa strict mode

Pieni unit test, varmista(), helpottaa testausta, vaikka kesken koodin:

var testi = false; // mikä tahansa boolean -testi
var selkokielinenViesti = "Hei: varmista -testin pitäisi olla true, ei false" 
                        // Kerro tässä mitä olisi pitänyt tapahtua
varmista(testiselkokielinenViesti);

Kun ajat testin (false) -arvolla, saat ilmoituksen:

Err: 
Error: Debug: Hei: varmista -testin pitäisi olla true, ei false
Url: 
 file:///Users/who/Sites/js/barebones/js/main.js
Line: 21 / 34

Saat tietää paitsi oman viestisi, sen lisäksi: 
1: Virheen tyypin,jos sellainen löytyy. Yleensä vain Error:
2. URL tiedostoon, jossa virhe esiintyy.
3. Millä rivillä ja monennessako kirjaimessa virhe esiintyy.

Jos testi on true, ei tapahdu mitään, kaikki on hyvin ja voit unohtaa koko testin.

On myös mahdollista muutella koodia siten, että erityyppiset virheilmoitukset käsitellään eri tavoin ja vaikkapa kerrotaan laajemmin selkokielellä miten kyseinen virhe voi syntyä, tai annetaan linkkejä materiaaliin, mutta tämän esimerkin tarkoitus on vain päästä alkuun.

Ideaali olisi, että ensin kirjoitat testin ja vasta sitten koodin jota testaat. Jätät testikoodin paikalleen, jotta jos joskus muutat vahingossa jotakin testi heti huomaa muutoksen ja varoittaa ei-toivotuista vaikutuksista. Sillä mitä nopeammin huomaat virheen, sitä nopeammin se on korjattu. Testaa siis kaikki koodi kauttaaltaan koko ajan, korjaat sekunnissa kun saat tiedon heti. Jos törmäät virheeseen joskus myöhemmin, et varmaankaan enää muista miten se on syntynyt ja metsästys voi olla pitkällinen prosessi. Testaa myös jokainen työkalusi, tee huolellinen perusta, jolle voi huoletta rakentaa.

Perusidea: Tutkimusten mukaan vanhaa koodia ei enää kukaan uskalla korjailla. Mutta jos kaikki on testattua, uskallat halutessasi ehkä jopa muokata jotakin vanhaa koodiasi, kun aika koittaa. Ja jonakin päivänä tämäkin projekti on kasvanut liian suureksi.

Kommentoi 'use strict' -ilmoitus pois hetkeksi ja testaa saatko siitä ilmoituksen:
var xyz = function () { 
// 'use strict'; // kääre alkaa ...

Lataa sivu uudelleen. Nyt pitäisi tulle virheilmoituksia. Tarkistele.
Muista palauttaa kommentit sitten takaisin, jotta pääset varsinaiseen työhön.

Näin on testipenkki valmis varsinaiseen koodin vääntöön...

Olisi siis tarkoitus rakentaa minimi -ohjelma ja testailla samalla perus -OOP koodeja.
Ja kyllä, tietysti 'strict mode' päällä.

17 marraskuuta, 2014

Osa 2. JavaScript Testipenkki

JavaScript koodin testipenkki 'strict mode' -testeihin.

Script tagissa on hyvä olla onerror -parametri, joka ilmoittaa jos kooditiedostosi ei lataudu, jos esim: osoite on väärin, tms. Virheitä voi olla vaikea jäljittää, jos tiedosto ei ole edes latautunut. Ulkoinen kooditiedosto on kuitenkin erittäin hyvä tapa, ei siis ollenkaan HTML -koodin sekaan JavaScriptiä, jos suinkin mahdollista ja yleensä on.

<script src="js/main.js" onerror="alert('Load Err: ' + this.src)">

Luo main.js -niminen tekstitiedosto ja siihen koodi:

var xyz = function () { 'use strict'; // this is wrapper start ...
       // Only 'strict mode' -experiments here !
}(); // strict mode wrapper end

Käytä funktiota irroittamaan koodi globaalista.

1. Ensin sulkeet: (); - Irrottaa koodin global -objektista
2. Anonyymi funktio toimii kääreenä

function () {} ();

3. Ensimmäinen asia koodissa on ilmoitus: 'strict mode' -joka kertoo selaimelle, että tähän koodialueeseen on suhtauduttava hiukan tiukemmin, kuin mihin on totuttu. Jos lause tulee vasta funktion sisällä, sen vaikutusalue on vain kyseisen funktion sisäinen, tuolloin globaali objekti koodataan kuten tavallisesti, eli strict mode ei ole silloin voimassa globaalilla alueella.

4. Virheilmoituskoodit on hyvä koodailla nyt saman tien, kun kerran testipenkkiä tehdään:
   - virheilmoitus kertoo miltä riviltä bugi löytyi, joten löydät sen nopeammin.

Lisätään Try - cach() - finally  -alueet:

try {  /*debug area*/
window.onerror=function(msg,Url,Ln,ch){
 alert("Window error:\n" + msg + "\nURL: " + Url + "\nLine: " + Ln+"/"+ch);
};
///// TESTIALUE ALKAA - TÄSTÄ ETEENPÄIN SAA MUOKATA ///////////

// Teretuloa 'strict mode' -kokeilujen kentälle !

var put = function(w) {alert('Viesti: ' + w ); };
put("Heippa Maailma"); // testataan 'put' -funktiota

///// TESTIALUE LOPPUU - ÄLÄ MUOKKAA TÄTÄ ALEMPAA ///////////
 } catch (e) { //Tämä blokki ajetaan jos virhe tapahtuu
        throw e; //window.error() kertoo virheen rivinumeron!
} finally { //Tämä blokki ajetaan joka kerta
//alert("'main.js' sivu on ladattu!"); 
} // try

Siinä. Tämä artikkeli ei vielä mitenkään erityisesti käsitellyt strict modea, mutta siihen tullaan seuraavassa. Tämä oli tärkeää vaihe, niin on jatkossa hiukan helpompaa.

Unit -testaus olisi seuraava vaihe...