Angular, Protractor, Jasmine, Chromedriver ja Chrome – timeout bugi

Törmäsin testiautomaatiossa ongelmaan: Aivan yllättäen testiajot päättyvät virheilmoitukseen:

[INFO] A Jasmine spec timed out. Resetting the WebDriver Control Flow.

Tämä siis tapahtuu heti ensimmäistä protractor käskyä annettaessa, mikä se onkaan. Grunt käynnistää iloisesti kyllä testiserverin, ja selenium serverin, kaikki ajurit ja kilkkeet on asennettuna, mutta selaimen kanssa homma ei etene.

Pienen nuuskimisen jälkeen jöytyi johtolanka. Chrome selaimen versio 38 ja 39, sekä nykyinen Chromedriver eivät ole yhteensopivia. Toisin sanoen, kun Chrome pakko-päivittää itsensä uuteen, tuota bugia alkaa ilmenemään muillakin.

https://code.google.com/p/chromedriver/issues/detail?id=928

Ratkaisuja on parikin. Vaihtoehto 1 on tiputella Chrome takaisin versioon 37 – joka toimi – samalla voi joutua tiputtelemaan webdriveriakin ajassa taaksepäin. Sitten pitää estää automaattipäivitykset.

Valitsin toisen tien ja toistaiseksi testiautomaatio pyöriköön Firefoxilla, täytyy seurata tätä mielenkiinnolla. Mutta hyvä tietää jos oudot timeoutit alkavat riivaamaan.

HTML 5, ja muita jorinoita

No niin, HTML 5 pompsahti pari päivää sitten standardiksi, viimein. W3C päivitti draftin moodiin recommendation, ja nyt se on sitten ihan leimaa myöten valmis.

http://www.w3.org/TR/html5/

Sinänsä tällä ei näytä olevan sen suurempia vaikutuksia – HTML5 on ollut de facto standardi jo hetken aikaa, ja toisaalta eiköhän sitä vielä jatkossakin ehosteta tarpeen vaatiessa.

Hauskaa on se, että kuten suurten selainsotien aikaan 90-luvulla, taaskin standardin tuki vaihtelee villisti ja tulkinnat myös. Oman selaimen yhteensopivuutta voi mittailla vaikkapa täältä:

http://html5test.com/

Omalla koneella vasta pyöräytetyt tulokset 555 maksimipisteestä:

Chrome: 512

Firefox: 475

Internet Explorer: 376

Chrome selain Nexus 5 puhelimessa: 497

Eli kuten aina selainten ihmeellisessä maailmassa, standardi on ”standardi”. Siltikin, näin periaatteessa ainakin, monia uusia kikkoja voi käytellä selaimissa. Niiden toimivuutta yksittäisille versioille voi mittaroida myös esim.

http://caniuse.com/

Equals ja Hashcode JPA/Hibernate sovelluksissa

Olen tästä kirjoitellut joskus aiemminkin. Mutta kyseessä siis Java-onjektien equals, hashCode, ja toString metodien toteuttaminen oikein. Periaatteessa ihan perusjuttu, jo ensimmäisissä oppitunneissa opittu, mutta muuttuukin jännittävämmäksi kun otetaan persistentit tietovarastot mukaan. Relaatiotietokantojen kanssa voisi sanoa että suurin osa on toteutettu väärin.

Mitä tällä on väliä? Nämä metodit (no ei sentään toString) astuvat peliin kun olioita puljataan kokoelmissa, tai uusissa Java 8 streameissä. Esim. set ei salli duplikaatteja. Se tarkistaa duplikaatit ja joissain toteutuksissa myös asemoi ’ämpärit’ hashCode ja equals metodien avulla. Jos ne on toteutettu väärin, setit eivät toimi oikein. Sama juttu jos yrität hakea listan metodeilla löytyykö sieltä tietty olio.

Miten tämä voidaan toteuttaa? No tapoja on muutama.

– Jätä toteuttamatta, tässä mallissa pelataan Object luokan oletustoteutuksilla, jotka katsovat equals ja hashCode sisäisen pointterin mukaan, eli pelaavat instanssin perusteella. Näin jos on vaikkapa sama tietokannan rivi ladattu kahteen eri instanssiin, ne ovat eri.

– Toteuta primary keyn perusteella, eli jos id on sama, objektit ovat samat, samoin hashCode lasketaan id:stä. Tässä mallissa heikkoutena on jos on kaksi objektia joiden id on null. Mekanismin mielestä ne olisivat samat. Tämä tulee esiin jos yrität esim. tunkea useampaa instanssia settiin.

– Toteuta business keyn perusteella, eli datasta löytyvän luonnollisen avaimen, esim. sosiaaliturvatunnus, etc. Tämän heikkous on että monella datalla voi olla vaikeaa löytää yksilöivää tietoa ilman kannassa generoitua primary key id:tä.

Lopulta ei ole oikein tai väärin, kunhan dokumentoituja pelisääntöjä noudatetaan (Object-luokan API dokumentaatio) – tärkeintä on tiedostaa mitä valinnasta seuraa koodille. Oletus eli ei equals/hashcodea ollenkaan on huonoin vaihtoehto kannan kanssa pelaavalle koodille. Sitä huonompi on ainoastaan rikkinäinen oma toteutus.

toString metodissa on vähemmän sudenkuoppia, mutta yhden kanssa on oltava tarkkana. Kun metodi tulostaa jäseniensä arvoja, ja jäsenet ovat custom olioita – syntyy helposti nullpointer exceptioneitä tai syklisiä referenssejä jotka johtavat stack overflow exceptioniin (ironista ;). Näissä olisi siis viisainta olla menemättä objektien toString metodeita pitkin navigoimaan, ja tyytyä tulostamaan vain jotain niiden sisältä, esim. id, ja sekin vain kun null arvot on tarkistettu.

Stackoverflow foorumin ihastuttavissa keskusteluissa oli linkki tästä tehtyyn hyvään taulukkoon:

To primary key or not to primary key?

No, tähän on myös toinen hyvä vaihtoehto. Tiedostetaan tämän metodin toiminnan puutteellisuus ja ei nojata siihen liikaa. Onko kaksi oliota sama – sehän riippuu tilanteesta ja tarpeista, eli on enemmänkin dynaaminen algoritmi kuin staattinen totuus. Streamien filter-operaatiot ovat oivallisia korvikkeita tälle. Mutta ellei parempaa pysty keksimään, se perinteinen id kenttä on ihan ok kunhan vain itse pitää rajoitukset mielessään.

Lisäksi pienenä lisä-sudenkuoppana: huomaa että joissain JPA-toteutuksissa liittyy automaagista weavingiä jota suoritetaan ajonaikana. Käytännössä siis kun kutsut get/set metodeita, niihin punotaan automaattisesti tietokantakutsuja mukaan. Näin ollen on eroa viittaatko muuttujaan suoraan, vai get metodi kautta. Lähtökohtana, jos get/set metodit on toteutettu oikein (pelkkiä gettereitä/settereitä, ei sivuvaikutuksia), on parempi mennä metodien läpi kun JPA on pelissä mukana.

Ja täällä erinomaista keskustelua aiheesta. Ei ole helppo kysymys, eikä ole yhtä autoritatiivista vastausta:

http://stackoverflow.com/questions/5031614/the-jpa-hashcode-equals-dilemma

Nexus 6 ja Android L

No niin, Interwebin viidakkorumpu kertoo että tänään julkaistaan Nexus 6 laite ja Android L virallinen versio.

Olen hetken aikaa jo miettinyt olenko kiinnostunut uudesta puhelimesta – siinä on ennätyksellisen iso lähes kuusituumainen näyttö, joka pistää autotelineet uusiksi ja saattaa aiheuttaa jo haasteita pienikätisille ja pienitaskuisille. Onko isompi parempi vai pahempi? Tähän taitaa Google vastata omalla mainosvideollaan..

Eli jokaiselle omansa, ei samaa kaikille. Jotkut tykkää pienestä, toisille ei iso riitä. Luulen että tuo laite joutuu ostoslistalle ja arvioon. Aikanaan pidin viisituumaista laitetta isona, mutta toisaalta olen pitänyt jopa seitsemäntuumaista Nexus tablettia farkkujen etutaskussa. Ei kai auta kuin ottaa selvää mikä on oma mieltymys. Vähän uumoilen että tulen hyvin toimeen kuusituumaisen kanssa. Milloin niitä tänne Suomen perukoille saadaan on toinen kysymys.

Itse Android L on ehdottoman positiivinen päivitys, Material Design UI-filosofioineen. Mutta senhän saa olemassaoleville Nexus 5 puhelimille, ja viidakon legendat kertovat että myös vanhemmille laitteille. Se ei siis itsessään edellytä hardware päivityksiä.

Ei kun virallista julkistusta odottelemaan 😉

[edit] Lollipophan siitä tuli, ja tuossa lisää: http://www.engadget.com/2014/10/15/nexus-6-official/