oikeellisuusväittämät

Oikeellisuusväittämä (assertion) on lauseke jonka uskotaan olevan tosi lausekkeen ajohetkellä. Jos näin ei ole, suoritetaan poikkeus AssertionException. Lisäämällä oikeellisuusväittämia tarkistamaan ohjelman ajonaikaista tilaa, järjestelmä varmentaa ohjelmoijan olettamukset ohjelman tilasta tai ilmoittaa asiasta ohjelman suorituksen kannalta terminaalilla tavalla. Toisin sanoen oikeellisuusväittämät antavat ohjelmoijalle mahdollisuuden tarkistaa onko ohjelma vielä järjissään: kalastaa ohjelmasta "mahdottomia" tiloja.

Oikeellisuusväittämät ovat ohjelmoijan kannalta edullisia, sillä jokaista ajateltua virhetilannetta vastaa kourallinen tilanteita joita ei ole tultu ajatelleeksi. Oikeellisuusväittämät antavat mahdollisuuden unohtaa nopeasti tapaukset joiden ei pitäisi koskaan tapahtua. Esimerkiksi ohjelmoijan suorituksen oletuksena voisi olla jonkin käyttäjälle näkymättömän konfiguraatiotiedoston olemassaolo. Tiedoston avausyrityksen jälkeen oikeellisuusväittämä tarkistaa onnistuiko avaus. Jos tiedosto puuttuu, ohjelman suoritus pysähtyy kuvaavan virheilmoituksen ohella.

Oikeellisuusväittämät ovat erinomainen tapa toteuttaa design-by-contract metodologia, joka riittämättömän lyhyesti kerrottuna kuvaa luokan ja sen asiakkaiden suhdetta muodollisena sopimuksena, jossa osapuolille on määritelty oikeudet ja vastuut. "viewing the relationship between a class and its clients as a formal agreement, expressing each party's right and obligations" Meyer, Bertand. 1997. Object-Oriented Software Contruction (2nd ed.). Upper Saddle River, NJ: Prentice-Hall.
Käytännössä tämä tarkoittaa ennakko-, jälki-ja muuttumattomuusehtojen ;)  (pre-,  postconditions ja invariants) luomista ja tarkistusta.

Ennakkoehdot ovat sopimuksellisia lupauksia joiden täytyy pitää ennen operaation aloitusta, jälkiehdot taas pitävät paikkansa suorituksen loputtua. Muuttumattomuus on ehto jonka pitää täyttyä aina ja kaikissa tilanteissa. Javassa tämä tapahtuu (yleensä) luokkatasolla, esimerkiksi luokan Jono instanssin koko ei voi koskaan olla alle nolla. Oikeellisuusväittämät käyvät aina jälki- ja muuttutmattomuusehtojen paikkaansapitävyyden tarkistamiseen. Oikeellisuusväittämiä voi käyttää ennakkoehtojen tarkistamiseen vain jos tarkistettava metodi ei ole julkinen. Julkisten metodien pitäisi tarkistaa eksplisiittisesti käytettävissä olevat arvot ja myös ilmoittaa poikkeamista julkisesti (heittämällä poikkeuksen). Aasinsilta oikeellisuusväittämien periaatteeliseen käyttöön: näiden mahdollisten sopimusrikkeiden tarkistaminen ei saa tuottaa lieveilmiöitä. Koska laajamittainen oikeellisuusväittämien käyttö tapahtuu ohjelman suoritusnopeuden kustannuksella, nämä voidaan ohittaa (yleensä) komentorivilla (vertaa C-suvun makroihin). Oikeellisuusväittämien ollessa mielivaltaisen monimutkaisia totuusarvolausekkeita metodi- ja oliokutsuineen, niiden sivuvaikutuset voivat helposti muuttaa ohjelman tilaa, tuottaen erinomaisen vaikeasti löydettäviä bugeja, kun oikeellisuusväittämät ja niiden luomat sivuvaikutukset ovat vaihtelevasti käytössä.

Oikeeliisuusväittämät verrattuna ohjelmatestaukseen

Oikeellisuusväittämät eivät ole näkyvissä loppukäyttäjälle samalla tavalla kuin testihjelmat, jotka auttavat dokumentoimaan käytettävien olioiden toimintaa. Oikeellisuusväittämillä ei, toisin kuin testitapauksissa, voida tarkistaa syötteen suhdetta oletettuun tulosteeseen eri skenaariossa, mutta testiohjelmat eivät voi tarkistaa ajonaikaista ohjelman tilaa, joten mm. kumulatiivisten pyöristysvirheiden tai säikeiden aiheuttamat ongelmat vaikeita löydettäviä. Tärkein ero on kuitenkin se, että testiohjelmilla voidaan vain tarkistaa ohjelman julkisen osan käyttäytyminen, ja vaikka epätoiminnallisuus pajlastuisikin, se ei välttämättä vielä kesso missä varsinainen ohjelmavirhe sijaitsee. Oikeellisuusväittämillä pystytään todentamaan yksityisten metodien toimintaa tasolla, joka ei ole mahdollista testiohjelmiston käytöllä.

Syntaksi

Oikeellisuusväittämiem syntaksi kaksiosainen erotettuna kaksoispisteellä. Lausekkeen täytyy olla tosi, jotta ohjelman suoritusta voidaan jatkaa. Jos se on epätosi AssertionError poikkeus tulee ajankohtaiseksi.

Yksinkertaisimmillaan oikeellisuusväittämä koostetaan avainsanasta assert ja lausekkeesta:

assert lauseke;

eli "jos lauseke ei ole tosi, jokin on pahasti pielessä, heitetään AssertionError ja poistutaan ohjelmasta"

public class Virkeluokka {
	private ToinenLuokka Virhemetodi(ToinenLuokka argumentti) {

	 // Tarkistetaan, että saatiin olio. Tämä on hyväksyttävä tapa, koska metodi on yksityinen.
	assert argumentti != null;

	//...Tehdään mitä tehdään
	}
}

Monimutkaisempi syntaksi on:

assert lauseke1 : lauseke2;

eli "jos lauseke1 on epätosi, heitä AssertionError poikkeus joka sisältää arvon lauseke2"

public class Virkeluokka {
	private ToinenLuokka Virhemetodi(ToinenLuokka argumentti ) {
		assert argumentti != null : "Olio " + argumentti + " jostain syystä tyhjä";
	}
}

Jälkimmäisen lausekkeen täytyy olla AssertionError olion konstruktorin hyväksuttävä argumentti. Näitä on seitsemän: olio, totuusarvo, char, int, long, float ja double. 

Oikeellisuusväittämät ovat oikeastaan pikakirjoitusmuoto normaalille virhekäsittelylle. Tosin perinteisempi tapa hoitaa asia ei ole riippuvainen oikeellisuusväittämien tarkistuksen päälläolotilasta.

public class Virkeluokka {
	private ToinenLuokka Virhemetodi(ToinenLuokka argumentti ) {
		if (!(argumentti != null)) {
			throw new AssertionError();
	}
}

Eli oliota AssertionError voidaan käyttää tavallisen virhepoikkeuksen tavoin, mutta assert mahdollistaa "makromaisen" toiminaalisuuden oikeelisuustarkistukseen ja nopean tavan ilmoittaa virhetilanteista enemmän tai vähemmän verbaalisesti. Lisäksi assert väitteet auttavat selventämään ohjelman sisäisia oletuksia ja rajoituksia. oikeellisuusväittämät siis helpottavat osaltaan koodin dokumentointia ja sitä kautta ylläpidettävyyttä.

Käyttöperiaatteita

Oikeellisuusväittämillä metsästetään mahdottomia tilanteita.  Oikeellisuusväittämien lisääminen mahdottomiin tilanteisiin auttaa löytämään epätodennäköisiltä tuntuvia bugeja ja auttaa löytänään ne heti virheen sattuessa, ei vasta kun virhe on kuplinut läpi ohjelman loputa kaataen sen huomattavan kaukana alkuperäisen virheen lähtökohdasta.

Oikeellisuusväittämillä metsästetään ohjelmoijan, ei käyttäjän virheitä. Väärät syötteet (julkisten metodien argumenttien arvot) eivät ole sama asia kuin esimerkiksi ohjelmaloogisesti mahdottomat muuttujien arvot. Ohjelman loppukäyttäjällä ei saisi olla mahdollisuutta kaataa ohjelmaa oikeellisuusväittämiin. Metodien parametrien syöttöarvojen tarkistaminen oikeellisuuväittämillä ei ole hyväksyttävää paitsi kun tarkistetaan, että syottarvojen tarkistus on toiminut oikein,  tai 'syvemmällä' metodissa, missä arvojen oletetaan implisiittisesti olevan oikein.

Esimerkkejä sopivasta paikasta assert lauseelle:
•	Switch lauseiden tyhjä default vaihtoehto.
•	Ohjelmavuon (control flow) mahdottomat kohdat, esimerkiksi metodin viimeisen silmukan tai ehdollisten return lauseiden jälkeen.
•	tarkistettaessa oletettavasti muuttumattoman olion muuttumattomuutta käsittelyn jälkeen
•	jne

Lisäksi voidaan sanoa, että hyvin suunitellulla oikeellisuusväittämen käytöllä saadan ohjelma kaatumaan mahdollisimman nopeasti. Debuggaus on nopeampaa ja yksinkertaisempaa kun virheet löytyvät varhain. Oikeellisuuväittämät löytävät ajonaikaisia virheitä jotka ovat muuten huomattavasti vaikeampia löytää kun käännösaikaiset virheet, koska virheet eivät välttämättä ole näyttäviä suuronnettomuuksia, vaan kenties vain vääristävät ohjelman kulkua aiheuttaen mahdollista huomaamatonta tuhoa tiedostoissa tms.

huonoista puolista ja puutteista

copypaste