Miltä näyttää yritysten toiminnanohjaus 2020-luvulla?

Blogitekstit • Digitalisaatio • Teknologia

Sanasta toiminnanohjausjärjestelmä, lyhemmin ERP, tulee ensimmäisenä mieleen raskas ja vaikeakäyttöinen tietojärjestelmä, joka yrityksen toiminnan sujuvoittamisen sijaan lähinnä hankaloittaa sitä. ERPit (Entreprise Resource Management) ovat kuitenkin viimeisen parin vuoden ajan eläneet murrosvaihetta, jota koronapandemia on entisestään kiihdyttänyt. ERPin tarkoituksena on aina ollut parantaa yrityksen liiketoimintaa: se on ollut työkalu niin talouden kuin tuotannon ja jakeluketjun hallintaan. Vanhat on-premises-toiminnanohjausjärjestelmät ovat kuitenkin vaatineet yritykseltä resursseja sekä järjestelmän käyttöönotossa että sen ylläpidossa, joista vastuu onkin usein kasautunut ”IT-puolelle” yrityksen muiden työntekijöiden jäädessä ihmettelemään järjestelmää ja sen tuomia ”etuja”. 2020-luvulla toiminnanohjausjärjestelmät eivät kuitenkaan ole enää näitä 90-luvun ATK-tuulahduksia – ne ovat ketteriä yrityksen bisnestä buustaavia järjestelmiä! 

Itsestään selvin ja yksi näkyvimmistä muutoksista toiminnanohjauksessa on palvelujärjestelmien muuttuminen pilvipohjaisiksi. Vanhoissa on-premises-ratkaisuissa yritystä kuormittavat käyttöönottokustannusten lisäksi kiinteät laite- ja käyttökustannukset, minkä vuoksi esimerkiksi startup-yrityksellä ei välttämättä ole mahdollisuutta tai halua sijoittaa kalliiseen järjestelmään. Pilvipohjainen palvelu mahdollistaa yritykselle sekä nopean käyttöönoton että matalammat kustannukset, kun yritys maksaa palvelusta kuukausittain vain käytön mukaan. Toinen ja yksi keskeisimmistä pilvipohjaisuuden eduista on se, ettei yrityksen itse tarvitse huolehtia järjestelmän ylläpidosta tai päivityksistä – palveluntarjoaja pitää järjestelmän kunnossa ja ajan tasalla.  

Koronaviruspandemian myötä yrityksillä on tarve yhä paremmalle ja tarkemmalle riskienhallinnalle sekä resurssien ohjaamiselle mahdollisimman tehokkaasti. Samalla etätyön määrä on kasvanut räjähdysmäisesti. Pilvipohjainen ERP mahdollistaa palvelun käytön ajasta ja paikasta riippumatta. Nykyaikainen ERP ei ole siis enää IT-osaston käyttämä järjestelmä, vaan liiketoiminnan ohjaukseen voivat osallistua kaikki yrityksen tekijät ja sidosryhmät, jolloin tiedon kulku tapahtuu ilman mutkia ja viivästyksiä. Toiminnanohjausjärjestelmä takaa luotettavan ja tarkan tiedon reaaliaikaisesti – ja juuri siihen yrityksen tulisikin päätöksentekonsa perustaa! Ajantasainen data mahdollistaa sekä toiminnan ennakoinnin että muutokset toimintaan lyhyelläkin varoitusajalla. 

Yksi nykyaikaisten toiminnanohjausjärjestelmien eduista on kerätyn datan analysointi tarkoituksenmukaisesti ja tarkasti. Kun päätöksiä yrityksessä halutaan tehdä tietoon nojaten, on tarve analyysiperusteisille ratkaisuille: yritykset, jotka käyttävät analysointityökaluja, tekevätkin kaksi kertaa todennäköisemmin vahvaa taloudellista tulosta, viisi kertaa todennäköisemmin kriittisiä ratkaisuja nopeasti ja kolme kertaa todennäköisemmin toteuttavat tehtyjä päätöksiä ja suunnitelmia tehokkaasti! Pääsy reaaliaikaiseen dataan ja sen analyysiin tuo toisin sanoen merkittäviä hyötyjä yritykselle. Toimintavarmuuden ja ketteryyden lisäksi data-analyysi parantaa bisnestä mahdollistamalla paremman asiakaskokemuksen tarjoamisen. Yritys voi seurata esimerkiksi asiakkaan ostohistoriaa ja kulutuskäyttäytymistä, jolloin yritys voi lisätä sekä myyntiään että sitoutumista toimimalla asiakkaan mieltymysten mukaisesti. 

2020-luvulla ERPin ehdottomia etuja on se, että palvelu on räätälöitävissä yrityksen yksilöllisten tarpeiden mukaiseksi, ja sen käyttöä voidaan laajentaa uusiin kohteisiin tarpeen mukaan. 2020-luvun ERP on käyttäjäkeskeinen, joustava ja saavutettava – työkalu, joka on suunniteltu yrityksen kaikkien työntekijöiden käyttöön! 

Palveluväylästä lyhyesti

Blogitekstit • Digitalisaatio • Teknologia

Palveluväylä on hämäävästi nimetty tiedonsiirtoalusta, joka nimestään huolimatta ei perustu ESB (Enterprise Service Bus) -malliseen integraatioon vaan X-ROAD-teknologiaan. Teknologia on alunperin Viron sähköisen hallinnon toimintoihin kehittetty integraatioratkaisu, joka on myöhemmin julkaistu avoimena lähdekoodina. Nykyään sen kehityksestä vastaa Nordic Institute for Interoperability Solutions (NIIS.org). Sähköisellä hallinnolla tarkoitetaan Internetiin tuotuja julkisia palveluita. Käytännössä voidaan puhua julkisen hallinnon Internet-käyttöliittymistä. Tyyppilisiä sähköisen hallinnon tarjoamia asiointipalveluita ovat vero-, sosiaaliturva- ja päätösasiat.

X-ROAD teknologia tarjoaa vakioidun ja tietoturvallisen tavan siirtää tietoa eri osapuolien välillä. X-Road koostuu liityntäpalvelimista (secure server) ja keskuspalvelimista (central server). Keskuspalvelin vastaa hallinnoinnista, lokituksesta ja varmentamisesta – liityntäpalvelimet taas toimivat kuluttajien (consumer) ja tuottajien (producer) välillä tiedonsiirrossa. Palveluväylän toiminnasta ja ylläpidosta vastaa Digi- ja väestötietovirasto.

Kuten arvata voikin, palveluväylään liittymistä varten tarvitaan oma liityntäpalvelin. Liityntäpalvelimen pystyttäminen on nykyään hiukan käsittelyajoista riippuen helppo ja nopea toimenpide. Liityntäpalvelinta pystyttäessä luodaan allekirjoitus- ja autentikointivarmenteet, jotka toimitetaan DVV:lle allekirjoitettaviksi. DVV:n allekirjoittama varmenne mahdollistaa liityntäpalvelimen liittämisen keskuspalvelimeen. Tämän jälkeen muita palveluväylän alipalveluita voidaan lisätä omien palveluiden käyttäjiksi. X-Roadin liityntäpalvelinta hallitaan web-käyttöliittymän kautta.

Palveluväylällä on olemassa kolme eri ympäristöä: FI-DEV, FI-TEST ja FI. Näistä kolmesta FI on tuotantoympäristö; muut ovat testauskäyttöön. Kehitysympäristö eli FI-DEV on avoin kehitysympäristö, johon voi hakea käyttöoikeuden myös yksityishenkilönä. FI-TEST on taas enemmin testiympäristö, joka vaaditaan palveluiden toimivuuden testaukseen ennen tuotantokäyttöä.

Liityntäpalvelimen ja siihen liittettävän palvelun väliin on tarpeiden mukaan hyvä liittää sovitinpalvelu, joka hoitaa WSDL-kuvauksen (=teknisen kuvauksen) mukaisen parsinnan kutsuille ja palauttaa oikeassa SOAP-muotissa kyselyn vastauksen. XRD4J -javaliitännäisellä tämä on helppo toteuttaa.

Kaiken viranomaisten välisen tiedonsiirron tulisi tapahtua nykyään palveluväylän kautta, mutta se tarjoaa myös yksityisille toimijoille vakioidun ja luotettavan tavan tiedonhallintaan. Jos teillä on tarvetta erillaisille ratkaisuille liityntäpalvelimista adaptereihin, me Joinexilla mielellään autamme sinua helpottamaan arkeasi.

Työvelvollisuusrekisteri

Caset • Teknologia

Työvelvollisuusrekisteri – varautumista poikkeustilanteisiin

Omasivari

Caset • Teknologia

Omasivari – Siviilipalvelus haltuun ajasta ja paikasta riippumatta

Tekninen velka voi johtaa konkurssiin

Teknologia • Yleinen

Tekninen velka tarkoittaa ohjelmiston kehityksessä syntyvää toteutusvelkaa. Joskus on perusteltua tehdä jokin ominaisuus nopeasti (quick and dirty) tiedostaen, että oikominen johtaa tulevaisuudessa lisätyöhön ominaisuuden muuttamisen tai ylläpitämisen suhteen.

Tekninen velka syntyy, kun ei ole mahdollisuutta, aikaa tai kykyä investoida työtä jonkun asian tekemiseen kestävällä tavalla. Kuten taloudelliseen velkaan, myös tekniseen velkaan liittyy korko. Korko on se lisätyö, joka joudutaan laittamaan sen asian jatkokehittämiseen, jonka tekemisessä alunperin oiottiin. 

Velkaa voidaan poistaa investoimalla kehitykseen myöhemmin, eli teknisen velan korkoa voidaan pienentää poistamalla huono ratkaisumalli. Korkoja voidaan toisaalta maksaa, jos korkotaso pysyy matalana ja velan poiston vaatima investoinnin hinta on korkea. Huonoimmassa tapauksessa velka kasvaa koko ajan, samoin korko, ja lopulta edessä on konkurssi – koko ohjelmiston uudelleenkirjoitus.

Teknisen velan ajatus on kohtuullisen yksinkertainen ja havainnollistava, mutta sen mittaaminen on hankalaa. SonarQube:lla on tähän mittari, jolla mittaaminen ei kuitenkaan ole ongelmatonta: mittarin osoittamat työmäärät velan poistamiseksi ovat noin 14-kertaiset testattaessa toteutuneisiin työmääriin nähden (testattu yksittäisessä projektissa). Ansioistaan huolimatta SonarQube ei myöskään arvioi perusteellisesti suunnittelun ja arkkitehtuurin velkaa, mikä edellyttäisi sekä asioiden arvioimista kokonaisuuksina että sisällön ymmärtämistä. SonarQube arvioi tehokkaasti yksittäisiä tiedostoja ja niiden formaaleja ominaisuuksia, mutta sisällön ymmärtämiseen tarvitaan ihmistä.

Sekä teknisen velan syntymiseen että koodin laatuun voi koodaaja vaikuttaa itse: teknisen velan syntyminen vahingossa ja huomaamatta pitää estää, ja työkalujen lisäksi tärkeimmät aseet siihen ovat ongelman tiedostaminen ja oikea toimintamalli.

Teknisellä velalla on suora (joskin käänteinen) yhteys laatuun ja laadunvarmistukseen: mitä suurempi tekninen velka, sitä heikompi laatu ja laadunvarmistus. Johdatuksen aiheeseen saat lukemalla esimerkiksi lopussa olevia lähteitä.

Takaisin otsikkoon: tarvitseeko velka maksaa takaisin? Pandemian ja siihen liittyvän keskuspankkielvytyksen myötä esitetty kysymys nousi esiin poliittiselta taholta, mutta sai varovaista vastakaikua myös talousasiantuntijoilta. Ehkä taloudellista velkaa on järjestelmän uskottavuuden nimissä pidettävä takaisinmaksettavana, mutta taloudellinen velka on validi vain niin kauan kuin velallinen on olemassa.

Myös tekninen velka raukeaa, kun ohjelmistosta aika jättää. Ohjelmiston elinkaaren pituus on joskus vaikeasti hahmotettavissa, ja väliaikaiseksi ajateltu ratkaisu voi osoittautua kovin sitkeähenkiseksi, kun taas hartaudella rakennettu ohjelmisto ei välttämättä koskaan näe tuotannon käynnistystä. Herääkin kysymys: kannattaako laatuun panostaa lainkaan? Kyllä kannattaa, sillä laadun rakentaminen kehityksen yhteydessä ei tuo lisätyötä verrattaessa laaduttomuuteen, johon palaa helposti enemmän aikaa kerrannaisvaikutuksina. Olennaista on laadun syntyminen tekemisen pisteessä – ei testauspisteessä.

http://martinfowler.com/bliki/TechnicalDebt.html

http://www.sonarqube.org/

https://en.wikipedia.org/wiki/Technical_debt

http://www.agiledeveloper.com/presentations/caring_about_code_quality.pdf

React-lomakkeiden testaaminen käytännössä

Teknologia

Esitin edellisessä kirjoituksessa näkemykseni siitä, miten React-komponentteja kannattaa testata, ja mihin testityökaluihin päädyin. Tällä kertaa sukelletaan testin ATV-rakenteeseen ja testataan React-lomaketta koodiesimerkkien avulla.

Alkuvalmistelut

Testaamiseen tarvitsemme seuraavat työkalut: Jest, jest-dom, React Testing Library ja user-event. En tässä käy läpi, miten nämä asennetaan tai paneudu kovin yksityiskohtaisesti siihen, miten testiajoja konfiguroidaan. Create React App -pohjaisissa sovelluksissa Jest on asennettu valmiiksi, ja testiajon voi käynnistää komentoriviltä komennolla:

npm run test # Suorittaa package.json tiedostossa olevan "test"-komennon

Muiden kuin Create React App -pohjaisten sovellusten kohdalla suosittelen vilkaisemaan Jestin selkeää dokumentaatiota.

# Suorittaa testejä ja jää kuuntelemaan muutoksia
# niiden kohteina oleviin tiedostoihin
jest --watch

Kirjoitan testit aina niiden komponenttien viereen, jotka ovat testauksen kohteena. LoginForm.jsx-komponentin vierestä löytyy LoginForm.test.jsx-niminen testitiedosto. Jest tunnistaa tällä tavalla nimetyt tiedostot ja osaa käynnistyessään ajaa niissä määritellyt testit.

// LoginForm.test.jsx
describe('LoginForm', () => { // Ryhmä, lohko tai muu vastaava!
  test('näyttää virheen kun lomake lähetetään puutteellisena', () => { // Testi
    /* Testin kaikki vaiheet tehdään täällä */
  });
});

Yksi testitiedosto voi sisältää useita testejä. Näitä voi halutessa ryhmitellä describe-lohkoihin, joita itsessään voi edelleen ryhmitellä describe-lohkoihin. Näin testit pysyvät järjestyksessä ja ongelmia tuottava testi on helppo paikallistaa. Jestin näppärällä komentorivityökalulla voi kätevästi suorittaa vain halutun nimiset tai tietyssä lohkossa olevat testit.

Mönkijä kiipeää rakennusmateriaalien päältä valmiin rakennelman huipulle

ATV: Aseta, Toimi, Varmista

Testauksen kulmakiveksi on vakiintunut Aseta, Toimi, Varmista -malli (englanniksi Arrange, Act, Assert).

  • Reactin kontekstissa ensin asetetaan DOM siihen tilaan, jossa sitä halutaan testata. Käytännössä tämä tarkoittaa jonkin komponentin renderöimistä.
  • Seuraavaksi toimitaan esimerkiksi painamalla painiketta tai muuttamalla lomakekentän arvoa.
  • Lopuksi varmistetaan, että toiminnasta aiheutui juuri ne seuraukset, jotka pitikin.

Aseta

React Testing Libraryn render-metodilla luodaan testattava komponentti ja annetaan sille tarvittavat propit. Tämän nimenomaisen render-metodin käyttö on tärkeää, koska ilman sitä emme myöhemmin pysty vuorovaikuttamaan renderöityjen elementtien kanssa.

// LoginForm.test.jsx
import { render } from '@testing-library/react';
import LoginForm from './LoginForm';

describe('LoginForm', () => {
  test('näyttää virheen kun lomake lähetetään puutteellisena', () => {
    // Aseta: renderöidään LoginForm komponentti
    render(<LoginForm />);
  });
});

Toimi

Kirjoittamamme testin tarkoitus on varmistaa, että käyttäjälle näytetään virheilmoitus, jos lomake lähetetään puutteellisena. Puutteellisuus voi tarkoittaa käytännössä mitä haluamme; jonkin kentän arvo on tyhjä, salasana on liian lyhyt tai käyttäjätunnus ei läpäise annettua validaattoria. Kaikki riippuu siitä, miten LoginForm-komponentti on toteutettu ja mitkä kaikki syötteet se hylkää (tai kääntäen, mitä haluamme sen hylkäävän, jotta testi menee läpi!). Sovitaan tässä kohtaa, että haluamme lähetyksen epäonnistuvan silloin, kun joko käyttäjätunnus- tai salasanakenttä on tyhjä. Luodaan ensin testi, jossa käyttäjätunnukselle annetaan arvo, mutta salasanalle ei.

// LoginForm.test.jsx
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import LoginForm from './LoginForm';

describe('LoginForm', () => {
  describe('näyttää virheen, kun lomake lähetetään', () => {
    test('ilman salasanaa', () => {
      // Aseta: renderöidään LoginForm komponentti
      render(<LoginForm />);

      // Toimi: etsitään käyttäjätunnuksen syöttökenttä
      const kayttajatunnusInput = screen.getByLabelText('Käyttäjätunnus');

      // Toimi: muutetaan käyttäjätunnuskentän arvoa
      userEvent.type(kayttajatunnusInput, 'kroisos.pennonen');

      // Salasanakenttään ei kosketa!

      // Toimi: lähetetään lomake etsimällä ensin lähetä-painike
      userEvent.click(screen.getByText('Kirjaudu'));
    });
  });
});

Toimimisen perustana on React Testing Libraryn screen. Sen avulla voimme vuorovaikuttaa synteettisellä testiruudullamme olevan sisällön kanssa. Käytämme edellä paria React Testing Library querya renderöityjen elementtien löytämiseen. getByLabelText hakee elementin, jonka <label>-elementin tekstisisältönä on annettu merkkijono. Voimme tehdä näin, koska LoginFormin toteuttanut koodari on antanut vastuullisesti kaikille lomakekentille labelit (tai jos ei ole, testi epäonnistuu ja sellainen pitää lisätä!). getByText puolestaan hakee elementin, jonka tekstisisältö on annettu merkkijono. Tämä soveltuu oikein hyvin painikkeiden hakemiseen.

React Testing Libraryn query-dokumentaatiossa on selkeästi kerrottu näiden hakufunktioiden toiminnasta. Suosittelen jättämään sen välilehteen auki ensimmäisiä testejä kirjoittaessasi!

Käyttäjän toimintojen matkimiseksi käytämme user-event-kirjaston type– ja click-funktioita. Kuten kaikki user-event-kirjaston funktiot, näiden vaikutukset ovat niiden nimien perusteella itsestään selviä. Testikäyttäjämme kirjoittaa käyttäjätunnuskenttään ja klikkaa ”Kirjaudu”-painiketta.

Varmista

Lopuksi haluamme varmistaa, että edellisten toimien seurauksena käyttäjälle todellakin näytetään virheilmoitus.

// LoginForm.test.jsx
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import '@testing-library/jest-dom';                      // Uusi!
import LoginForm from './LoginForm';

describe('LoginForm', () => {
  describe('näyttää virheen, kun lomake lähetetään', () => {
    test('ilman salasanaa', () => {
      // Aseta: renderöidään LoginForm komponentti
      render(<LoginForm />);

      // Toimi: etsitään käyttäjätunnuksen syöttökenttä
      const kayttajatunnusInput = screen.getByLabelText('Käyttäjätunnus');

      // Toimi: muutetaan käyttäjätunnuskentän arvoa
      userEvent.type(kayttajatunnusInput, 'kroisos.pennonen');

      // Salasanakenttään ei kosketa!

      // Toimi: lähetetään lomake etsimällä ensin lähetä-painike
      userEvent.click(screen.getByText('Kirjaudu'));

      // Varmista: varmistetaan, että näytöltä löytyy virheestä ilmoittava teksti
      expect(
        screen.getByText('Unohtuiko salasana?'),
      ).toBeInTheDocument();
    });
  });
});

Viimeinen importimme on jest-dom. Sen avulla voimme näppärästi varmistaa kaikenlaisia DOM-elementteihin liittyviä asioita. Tässä tapauksessa meille riittää pelkästään sellaisen olemassaolo, kunhan tekstisisältönä on ”Unohtuiko salasana?”.

Kas näin! Ensimmäinen testimme on paketissa. npm run test komentoriville ja se suoritetaan automaattisesti.

Jo opituilla menetelmillä voimme helposti tarkistaa myös tapaukset, joissa salasana tai molemmat lomakkeen kentät ovat tyhjiä:

// LoginForm.test.jsx
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import '@testing-library/jest-dom';
import LoginForm from './LoginForm';

describe('LoginForm', () => {
  describe('näyttää virheen, kun lomake lähetetään', () => {
    test('ilman salasanaa', () => {
      // Tätä testiä on hieman typistetty
      render(<LoginForm />);

      const kayttajatunnusInput = screen.getByLabelText('Käyttäjätunnus');
      userEvent.type(kayttajatunnusInput, 'kroisos.pennonen');
      userEvent.click(screen.getByText('Kirjaudu'));

      expect(
        screen.getByText('Unohtuiko salasana?'),
      ).toBeInTheDocument();
    });

    test('ilman käyttäjätunnusta', () => {
      render(<LoginForm />);

      const salasanaInput = screen.getByLabelText('Käyttäjätunnus');
      userEvent.type(salasanaInput, 'roopeAlas€€€2020');
      userEvent.click(screen.getByText('Kirjaudu'));

      expect(
        screen.getByText('Unohtuiko käyttäjätunnus?'),
      ).toBeInTheDocument();
    });

    test('tyhjänä', () => {
      render(<LoginForm />);

      userEvent.click(screen.getByText('Kirjaudu'));

      expect(
        screen.getByText('Anna nyt edes jotain tietoja!'),
      ).toBeInTheDocument();
    });
  });
});

Voit varmaankin kuvitella miltä näyttäisi testi, joka testaa lomakkeen onnistunutta lähetystä?

Jatkan tästä vielä myöhemmin kirjoituksella, jossa käyn kevyesti läpi isomman sovelluksen testaamisen haasteita ja mockausta. Mitä tehdä, kun komponentti vaatii toimiakseen jotain korkealla komponenttipuussa asuvaa dataa, kuten teeman, Routerin tai lokalisaatiotietoja? Palaan näihin tuonnempana. (Seuraa meitä Twitterissä, niin saat tiedon uusien kirjoitusten ilmestymisestä!)

Liikkeelle React-komponenttien testaamisessa

Teknologia

Olen pitänyt ajatusta käyttöliittymien testauksesta haastavana. Selain on niin monimutkainen ympäristö – miten siellä testaaminen toimii käytönnössä? Kannattaako testien laatimiseen käyttää aikaa? Mitä ylipäätään kannattaa testata?

Mikä on testaamisen arvoista?

Refaktoroidessani Omasivarin lomakkeita huomasin nopeasti pallottelevani editorin ja selaimen välillä. Vaihdoin yhden tekstikentän toteutusta, jonka jälkeen kokeilin, päivittyikö sen arvo edelleen oikein, sainko virheilmoituksen syöttäessäni sähköpostiosoitteen väärin ja vähän kaikkea muuta, mitä keksin kokeilla. Sama toistui seuraavan kentän kanssa. Ja seuraavan. Ja seuraavan, kunnes lopulta aloin kokeilemaan, lähetetäänkö kaikki tiedot todella palvelimelle, kun painan lomakkeen lähetyspainiketta. Entä jos pakollinen etunimikenttä on tyhjä ja tilinumeron tilalla on tuliemoji? 🔥

Seuraavaa lomaketta työstäessäni uskalsin jo muuttaa kaikkien kenttien toteutukset kerralla ja näpertää selaimen kanssa vasta sitten. Kävin silti kaikki mahdolliset validaatiovirheet läpi manuaalisesti. Kolmannen lomakkeen kohdalla aloin jo kyllästyä samojen asioiden toistamiseen. Päätin luoda Omasivarin ensimmäisen testin.

Ennen tätä lomakekoettelemusta en ollut osannut tunnistaa kehittämistäni sovelluksista sellaisia osia, jotka olisivat hyötyneet automatisoiduista testeistä. Tästä viisastuneena ymmärsin, että testaaminen kannattaa aloittaa sellaisista komponenteista, joita huomaa testaavansa toistuvasti käsin. Usein tätä tehdään juuri lomakkeiden kanssa, joiden kentissä olevat arvot määrittävät muun muassa sen, tuleeko lisätietokenttiä näyttää tai saako lomaketta edes lähettää. Testi tekee kaiken käsityön muutamassa sekunnissa ja takaa lomakkeen toimivan halutulla tavalla seuraavankin kerran, kun sitä pitää muuttaa.

Mitä testataan?

Edellä kuvaamani testauksen lähtökohtana on tarve toistaa käyttäjän tekemiä toimintoja. Kirjoitettavien testien tulisi siis varmistaa, että näiden toimintojen seurauksena tapahtuu juuri sitä, mitä halutaan tapahtuvan. Käyttäjä syöttää lomakkeen tiedot oikein ja lomake lähetetään. Tyhjäksi jätetty pakollinen kenttä johtaa puolestaan virheilmoituksen näkymiseen.

Käytetään esimerkkinä tapausta, jossa käyttäjä yrittää kirjautua sovellukseen ilman salasanaa. Lomake huomaa puuttuvan tiedon ja huomauttaa tästä käyttäjälle.

Havainnollistava kuva kirjautumissivusta

Testissä voidaan varmistaa, että lomakkeen renderöivän React-komponentin sisäinen tila muuttuu kuvaamaan virhetilannetta. Tätä kutsutaan implementaation testaamiseksi: ei tutkita käyttäjälle näkyvää toiminnan seurausta vaan tapaa, jolla lopputulosta tavoitellaan. Testi onnistuu, jos jokin muuttuja saa arvokseen Error objektin, mutta on vaarallista olettaa sen johtavan automaattisesti ruudulla näkyvään virheilmoitukseen.

On luotettavampaa testata komponentin käyttäytymistä käyttäjän näkökulmasta. Tutkitaan oikeasti renderöityä HTML-dokumenttia ja etsitään sieltä elementtiä, joka kertoo virheestä käyttäjälle. Testi onnistuu, jos elementti löytyy.

Kuvituskuva painikkeen implementaatiosta versus käyttäytymisestä

Mikään ei kuitenkaan ole mustavalkoista. Joskus voi huomata testaavansa implementaatiota vahingossa. Toisinaan se voi olla perusteltuakin. Vaikeinta on löytää itsensä jostain näiden rajamailta.

Millä React-komponentteja testataan?

Omaan testityökalupakkiini päätyivät seuraavat työkalut:

  • Jest – pyörittää koko testikoneistoa
  • jest-dom – tarjoaa varmistuksia HTML-dokumentin testaamiseen
  • React Testing Library – työkaluja DOM-elementtien etsimiseen ja manipuloimiseen intuitiivisella tavalla
  • user-event – simuloi käyttäjän tekemiä toimintoja todella helppokäyttöisesti

Kokeilin seuraavia työkaluja, mutta jätin ne tarkoituksella pois:

  • Enzyme – täyttää saman roolin kuin React Testing Library, mutta painottaa enemmän implementaation testaamista ja React-komponenttien sisäisen tilan tutkimista.

Jatkan seuraavassa kirjoituksessa käytännöllisemmillä esimerkeillä React-lomakkeiden testaamisesta. Käydään siellä läpi miten testi luodaan, mistä osista se koostuu, ja kuinka testejä ajetaan.

KEHA-keskus

Caset • Teknologia

KEHA-keskus – Sähköistä viestinvälitystä Suomi.fi-viestit palvelun kautta

React hooks – React blogi part 2

Teknologia

Matrix-kuva "What if I told you functions can have state"-tekstillä

Otetaanpas jälleen kevyt tekstin aloitus asiaan liittyvällä meemillä.

Yleistä React hookeista

  • Hookit ovat täysin taaksepäin yhteensopivia.
  • Hookkeja ei ole pakko käyttää. Niitä voi helposti testata muutamassa komponentissa ilman, että joutuu kirjoittamaan olemassa olevaa koodia uusiksi.
  • Luokat eivät ole poistumassa Reactista.
  • Hookit tuli käytettäväksi Reactin 16.8 versiossa.

Mitä Hookit ovat?

Ne ovat funktioita, joilla voi hallita Reactin tilaa ja ”napata” kiinni elinkaaren (lifecycle) ominaisuuksiin funktionaalisissa komponenteissa. Hookkeja ei voi käyttää luokka-komponenteissa – ne sallivat Reactin käytön ilman luokkia.

Osalle JavaScript-luokkien käyttö on saattanut aiheuttaa päänvaivaa, sillä ne eroavat muiden kielien luokista melkoisesti. Luokkia voi kuitenkin huoletta käyttää jatkossakin, sillä ne eivät ole Reactista poistumassa.

Hookeilla voidaan ”kaivaa” tilallista logiikan komponenteista, joita voidaan riippumattomasti testata ja uudelleen käyttää. Hookit sallivat tilallisen logiikan uudelleenkäytön muuttamatta komponentin hierarkiaa. 

Hookit ovat JavaScript funktioita, mutta niillä on kaksi sääntöä:

  • Hookkeja ei saa kutsua looppien sisällä tai nestatuissa funktioissa.
  • Hookkeja ei saa kutsua tavallisista JavaScript funktioista –niitä voi käyttää vain Reactin funktionaalisissa komponenteissa.

Omasta kokemuksesta voin sanoa, että funktionaaliset komponentit + hookit yksinkertaistavat React-devausta ja ovat nopeampia oppia verrattuna luokka-komponentteihin.

Mitä Hookit korvaavat?

  • Luokat
  • Render Prop kuvion

Hieman vaihtelevaa mielipidettä on siitä, mitä ne eivät korvaa. Muutamia on tullut vastaan tuolla internetin ihmeellisessä maailmassa, mutta teemaksi on alkanut muotoutua esimerkiksi seuraavat:

  • Redux
  • Higher Order Components (HOC)

Tässä täytyy nyt mainita, että luokka-komponenttien kanssa HOC tulee epäilemättä pysymään käytössä, mutta funktionaalisissa komponenteissa sen voi korvata custom hookeilla. Täältä käytännön esimerkkiä kuinka korvata HOC custom hookeilla: https://dev.to/gethackteam/from-higher-order-components-hoc-to-react-hooks-2bm9

Erityisesti Reduxin suhteen tuntuu olevan paljon mietintää siitä, voivatko Hookit sen korvata. Reduxin käytöllä on omat etunsa, etenkin koko sovelluksen tilaa hallittaessa. Hookkeja käytettäessä taas ei tarvitse latailla/asentaa mitään riippuvuuksia. Molemmissa on puolensa, joten voidaan todeta, että riippuu täysin tilanteesta, sovelluksen koosta ja tarpeesta, kumpaa kannattaa käyttää; oman sovelluksen osalta ratkaisua kannattaa harkita ja päätös tehdä tilannekohtaisesti.

Lähteet ja lisää luettavaa

https://joinex.fi/react-pahkinankuoressa/

https://reactjs.org/docs/hooks-intro.html

https://medium.com/javascript-scene/do-react-hooks-replace-redux-210bab340672

https://www.simplethread.com/cant-replace-redux-with-hooks/

Suomi.fi-viestit osana EU:n digitaalista palveluväylää

Digitalisaatio • Teknologia

Asetus digitaalisen palveluväylän perustamisesta hyväksyttiin EU:n neuvostossa 27.9.2018. Palveluväylän on tarkoitus mahdollistaa esimerkiksi muuttoon, työskentelyyn tai opiskeluun liittyvien asioiden hoitamisen kaikissa jäsenmaissa digitaalisia kanavia pitkin. Asiointi tapahtuu euroopanlaajuisen Sinun Eurooppasi -portaalin kautta. Määräaikaa palveluiden sähköistämiselle on annettu vuoteen 2023 asti.

Tämä päätös pakottaa jäsenmaita uudistamaan järjestelmiään niin, että niitä voidaan käyttää kokonaan verkon välityksellä. Lisäksi kansalaisille tarjottavien palveluiden tulee noudattaa yksi tieto yhteen kertaan -periaatetta jonka mukaan tietoa ei saisi kysyä uudestaan, mikäli se on jo toisessa EU-maassa käyttäjästä olemassa. 

“Julkisen hallinnon asiakkuusstrategian mukaan viranomaisten tulee huolehtia siitä, että sähköinen kanava on asiakkaalle houkuttelevin vaihtoehto.”

Valtiovarainministeriö 2019

Laki digitaalisten palveluiden tarjoamisesta tuli voimaan 1.4.2019, ja se velvoittaa julkishallinnon toimijoita tarjoamaan jokaiselle mahdollisuuden asiointiin ja asiakirjojen lähettämiseen sähköisesti. Väestörekisterikeskuksen ylläpitämä Suomi.fi-palvelu on tärkeä osa näitä digitaalisia palveluita, ja tulevina vuosina pääpaino kehittämisessä onkin etenkin Suomi.fi-palvelun eri osa-alueissa, kuten Tunnistuksessa, Valtuutuksissa ja Viestit-palvelussa.

Suomi.fi-viestien kautta asioita voidaan hoitaa tunnistautuneena, luotettavasti ja turvallisesti. Käyttäjien määrä on kasvussa, ja elokuussa 2019 palvelua käytti yli 230 000 suomalaista. Käyttäjämäärä on yli kaksinkertaistunut vuodesta 2018. 

Viranomaisen lähettäessä salassa pidettävää tietoa tulee varmistua vastaanottajan henkilöllisyydestä. Perinteinen sähköposti ei siis ole tietoturvaltaan riittävä tällaiseen viestintään. Tällä hetkellä viestien lähettäminen tapahtuu suomalaisen henkilötunnuksen perusteella, mutta myös henkilötunnuksettomien käsittely tulee myöhemmin mahdolliseksi. Tietopyyntö tai viesti voi siis jatkossa tulla myös muusta EU-maasta.

Viestit-palvelu on usein integroitavissa osaksi olemassa olevaa järjestelmää, eikä kokonaan uutta järjestelmää tarvita. Samalla voidaan ottaa käyttöön myös muita Suomi.fi -palveluita, jolloin yhä enemmän toimintoja saadaan uuden palveluväylän piiriin. Esimerkiksi Suomi.fi-tunnistautuminen lisää turvallisuutta ja vapauttaa järjestelmät tunnusten ylläpidosta niiden ydintoimintojen suorittamiseen. Lisäksi Suomi.fi-tunnistautuminen tarjoaa kertakirjautumisen edut.

Sekä asiointi että asiakirjojen lähettäminen ja vastaanotto tapahtuu tulevaisuudessa yhä enemmän sähköisesti. Uuden lain tuoma velvoite aiheuttaa työtä Suomi.fi -palveluiden integroinnissa kuntien ja viranomaisten omiin järjestelmiin. Nämä uudistukset kuitenkin helpottavat ja nopeuttavat kansalaisten asiointia, ja sitä kautta säästämme myös yhteisiä verovaroja. Sähköinen viestintä vähentää paperipostia ja on paitsi taloudellista myös ympäristönsuojelua tukevaa.

Lisätietoa

https://uutiskirjeet.vrk.fi/uutiset/suomi.fi-palvelut/suomi.fi-palvelut-nyt-ja-tulevina-vuosina.html?p26=2

https://esuomi.fi/palveluntarjoajille/viestit/

https://vrk.fi/blogit/-/blogs/single-digital-gateway-ja-suomi-fi-palvelut

https://www.consilium.europa.eu/fi/press/press-releases/2018/06/20/digital-single-gateway-easier-access-to-online-information-and-procedures/