Sunteți pe pagina 1din 12

1.

TESTAREA PROGRAMELOR OO
1.1. INTRODUCERE N TESTAREA POO
Introducere n testare
Testarea software este o etap important i plin de provocri din dezvoltarea programelor.
n cadrul acestui proces sunt descoperite evidene ale defectelor i se verific dac programul
este conform cu specificaiile. Testarea nu trebuie confundat cu depanarea, -care implic
descoperirea surselor erorilor-, i nici cu etapa de corectare a erorilor.
Testarea este o parte necesar (dar insuficient) din asigurarea calitii programelor.
Asigurarea calitii cuprinde activiti destinate prevenirii i nlturrii defectelor, iar testarea
poate contribui la mbuntirea calitii prin identificarea problemelor devreme n procesul de
dezvoltare, nainte de scrierea codului. Testarea nainte de scrierea codului presupune o
munc mai strns a dezvoltatorilor cu testerii i viceversa.
Perspectiva testrii este atitudinea testerului, care are sarcina dificil de a pune sub semnul
ntrebrii toate aspectele legate de softul testat. Fr a citi codul, un tester trebuie s
anticipeze greelile i optimizrile pe care le poate face un dezvoltator i apoi s construiasc
teste pentru detectarea acestora. De aceea, n multe privine, a fi un tester bun este mai dificil
dect a fi un dezvoltator bun, ntruct testarea solicit o bun nelegere a procesului de
dezvoltare i a produselor sale dar i abilitatea de anticipa erori posibile. Cutarea greelilor
trebuie ghidat att de cutarea sistematic, ct i de intuiie iar scopul final este de a
demonstra faptul c un soft se comport conform specificaiei sale, i nu execut nimic din
ceea ce nu i se cere s execute.
Importana testarii rezid nu doar din faptul c aceasta ofer o asigurare c un sistem software
face ceea ce trebuie s fac (i nimic n plus) dar i din asigurarea utilizatorilor mpotriva
cderilor programului ce pot duce la pierderi de timp, proprieti, clieni, sau chiar viei.
Scopul procesului este scrierea de programe mai mentenabile, reutilizabile, flexibile, etc.
Ne vom ocupa n cadrul primului capitol de testarea sistemelor orientate obiect, structurate pe
componente. Acestea au avantajul c testarea poate ncepe din timpul dezvoltrii sistemului
(testarea modelelor de analiz i design) ceea ce reduce costurile i sporete eficiena. Vom
urmri ce, cnd i cum testm n programele orientate obiect, comparativ cu testarea
procedural (spre exemplu, motenirea i polimorfismul introduc noi provocri testerilor), i
vom presupune ca procesul de dezvoltare al programului este incremental.
Noiunile de testare prezentate sunt utile programatorilor, -care deja testeaz software, dar vor
s cunoasc mai multe despre testarea programelor orientate obiect; dar i managerilorresponsabili cu dezvoltarea software, care doresc s tie cum i unde testarea se ncadreaz n
planul global. De asemenea, dezvoltatorii sunt rspunztori cu testarea programelor pe care le
produc, i trebuie s considere testarea n timpul analizei, design-ului i activitilor de
implementare.
Scenariul de dezvoltare software
Vom presupune n continuare ca procesul este incremental, cu iteraii la fiecare etap
(increment) (modificri n modul de dezvoltare a programului introduc implicit modificri n
maniera de testare). n plus, vom considera i c dispunem de modelele software n UML, i

c design-ul software respect principiile unui design de calitate, n ceea ce privete


motenirea, ascunderea datelor, abstractizarea, cuplajul slab i coeziunea ridicat.
Reprezentrile software pe care se va face testarea vor fi atat codul surs al programului i
fiierele de date ct i modelele create n cadrul etapelor de analiz i design.
Programarea orientat pe obiecte
Spre deosebire de programarea procedural, programarea orientat pe obiecte focalizeaz
obiectele, nu funciile ce transform intrrile n ieiri. Un program orientat obiect este o
mulime de obiecte ce modeleaz o problem i colaboreaz pentru a produce o soluie.
Conceptul din spatele acestei abordri este c structura i componentele unei probleme nu se
vor schimba frecvent n timp, dar soluia problemei- da. n consecin, un program structurat
dup problem (nu dup o soluie imediat) va fi mai adaptabil modificrilor ulterioare. n
plus, un programator familiar cu problema poate recunoate uor componentele n software,
deci programul este mai mentenabil, iar componentele fiind derivate direct din problem, pot
fi reutilizate n dezvoltarea altor probleme similare.
Avantajul principal al programelor orientate obiect este c ne pun la dispoziie modelul de
analiz i cel de design, naintea implementrii (codului), deci se poate ncepe testarea nc
din timpul analizei. Testele pentru analiz se rafineaz apoi n teste pentru design, care se
rafineaz, la rndul lor, n teste ale implementrii, deci testarea se poate ntreptrunde cu
procesul de dezvoltare.
Testarea modelelor de analiz i design are multiple avantaje. n primul rnd, cazurile de test
se pot identifica devreme, chiar odat cu determinarea cerinelor, i aceast testare timpurie
ajut analitii i design-erii s neleag i s exprime mai bine cerinele, i s se asigure c
cerinele specificate sunt testabile. n al doilea rnd, erorile se pot detecta devreme n
procesul de dezvoltare, economisind timp, bani i efort (de ce problemele sunt descoperite
mai rapid, vor fi mai uor i mai ieftin de reparat). n fine, un alt avantaj este c testarea
modelului asigur ca testerii i dezvoltatorii s aib o nelegere consistent a cerinelor
sistemului. ntruct testarea trebuie adaptat criteriilor de calitate solicitate, dac o companie
i propune s creeze software reutilizabil i design-uri extensibile, atunci la testare trebuie
depistate problemele prin prisma acestor obiective. Tehnicile tradiionale de testare nu sunt
potrivite cu obiectivele de mai sus.
n abordarea prezent vom considera c testarea este un proces separat de procesul de
dezvoltare, dar relaionat cu el i ne vom ghida dup principiul: Testeaz devreme. Testeaz
des. Testeaz suficient. De asemenea, procesul de dezvoltare va fi unul iterativ, bazat pe
repetarea urmatorilor pasi:
1.
2.
3.
4.

Analizeaz puin.
Creeaz puin din design.
Implementeaz puin.
Testeaz ce poi.

(Testeaz ce poi include ceea ce poi tehnic face, n condiiile constrngerilor de timp i
resurse).
Un avantaj al sistemelor dezvoltate incremental este faptul c testarea se poate face la sfritul
fiecrei etape. Pentru un program orientat obiect exista urmtoarele tipuri de testri:








Testarea modelului
Testarea claselor
Testarea interaciunilor
Testarea sistemului (i subsistemelor)
Testarea acceptrii
Testarea n situaii finale

Testarea software este de obicei o combinaie de inspecii, revizii, si execuii de teste


desfurate cu scopul de a observa eventuale erori.
Inspeciile sunt examinri ale programului pe baza unei liste de probleme tipice (semantica
limbajului de programare, conveniile de implementare- de exemplu, asigurarea c fiecare
variabil este iniializat nainte de prima utilizare/ c fiecare pointer refer o locaie corect
etc.) Compilatoarele moderne pentru limbaje OO pot detecta multe probleme de pe listele
tradiionale pentru inspecii.
Reviziile sunt examinri ale programului cu scopul de a gsi erori, nainte de executarea sa, ce
se desfoar n cursul dezvoltrii software, analiznd dac nelesul fiecrei pri de program
satisface cerinele aplicaiei. Scopul unei revizii este de a descoperi erori de genul cerine
greit nelese sau probleme n logica programului; unele revizii pot verifica dac algoritmii
sunt att de eficieni pe ct pot fi, dac numele de variabile sunt alese inspirat, etc.
Execuiile de test presupun testarea software n contextul unui program care ruleaz. Prin
executarea programului, testerul ncearc s determine dac programul are comportamentul
dorit, prin perechi de date intrare-ieire verificate. Problemele acestui tip de testare constau n
determinarea acelor intrri ce pot duce la erori, n calcularea ieirilor corecte pentru intrri
date i n determinarea unui mod de observare a ieirilor. Ne vom concentra n acest curs pe
acest tip de testare, dar ideea de execuie va fi extins pentru a include i execuia simbolic a
reprezentrilor non-executabile ale unui sistem.
Perspectiva testrii poate fi:
 Sceptic: solicit dovada calitii;
 Obiectiv: nu presupune nimic;
 Contiincioas: nu scap ariile importante;
 Sistematic: se pot reproduce cutrile efectuate.
Exerciiu
1. Considerai o aplicaie ce va fi folosit pentru a programa slile de conferin dintr-o
cldire. Aplicaia are o IUG ce permite utilizatorului s indice data, ora, i durata (n
incremente de 15 minute). Apoi afieaz o list cu slile de conferin disponibile la ora
respectiv i permite rezervarea unei sli.
Sistemul permite i anularea unei rezervri. Proiectul trebuie dezvoltat incremental adic, n
etape cresctoare de funcionalitate. Considerai urmtoarele dou planuri. Care va reui mai
bine? Ce testare se poate face la sfritul fiecrui increment?

Plan A

Plan B

Increment 1: Crearea interfeei grafice;

Increment 1: Dezvoltarea capacitii de a


introduce data, ora, durata, i afiarea
Increment 2: Crearea subsistemului de disponibilitii slilor;
stocare a datelor;
Increment 2: Dezvoltarea capacitii de a
Increment 3: Dezvoltarea subsistemului rezerva o camer;
aplicaie (rezervrile).
Increment 3: Dezvoltarea capacitii de a
anula o rezervare.

Programele Orientate Obiect din perspectiva testrii


Conceptele de baz ale POO sunt Obiectul, Mesajul, Interfaa, Clasa, Motenirea,
Polimorfismul. Le vom analiza pe fiecare din perspectiva testrii.
1. Obiectul este o entitate operaional-computational de baz ntr-un program OO, ce
ncapsuleaz att valori specifice ale datelor ct i codul ce opereaz asupra acestor valori. Un
program OO este o comunitate de obiecte ce coopereaz pentru a rezolva o problem. Un
principiu GOOD ne spune ca un obiect trebuie s fie o reprezentare a unei entiti specifice
din cadrul problemei sau al soluiei. Din prisma testrii, trebuie verificat dac un obiect se
comport conform specificaiei, i dac interacioneaz corect cu alte obiecte n timpul
execuiei.
Ciclul de via al unui obiect ncepe la crearea obiectului, trece printr-o succesiune de stri i
sfrete la distrugerea obiectului. Starea corect a unui obiect depinde de vrsta sa, o stare
inconsistent, crearea tardiv sau distrugerea prea timpurie a obiectelor fiind surse uzuale de
erori. Orice obiect ncapsuleaz date i prin aceasta, el este uor de manevrat i identificat n
cadrul sistemului, dar ascunderea informatiilor poate ngreuna testarea, ntruct unele
modificri ale obiectului nu sunt vizibile.
2. Mesajele reprezinta cereri ca anumite operaii s fie executate de obiecte. Un mesaj include
numele operaiei si lista de parametri actuali. n C++ mesajul este apelul unei funcii membru,
iar n Java mesajul este invocarea unei metode.Colaborarea ntre obiecte se realizeaz prin
transmiterea de mesaje (Figura).
mesaj

receptor

emitor
Valoare ntoars/ exceptie

Figura

Din perspectiva testrii orice mesaj are un emitor -care decide cnd trimite mesajul, i poate
grei n aceasta decizie i orice mesaj are un receptor -care poate nu este (nc) pregtit pentru
mesajul primit. n plus, orice mesaj poate include parametri actuali, folosii de receptor n
prelucrarea mesajului. Obiectele folosite ca parametri trebuie s se afle n starea corect
nainte (i dup) procesarea mesajului, i trebuie s implementeze interfaa ateptat de
receptor.
3. Interfaa este o agregare de declaraii de comportament, nrudite n raport cu un anumit
concept. O interfa este un set constructiv pentru specificaii, ce definete mulimea complet
a comportamentelor publice ale unei clase. n Java exist conceptual dedicat de interface,
iar n C++ o interfa este o clas de baz abstract, doar cu metode pur virtuale, publice.
Interfeele ncapsuleaz specificaii de operaii, specificaii ce vor sta la baza construirii de
clase; i dac interfaa cuprinde comportamente nerelaionate cu ansamblul, implementarea va
avea un design nesatisfcator. Interfaa trebuie privit i prin prisma relaiilor sale cu alte
interfee/ clase: ea se poate specifica drept tipul unui parametru al unui comportament, pentru
a permite ca orice implementator al interfeei s fie folosit ca parametru.
4. Clasa reprezint o mulime de obiecte cu aceeai baz conceptual, constituind un element
de baz n definirea programelor orientate-obiect, n timp ce obiectele sunt elemente de baz
n executarea programelor orientate-obiect. Crearea de obiecte definite de o anumit clas se
numeste instaniere (un obiect este o instan a unei clase). Specificaia unei clase definete ce
poate s fac fiecare obiect al clasei, iar implementarea clasei descrie cum face fiecare obiect
ceea ce face. n C++ fiierele header (.h) descriu specificaia, iar fiierele surs (.cpp) conin
implementarea (Figura). n Java, dei specificaia i implementarea sunt n acelai fiier,
exist totui o separaie logic ntre ce i cum.

Figura. Header (CE?) / sursa (CUM?)

Clasele statice. Din perspectiva testrii, o clas cu membri statici trebuie tratat ca un obiect,
i trebuie creat o succesiune de teste att pentru clas n sine, ct i pentru instanele sale.
Trebuie s fim ntotdeauna sceptici n legtur cu datele statice, non-constante, asociate cu o
clas, deoarece acestea pot afecta comportamentul instanelor.

I. Specificaia unei clase definete ce reprezint clasa, ce poate o instan a clasei s fac, si
include cte o specificaie pentru fiecare operaie a clasei.
Operaie = aciune ce poate fi aplicat unui obiect, cu un anumit efect. Operatiile se clasifica
n:
 Operaii inspector (accesator)- care furnizeaz informaii despre obiecte, fr a
le modifica (valori ale unor date membru, starea obiectului etc.). (n C++ ele
trebuie declarate const);
 Operaii modificatoare- care schimb starea unui obiect prin modificarea
valorii unor atribute ale obiectului
Testarea operaiilor inspector difer de a operaiilor modificator. Exist operaii care sunt i
inspectori, i modificatori, i operaii care execut modificri doar n anumite condiii, i pe
care le vom clasifica drept operaii modificator. Este o bun decizie de design OO ca o
operaie s fie ori modificator, ori inspector, dar nu ambele n acelai timp, acest aspect
uurnd testarea. Constructorii (ce iniializeaz instane noi) i destructorii (care efectueaz
procesrile necesare nainte de sfritul vieii obiectului) sunt diferii de accesatori i
modificatori prin faptul c sunt implicit invocai la crearea/ distrugerea obiectelor (unele
invocri sunt vizibile n program, unele nu).
Exemplu:
X=a+b+c
Tmp1=a+b;
Tmp2=tmp1+c;
X=tmp2
Specificarea operaiilor. Fiecare operaie din specificaia clasei trebuie s aib ataate un
neles i nite constrngeri (fiecare operaie s aib o specificaie care descrie ce face
aceasta). O bun specificare a semanticii operaiilor este critic att pentru dezvoltare ct i
pentru testare. Semantica trebuie specificat n diferite puncte:
 Precondiii
 Postcondiii
 Invariani
Precondiiile unei operaii descriu condiii ce trebuie s fie ndeplinite nainte ca operaia s
se poat executa, si se exprim n termenii atributelor obiectului ce conine operaia i/sau
atributelor parametrilor actuali ai mesajelor ce solicit executarea operaiei.
Postcondiiile unei operaii descriu condiii ce trebuie s fie ndeplinite dup execuia
operaiei, i se exprim n termeni de:
 atributele obiectului ce conine operaia;
 atributele parametrilor actuali ai mesajului ce solicit execuia operaiei;
 o valoare de rspuns a operaiei i/sau
 excepiile ce pot apare
Invarianii descriu condiii ce trebuie ndeplinite constant pe parcursul duratei de via a
obiectului. Un invariant de clas descrie o mulime de granie operaionale pentru o instan a
unei clase, fiind o postcondiie implicit pentru fiecare operaie (dar invarianii pot fi nclcai
n timpul execuiei). Acetia se pot exprima n termeni de atribute/stri ale obiectului.

Specificarea operaiilor in OCL. Dac diagramele de clase definesc clasele (atribute i


operaii), iar diagramele de stare ilustreaz comportamentul unei instane a clasei, specificarea
semanticii operaiilor se poate face cu un limbaj special: Object Constraint Language (OCL)Limbajul Constrngerilor Obiectuale. Constrngerile OCL se exprim n contextul unei
diagrame de clase, i implic atribute, operaii i asocieri definite n diagram. Semantica
operaiilor este descris n termeni de precondiii i postcondiii (Figura). Condiiile invariante
pentru o clas (interfa) trebuie s fie ndeplinite la nceputul i la finalul oricrei operaii. O
bun specificare a unei operaii este absolut necesar pentru testare (este imposibil s testezi
un cod cu scop vag sau ambiguu). Existena unor astfel de specificaii mbuntete i
calitatea codului (inclusiv reutilizabilitatea claselor).

Figura . OCL pentru operaiile clasei PuckSupply


Vom descrie n continuare dou tehnici de design a claselor prin prisma precondiiilor i a
postcondiiilor: programarea contractual (care accentueaz precondiiile dar are postcondiii
mai simple) i programarea defensiv care este reversul primeia.
Programarea contractual. n aceast tehnic de design propus de Bertrand Meyer, o
interfa se definete n termenii obligaiilor primitorului/ transmitorului implicai ntr-o
interaciune. Astfel:
 Precondiiile descriu obligaiile transmitorului (nainte ca transmitorul s fac o
cerere primitorului, transmitorul trebuie s se asigure c precondiiile sunt
ndeplinite). Cnd construim design-ul interfeei unei clase, precondiiile trebuie s
fie suficiente pentru:
o a permite primitorului s ajung la postcondiii;
o a permite transmitorului s determine dac toate precondiiile sunt ndeplinite
nainte de trimiterea unui mesaj.
 Postcondiiile descriu obligaiile primitorului (care trebuie s verifice c acestea sunt
ndeplinite). Trebuie ca postcondiiile s acopere toate ieirile posibile ale unei
operaii, n ipoteza c precondiiile sunt ndeplinite.
Este util s definim metode accesor pentru verificarea condiiilor.

Programarea defensiv. n acest caz, interfaa se definete n primul rnd din perspectiva
primitorului, i a presupunerilor fcute de acesta asupra strii sale, i asupra valorii intrrilor
(argumente sau valori de date globale), la momentul cererii. Operaiile ntorc o indicaie
asupra strii cererii: succes/ eec pentru un anumit motiv (valoare de intrare greit). Scopul
principal al programrii defensive este s determine garbage in pentru a elimina garbage
out. Dezavantajele acestei abordri sunt:
 mrete complexitatea software: transmitorul trebuie s corecteze n funcie de
ieirile posibile ale operaiei (lipsa de ncredere nu poate fi doar de partea
primitorului, ci i a transmitorului -care verific ieirile operaiei);
 Crete dimensiunea codului i a timpului de execuie.
n concluzie, programarea defensiv reflect o lips de ncredere a transmitorului fa de
primitor, iar n programarea contractual, responsabilitatea e mprit mutual ntre
transmitor i primitor (primitorul proceseaz o cerere pe baza unor intrri presupuse a
ndeplini precondiiile, iar transmitorul presupune postcondiiile ndeplinite dup procesarea
cererii). Cele dou tehnici se pot combina. Design-ul interfeelor prin programare contractual
elimin necesitatea ca primitorul s verifice precondiiile deci programarea contractual este
mai eficient din perspectiva programului i programatorului, dar dezavantajul este ca n
contextul execuiei programului, nu putem fi siguri de respectarea contractului. Aadar,
trebuie ca toate interaciunile s fie testate n programarea contractual.
Deci, prin prisma testrii, programarea contractual simplific testarea claselor dar complic
testarea interaciunilor (trebuie s ne asigurm c fiecare transmitor ndeplinete
precondiiile), n timp ce programarea defensiv complic testarea claselor (cazurile de test
trebuie s acopere toate rezultatele posibile) dar i testarea interaciunilor (trebuie s ne
asigurm c se produc toate rezultatele posibile i c sunt tratate corect de transmitor).
O idee ce vine n sprijinul testrii este aceea de a verifica din timpul design-ului dac
precondiiile, postcondiiile i invarianii sunt testabili:
 Sunt constrngerile exprimate clar?
 Specificaia include metode de verificare a precondiiilor?
Din perspectiva testrii, n programarea contractual trebuie testate doar situaiile n care
precondiiile sunt satisfcute, iar n programarea defensiv trebuie s testm fiecare intrare
posibil pentru a verifica dac ieirea este tratat corespunztor.

Figura Specificaia clasei PuckSupply n programarea prin contract

Figura .Specificaia clasei PuckSupply n programarea defensiv


Specificaiile operaiilor unei clase descriu comportamentul clasei respective. o descriere mai
complex a comportamentului unei clase gsim n diagramele de stare (UML), alctuite din
stri i tranziii, n care este descris cum afecteaz diversele operaii tranziia dintr-o stare n
alta. Spre exemplu, clasa PuckSupply poate trece prin dou stri :empty, non-empty (n funcie
de valorile unui anumit atribut al clasei: size).
II. Implementarea claselor cuprinde definirea valorilor atributelor (datelor membru,
variabilelor), scrierea codului funciilor membru/ metodelor i a constructorilor i
destructorilor. Iat cteva surse uzuale de erori n implementarea claselor :
 Atributele noilor instane nu sunt iniializate corect
 n colaborarea cu alte clase n implementarea codului unei clase, dac acele clase nu
sunt implementate corect, aceasta duce la erori n codul clasei care le-a folosit n
definiia sa

 Implementarea clasei satisface specificaia, dar nu avem garania c specificaia este


corect
 Implementarea nu conine toate operaiile sau definete incorect operaiile
 Clasa nu ofer o modalitate de verificare a precondiiilor de ctre transmitor.
5. Motenirea permite refolosirea specificaiei i implementrii unei clase pre-existente
(superclas/ clas de baz) de ctre o subclas/ clas derivat. Relaia de motenire este
ierarhic, un arbore cu descendeni i ancestori. Un principiu GOOD spune motenirea ar
trebui folosit doar pentru implementarea relaiilor de tip este-un / este-un-fel-de
(principiul substituiei prezentat mai jos ne va explica de ce). Din perspectiva testrii, ntr-o
relaie de motenire erorile se propag de la o clas la descendenii si. Acest lucru poate fi
prevenit prin testarea unei clase imediat ce a fost dezvoltat. Avantajul motenirii const n
faptul c permite reutilizarea cazurilor de test (de la clasa de baz la derivate).
6. Polimorfismul este abilitatea de a trata un obiect ca aparinnd la mai mult dect un singur
tip. Aa cum menionam mai sus, motenirea ar trebui folosit doar pentru a modela relaiile
este-un sau este-un-fel-de, deci dac D este o subclas a lui C atunci s putem spune D
este un fel de C. Principiul susbstituiei (Barbara Liskov) ne spune c instana unei subclase D
a lui C trebuie s poat fi folosit fr excepii/ erori oriunde se folosete o instan a
superclasei C (cu alte cuvinte, o subclas trebuie s fie un subtip: specificaia subclasei
trebuie s respecte complet specificaia ancestorului direct; deci subclasa poate fi privit ca o
submulime a mulimii bazei conceptuale comune -clasa de baz-). Un mod de a fora
substitutabilitatea este s constrngem modificrile de comportament de la clas la subclas.
Comportamentul unei clase se poate defini n termenii strilor observabile ale unei instane i
a semanticii operaiilor definite pentru o instan a clasei, iar comportamentul unei subclase se
poate defini n termenii schimbrilor incrementale ale strilor observabile i operaiilor
definite de clasa de baz.
Principul care ne ajut s controlm modificrile ce apar n clasa derivat spune c aceasta
trebuie s nu cear mai mult, i s nu promit mai putin (require no more, promise no
less). Astfel, pentru respectarea principiului substituiei, se admit doar urmtoarele
modificri n comportamentul unei subclase:
 Precondiiile fiecrei operaii s fie aceleai sau mai slabe (-mai puin restrictive
din perspectiva clientului)
 Postcondiiile fiecrei operaii s fie aceleai sau mai puternice (s fac cel puin la
fel de mult ca cele definite n superclas)
 Invariantul de clas s fie la fel sau mai puternic (eventual s adauge constrngeri
noi)
Din perspectiva strilor observabile, modificarile permise se vd astfel:
 Strile observabile i toate tranziiile ntre ele din clasa de baz trebuie s se
pastreze n subclas
 Subclasa poate s adauge tranziii ntre aceste stri
 Subclasa poate aduga stri observabile noi dac sunt concurente sau substri ale
unei stri existente

Vom traduce aceste restricii i n contextul programrii contractuale. Am vzut n


programarea contractual c precondiiile stabilesc obligaiile transmitorului, iar
postcondiiile i invarianii stabilesc obligaiile primitorului n orice interaciune. Deci cerina
pentru precondiii cel puin la fel de slabe nseamn c n ndeplinirea obligaiilor fa de A,
transmitorul ndeplinete automat i obligaiile fa de B (mai puin restrictive), iar cerina
pentru postcondiii i invariani cel puin la fel de puternici nseamn c primitorul mplinete
obligaiile fa de transmitor n termenii contractului lui A (chiar dac primitorul face ceva
n plus dect se ateapt transmitorul).
Exemplu. Sa considerm modelul din Figura

Pentru fiecare operaie motenit:


1. Metoda tryIt() din A satisface precondiiile lui doIt() din B, nainte de a chema doIt();
2. Dac se substituie o instan C sau D, precondiiile pentru C::doIt() sau D::doIt() nu
trebuie s adauge condiii noi fa de cele pentru B::doIt() (altfel ar trebui s adaptm
A pentru acomodarea cu C i D);
3. Invariantul definit pentru B trebuie s fie adevrat i n instanele C i D; se pot
aduga invariani noi
Polimorfismul este mecanismul specific programrii orientate obiect care st n spatele
principiului substituiei i presupune ca aceeai metod s poat apare cu diferite definiii n
cadrul ierarhiei de motenire. O referin polimorfic ascunde clasa actual a referentului, toi
referenii fiind manevrai prin intermediul interfeei comune, iar asocierea unei anumite
metode la o operaie specificat ntr-un mesaj are loc n timpul execuiei (legare dinamic). n
C++ este implementat folosind funcii virtuale, iar n Java folosind motenirea sau
implementarea de interfee.
Atat limbajul C++ ct i Java ofer suport pentru determinarea clasei actuale a referentului la
execuie. Inspeciile la execuie creeaz un punct de mentenan, n cazul extinderii ierarhiei
de clase, prin urmare GOOD prevede ca astfel de inspecii s fie minimale.
Clasele abstracte se scriu cu scopul de a defini o interfa pentru descendeni. Folosirea
abstractizrii permite exploatarea polimorfismului la design, ntruct prile programului
afectate de schimbri trebuie s se limiteze la cele care construiesc instane ale claselor.
Din perspectiva testrii, polimorfismul permite extinderea incremental a sistemelor prin
adugarea de clase, n loc de modificarea celor existente, iar n extinderi pot aprea
interaciuni neateptate. De asemenea, mecanismul permite ca operaiile s aib parametri

referii polimorfic, (aceasta mrete numrul de tipuri posibile de parametri ce trebuie testai)
i permite unei operaii s specifice rspunsuri sub forma de referine polimorfice (aici clasa
real a referinei pote fi incorect sau neateptat pentru transmitor).
O prim conlcuzie important este c natura dinamic a limbajelor orientate obiect acord mai
mult importan testrii unei suite de configuraii din timpul execuiei.