0% found this document useful (0 votes)
37 views48 pages

Mecanismul Template TDD

The document discusses templates in C++. It provides examples of function templates like a max template that finds the maximum of two values of any type. It also discusses class templates like a Vector template that can store elements of any type. Template parameters allow containers and algorithms to work with different data types generically. The key benefits are avoiding code duplication and catching errors at compile-time rather than runtime.

Uploaded by

petricapp
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
37 views48 pages

Mecanismul Template TDD

The document discusses templates in C++. It provides examples of function templates like a max template that finds the maximum of two values of any type. It also discusses class templates like a Vector template that can store elements of any type. Template parameters allow containers and algorithms to work with different data types generically. The key benefits are avoiding code duplication and catching errors at compile-time rather than runtime.

Uploaded by

petricapp
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
You are on page 1/ 48

Mecanismul template.

TDD.
POO- Curs 11
Polimorfism probleme
Test.cpp
#include "Integer.h"
#include "Person.h"
#include "Array.h"
#include <iostream>
using namespace std;

void print(Array& a){
for(int i=0;i<a.length();i++)
cout<<a.getElem(i)->toString()<<" ";
cout<<endl;
}

int main(){
Array a(4);
a.add(new Integer(3));
a.add(new Integer(4));
a.add(new Integer(5));
a.add(new Person("Adriana"));
Person* p= (Person*)a.getElem(0);
cout<<p->toString()<<endl;
return 0;
}

Se compileaza????
DA.
In afara controlului compilatorului
Abordarea template ar identifica o astfel de eroare.
Test.cpp
#include "Integer.h"
#include "Person.h"
#include "Array.h"
#include <iostream>
using namespace std;

void print(Array& a){
for(int i=0;i<a.length();i++)
cout<<a.getElem(i)->toString()<<" ";
cout<<endl;
}

int main(){
Array a(4);
a.add(new Integer(3));
a.add(new Integer(4));
a.add(new Integer(5));
a.add(new Person("Adriana"));
Person* p= (Person*)a.getElem(0);
cout<<typeid(p).name()<<" "<<p->toString()<<endl;

Integer* i=(Integer*)a.getElem(3);
cout<<typeid(i).name()<<" "<<i-
>toString()<<endl;
Integer x;
Integer j=*i;
//Integer j=*(Integer*)a.getElem(0);
Integer s=x+j;
cout<<"Suma numerelor "<<j.toString()<<"
si "<<x.toString()<<" este
"<<s.toString()<<endl;

system("pause");
return 0;
}

RTTI (RunTime Type Identification)
Genericitate in diferite limbaje
C void*

Java + Smalltalk mostenire + polimorfism (o singura
clasa de baza Object, IE, TElem, etc)

2004 Java introduce generics

C++ nu are o ierarhie derivata dintr-o singura clasa de
baza

Unele biblioteci pot fi cumparate de la diversi furnizori
probabilitatea ca toate clasele sa fie derivate din aceeasi
clasa de baza scazuta
Polimorfism si Genericitate
Shape
<<interface>>
Circle
Square
Mostenire multipla
Cum am putea adauga
Shape-uri in Container?
Container
<<interface>>
Object
<<interface>>
Polimorfism si Genericitate
Shape
<<interface>>
Circle Square
Container
<<interface>>
Object
<<interface>>
OShape
OCircle
OSquare
Codul???
Greu de inteles, intretinut, etc
Solutia cea mai potrivita utilizarea template-urilor (Adapter/ wrapper
design pattern)
Design patterns = sabloane de
proiectare
Design Patterns: Elements of Reusable Object-Oriented
Software - 1994
Gang of Four (GoF )- Erich Gamma, Richard Helm, Ralph Johnson
and John Vlissides

Sabloane-clasificare:
Creationale instantierea claselor: Abstract Factory, Builder,
Factory Method, Prototype, Singleton

Structurale compunerea claselor si obiectelor: Adapter, Bridge,
Composite, Decorator, Faade, Flyweight, Proxy

Comportamentale: Chain of responsibility ,Command Interpreter,
Iterator, Mediator, Memento, Observer, State, Strategy,
Template method, Visitor
Sablonul Adapter
Translateaza o interfata a unei clase intr-o interfata compatibila

Permite unor obiecte care in mod normal nu ar putea sa coopereze
datorita interfetelor incompatibile sa colaboreze, furnizand clientilor
interfata proprie, in timp ce lucreaza cu interfata originala

Adaptorul transforma apelurile metodelor din interfata sa in apeluri
ale metodelor din interfata originala

De obieci, codul necesar este redus
Reutilizarea codului
Mostenirea si compozitia reutilizarea codului obiect

Mecanismul template reutilizarea codului sursa

Containerele standard C++ si algoritmii sunt dezvoltate
folosind exclusiv mecanismul template

Template = mecanism de creare a unor tipuri generice
de date
Solutia template
Containerul nu mai retine o clasa de baza generica (Object, IE,
TElem, etc), ci un parametru nespecificat

La utilizarea template-ului, parametrul este substituit de compilator

Mecanismul template implementeaza conceptul de tip parametrizat
= familie de tipuri relationate

Vector parametrizat = vector<int>, vector<char> ,
vector<Student>, vector <vector<int>>, etc
Ce poate fi template?
Functii
Clase
Membri
Functii template
Maximul a 2 numere
inline int max (int a, int b) {return a>b?a:b;}
inline long max (long a, long b) {return a>b?a:b;}
inline int max (int a, int b) {return a>b?a:b;}
inline long max(long a, long b) {return a>b?a:b;}
inline double max(double a , double b) {return a>b?a:b;}

overloading
Cod redundant
Functiile template
template <class T> inline T max(const T& a, const T& b) {return
a>b?a:b;}
Folosit pentru a
declara un template
Argumentul template-ului, tipul argumentului template-ului
Procesul de generare a unei functii concrete dintr-o functie template =
instantiere
int z=max<int>(3,7);
double d=max<double>(3.5, 4.9);
T=Student
T=Masina
Operatorul > supraincarcat !!!
Deductia tipului/specializarea
templateului
int i=3, j=4;
int z =max(i,j);
Compilatorul deduce min<int>(i,j) daca
ambele argumente au acelasi tip
double j=2.5;
int i=3;
max(i,j);
no matching function for call to `maxim (int &, double &)'
double j=2.5;
int i=3;
max<double>(i,j);
solutia
char* a=ana;
char* b=maria;
max(a,b);
Adrese!!!
template <> const char* maxim<const char*>(const char*
const& a, const char* const& b) {
return (strcmp(a,b)<0)?b:a;
}
Specializarea template-ului
Apel: max<>(a,b);
Functii template
#ifndef INTEGER_H
#define INTEGER_H
#include<iostream>
using namespace std;

class Integer{
private:
int i;
public:
Integer(int n=0):i(n){}
bool operator<(const Integer&v)const{
return i<v.i;
}

bool operator>(const Integer& v)const{
return i>v.i;
}

friend ostream& operator<<(ostream& os, Integer& i){
return os<<i.i<<endl;
}
~Integer(){}
};
#endif
#include<iostream>
using namespace std;
#include "Integer.h"

template <class T> inline T maxim(T a, T b){
return a>b?a:b;
}

int main(){
cout<< maxim<int>(2,5)<<endl;
cout<<maxim<double>(3.4, 8.9)<<endl;
cout<<maxim<Integer>(Integer(4), Integer(7));
return 0;
}

Clase template
Structura unei clase template, incluzand functii membre si date
statice:
template <class T> class A{
void f();
static T x;
};
template <class T> void A<T>::f(){}
template <class T> T A<T>::x=0;
Nume
clasa
Tip de
data
Declaratia
template
Tip
returnat
T reprezinta tipul argumentului template-ului si este
legat la acel tip in momentul instantierii
Instantierea unei clase template
A<int> a; (T=int)

Legarea argumentului template-ului si generarea clasei concrete =
instantiere

Template= schelet/macro/framework

La adaugarea unui tip specific acestui schelet clasa concreta C++

Argumentele template-ului pot fi si expresii constante:

template <int N> class A{}
A<-37> a;

Util cand se doreste transmiterea unei dimensiuni la un template

Clasa template Vector
Tipul elementelor parametru template
Capacitatea parametru template

template <class T, int N> class Vector {};

Vector<int, 100> v;
Valoare implicita
instantierea
Vector
-elem[*]: T
-dim: int
<<create>>-Vector()
+set(pos: int, val: T): void
+get(pos: int): T
<<CppOperator>>+[](: int): T
+add(: T): void
+size(): int
+remove(pos: int): T
T : class
CAP = 10
Clasa template Vector
#ifndef VECTOR_H
#define VECTOR_H

template <class T, int CAP=10> class Vector{
T elem[CAP];
int dim;
public:
Vector();
void set(int pos, T val);
T get(int pos) const;
void add(T);
int size();
T remove(int pos);
};

template<class T, int CAP> Vector<T,
CAP>::Vector(){dim=0;}
template<class T, int CAP> void
Vector<T,CAP>::set(int pos, T val){
elem[pos]=val;
}
template<class T, int CAP> T Vector<T, CAP>::get(int
pos) const{
return elem[pos];
}

template<class T, int CAP> void Vector<T,CAP>::add(T
a) {
elem[dim++]=a;
}

template<class T, int CAP> int Vector<T,CAP>::size(){
return dim;
}

template<class T, int CAP> T
Vector<T,CAP>::remove(int pos){
T aux = elem[pos];
elem[pos]=elem[--dim];
return aux;
}


#endif

Test
#include "Vector.h"
#include <iostream>
#include <conio.h>
using namespace std;


template <typename T, int CAP>
void read ( Vector<T, CAP>& v){
int n;
cout<<"Dati nr de elem :";
cin>>n;
T e;
for(int i=0;i<n;i++)
{cin>>e;
v.add(e);
}
}

template <typename T, int CAP>
void print (Vector<T,CAP> t) {
for (int i=0;i<t.size();i++)
cout<<t.get(i)<<" ";
cout<<endl;
}

int main(){
Vector<double> a;
read<double>(a);
print<double>(a);

Vector<int, 20> b;
read<int>(b);
print<int>(b);


// Vector<long,-40> c;

return 0;
}

Valid pana la instantierea
templateului
Test Vector
#include "Integer.h"
#include "Rational.h"
#include "Vector.h"
#include <iostream>
#include <typeinfo>
using namespace std;

template <class T> void print(Vector<T>& a){
for(int i=0;i<a.size();i++)
cout<<a.getElem(i)<<" ";
cout<<endl;
}

int main(){
Vector<Integer> a;
a.add(Integer(3));
a.add(Integer(4));
a.add(Integer(5));
a.add(Rational(2,7));
system("pause");
return 0;
}
La COMPILARE
Fisiere header
Atat declaratiile cat si definitiile unui template vor fi puse intr-un fisier
header

Regula generala pentru fisiere header: dont put anything that
allocates storage!

Template compilatorul nu va aloca spatiu in acel moment, ci doar
in momentul in care i se spune sa o faca (la instantiere)
Argumente ale template-ului
Template <class T> class A {};
Tipul argumentelor (T):

Void:
template <class T> class A{T* elem; };
A<void> a;

Argumente netipizate (expresii constante)
template <class T, int n> class A{
T elem[n];
};
A<float,100> b;
Cunoscut la compilare - evita alocarea dinamica a memorie
Argumente ale template-ului
Adresa unor obiecte externe
template <char* cp> class A{};
char c;
A<&c> a;

Adresa unei functii

template<void (*fp)(int)>class A{};

void f(int){}
A<f> a;
SirOrdonat
OrdSeq
-elem: T[*]
-n: Integer
+<<create>>OrdSeq()
+insert(e: T)
+dim(): Integer
+get(pos: Integer)
+<<destroy>>~OrdSeq()
T
int (*fc)(T,T)
CAP:int=10
SirOrdonat
#ifndef ORD_SEQ_H
#define ORD_SEQ_H
#include <iostream>
using namespace std;

template <class T, int (*cmpFun)(T,T), int CAP=10>
class OrdSeq{
T elem[CAP];
int n;
public:
OrdSeq(){n=0;}
void insert(T inf){
if(n==0) {elem[n++]=inf;return;}
if(cmpFun(elem[n-1],inf)){
elem[n++]=inf; return;
}
int p=0;
while((!cmpFun(inf,elem[p]))&&(p<n))
p++;
for(int j=n;j>p;j--) elem[j]=elem[j-1];
elem[p]=inf;
n++;
}

int dim(){return n;}

T get(int i){return elem[i];}
};
#endif
#include "OrdSeq.h"
#include <iostream>
using namespace std;

template <class T>int cresc(T a, T b){
return a<b;}

template <class T> int descresc(T a, T b){
return a>b;}

template <class T, int(*cmpFun)(T,T), int N> void
print(OrdSeq<T, cmpFun, N> o){
for(int i=0;i<o.dim();i++)
cout<<o.get(i)<<" ";cout<<endl;
}


int main(){
OrdSeq<int,descresc<int>,50> a;
a.insert(5);
a.insert(3);
a.insert(4);
print<int,descresc>(a);

OrdSeq<double, cresc <double>> b;
b.insert(3.4);
b.insert(4.5);
print<double,cresc>(b);
return 0;
}
Argumente ale templateului
TemplateTemplate.cpp
#ifndef TEMPLATE_H
#define TEMPLATE_H
#include <iostream>
using namespace std;

template <class T> class Array{
enum{CAP=10};
T* elem;
int cap;
int dim;
public:
Array(){
dim=0;
cap=CAP;
elem=new T[CAP];
}

void push_back (const T& e){
if (dim==cap) {
T* aux = new T[2*cap];
cap*=2;
for(int i=0;i<dim;i++)
aux[i]=elem[i];
delete [] elem;
elem=aux;
}
elem[dim++]=e;
}

T* begin() { return elem;}
T* end() {return elem+dim;}
~Array() {delete [] elem;}
};

template <class T, template <class> class Seq> class
Collection{
Seq<T> s;
public:
void append(const T& e){s.push_back(e);}
T* begin(){return s.begin();}
T* end(){return s.end();}
};
#endif


Test.cpp

#include "TemplateTemplate.cpp"

int main(){

Collection <int, Array> c;
c.append(2);
c.append(3);
int* p = c.begin();
while(p!=c.end()){
cout<<*p++<<" ";
}
return 0;
}

Alte templateuri
Argument template
Clase template inner
Multime
-elem: T[*]
-n: integer
<<create>>-Multime()
<<destroy>>-Multime()
<<create>>-Multime(: Multime)
<<CppOperator>>+=(: Multime): Multime
<<CppOperator>>++(: Multime): Multime
<<CppOperator>>+-(: Multime): Multime
<<CppOperator>>+*(: Multime): Multime
<<CppOperator>>++=(: T): Multime
<<CppOperator>>+-=(: T): Multime
+dim(): integer
+apartine(: T): integer
+getIterator(): iterator
T : class
CAP = 10
iterator
+crt: Integer
+iterator(: Multime)
<<CppOperator>>+operator++()
<<CppOperator>>+operator--()
<<CppOperator>>+operator+=(: Integer)
<<CppOperator>>+operator-=(: Integer)
<<CppOperator>>+operator(): T
<<inner>>
Multime.h
#ifndef MULT_H
#define MULT_H
#include <iostream>
using namespace std;

template <class T, int CAP=10> class Multime{
private:
T elem[CAP];
int n;
public:
Multime();
~Multime();
Multime(const Multime&);
Multime& operator=(const Multime&);
Multime operator+(const Multime&) const;
Multime operator-(const Multime&) const;
Multime operator*(const Multime&) const;
Multime& operator+=(const T&);
Multime& operator -=(const T&);

int dim();
int apartine(const T&) const;
class iterator;
friend class iterator;

class iterator{
Multime& m;
int crt;
public:
iterator (Multime& n):m(n){crt=0;};
void operator++(){++crt;}
void operator--(){--crt;}
T operator()(){return m.elem[crt];}
int valid(){return ((crt>=0)&&(crt<m.n));};
iterator& operator+=(int i){crt+=i;return *this;}
iterator& operator-=(int i){crt-=i; return *this;}
};

iterator getIterator();
};
#endif

Multime.cpp
#include "MULTT.H"

template <class T, int CAP> Multime<T,CAP>:: Multime(){
n=0;
}

template <class T, int CAP> Multime<T,CAP>:: ~Multime(){
}

template <class T,int CAP> Multime<T,CAP>::Multime(const
Multime<T,CAP>& m){
n=m.n;
for(int i=0;i<m.n;i++)
elem[i]=m.elem[i];
}

template <class T,int CAP > Multime<T,CAP>
Multime<T,CAP>::operator+(const Multime<T,CAP>& m) const{
Multime<T,CAP> r(*this);
for(int i=0;i<m.n;i++)
if(r.apartine(m.elem[i])==0)
r+=m.elem[i];
return r;
}

template <class T,int CAP> Multime<T, CAP> Multime<T, CAP>::operator-
(const Multime<T, CAP>& m) const{
Multime <T, CAP> dif;
for(int i=0;i<n;i++)
if(m.apartine(elem[i])==0) dif+=elem[i];
return dif;
}

template <class T,int CAP> Multime<T,CAP>
Multime<T,CAP>::operator*(const Multime<T,CAP>& m) const{
Multime<T,CAP> i;
for(int j=0;j<n;j++)
if(m.apartine(elem[j])) i+=elem[j];
return i;
}



template <class T, int CAP> Multime<T, CAP>& Multime<T,
CAP>::operator+=(const T& e){
if (!apartine(e)) elem[n++]=e;
return *this;
}
template <class T, int CAP> Multime<T, CAP>& Multime<T,
CAP>::operator-=(const T& e){
for(int i=0;i<n;i++)
if(elem[i]==e){
for(int j=i;j<n-1;j++)
elem[j]=elem[j+1];
n--;
}
return *this;
}

template <class T, int CAP> int Multime<T, CAP>::apartine(const T& e)
const{
for(int i=0;i<n;i++)
if(elem[i]==e) return 1;
return 0;
}


template <class T, int CAP> Multime<T, CAP>&
Multime<T,CAP>::operator=(const Multime<T, CAP>& m){
if (this==&m){}
else{
n=m.n;
for(int i=0;i<n;i++)
elem[i]=m.elem[i];
}
return *this;
}

template <class T,int CAP> int Multime<T, CAP>::dim(){
return n;}
template <class T, int CAP> Multime<T,CAP>::iterator
Multime<T,CAP>::getIterator() {
Multime<T,CAP>::iterator it(*this); return it;
}
Test.cpp
#include "MULTT.cpp"
#include <iostream>
using namespace std;

template <class T> void citMult(Multime<T>& a){
T el;
cin>>el;
while(el!=0){
a+=el;
cin>>el;
}
}


template <class T, int CAP> void
tipMult(Multime<T,CAP> a){
Multime<T,CAP>::iterator it=a.getIterator();
while(it.valid()){
cout<<it()<<" ";
++it;
}
cout<<endl;
}

template <class T,int CAP> void tipMult(Multime<T,CAP> a,
int step){
Multime<T,CAP>::iterator it=a.getIterator();
while(it.valid()){
cout<<it()<<" ";
it+=step;
}
cout<<endl;
}



int main(){
Multime<int> m;
citMult<int>(m);
tipMult<int>(m);
tipMult<int>(m,2);
return 0;
}

Argumente ale template-ului
Ce NU poate fi argument al template-ului:
Expresii constante de tip flotant

Adrese ale unor vectori

Adrese ale unor membri nestatici ai unor clase

Tipuri locale

Adrese ale unor obiecte locale

Clase template echivalente
Doua clase template se refera la aceeasi clasa daca:
Numele templateului e identic
Sunt in acelasi domeniu de vizibilitate
Argumentele lor au valori identice


template <class T, int n> class A{};
typedef short* pShort;
A<short*, 100> a1;
A<pShort, 100> a2;
Acelasi tip
Template si interfete
IStiva
+push(: T): void
+pop(): T
+empty(): bool
+peek(): T
<<destroy>>-IStiva()
T : class
StivaS
-elem: T[*]
-top: Integer
<<create>>+StivaS()
<<destroy>>+~Stiva()
StivaD
<<create>>+StivaD()
<<destroy>>+~StivaD()
Nod
-info: T
-next: Nod
<<create>>+Nod(: T, : Nod)
<<create>>+Nod(: T)
<<destroy>>+~Nod()
-top
<<inner>>
Stiva
IStiva.h
#ifndef ISTIVA_H
#define ISTIVA_H

template <class T> class IStiva{
public:
virtual void push(const T&)=0;
virtual T pop()=0;
virtual bool empty()const=0;
virtual T& peek()const=0;
virtual ~IStiva(){}
};
#endif

StivaS.H
#ifndef STIVAS_H
#define STIVA_S
#include "IStiva.h"

template <class T, int CAP=10> class StivaS: public
IStiva<T> {
T elem[CAP];
int top;
public:
StivaS(){top=0;}
StivaS(const StivaS& s){
for(int i=0;i<s.top;i++)
elem[i]=s.elem[i];
top=s.top;
}
void push(const T& e){elem[top++]=e;}
T pop(){return elem[--top];}
T& peek()const{return elem[top-1];}
bool empty()const{return top==0;}
~StivaS(){}
};
#endif

Stiva
StivaD.cpp

#ifndef STIVAD_H
#define STIVA_D
#include "IStiva.h"

template <class T> class StivaD:public IStiva<T>{

class Nod{
T info;
Nod* next;
public:
Nod(const T& e, Nod* n):info(e),next(n){}
Nod(const T& e):info(e), next(0){};
~Nod(){};
template <class T> friend class StivaD;

}*top;
public:
StivaD(){top=0;}
void push(const T& e){
top=new Nod(e,top);
}
T pop(){
Nod* aux=top;
T e=aux->info;
top=top->next;
delete aux;
return e;
}

T& peek()const{
return top->info;
}
bool empty()const{
return (top==0);
}

~StivaD(){
while(top){
Nod* a=top;
top=top->next;
delete a;
a=top;
}
}
};
#endif;

Test.cpp

#include "StivaS.cpp"
#include "StivaD.cpp"
#include <iostream>
using namespace std;


int main(){
IStiva<int>* s= new StivaD<int>;
s->push(2);
s->push(5);

while(!s->empty()){
cout<<s->pop()<<" ";
cout<<endl;
}
return 0;
}

Test Driven Development (TDD)
Metoda de dezvoltare a softului bazat pe iteratii

Cicluri de dezvoltare foarte scurte:
Programatorul scrie teste automate care esueaza initial
defineste o imbunatatire dezirabila a unei functionalitati
scrie cod pentru a trece testul

Incurajeaza proiectarea simpla si inspira incredere

Instrumente pentru C++:
Visual Assert
CPPUnit
WinUnit

API-uri Visual Assert pentru C
CFIX_ASSERT verifica orice tip de expresie care se evalueaza la true sau
false
CFIX_ASSERT( a == 1 );
CFIX_ASSERT( !"This will always fail" );
CFIX_ASSERT_OK
CFIX_ASSERT_SUCCEEDED
CFIX_ASSERT_FAILED
CFIX_ASSERT_HRESULT
CFIX_ASSERT_STATUS
CFIX_ASSERT_MESSAGE
CFIX_ASSERT_EQUALS_DWORD, CFIX_ASSERT_EQUALS_ULONG
CFIX_FAIL
CFIX_INCONCLUSIVE un test nu e relevant esuare
CFIX_INCONCLUSIVE( L"This test case cannot be run on WOW64" );
CFIX_INCONCLUSIVE( L"This test case requires admin privileges" );
CFIX_LOG pentru a scrie in loguri diverse informatii
CFIX_LOG( L"A simple log message" );
CFIX_LOG( L"Value is %x, Last error was: %d", foo, GetLastError() );



CFIXCC_ASSERT_EQUALS
compararea pe baza operatorului ==
Pentru valori flotante se accepta o deviatie de 10 unitati pe ultima pozitie
class SomeClass {
private:
int value;
public:
bool operator == ( const SomeClass& other ) const
{ return this->value == other.value; } ...
};

Teste cu succes:
CFIXCC_ASSERT_EQUALS( SomeClass( 1 ), SomeClass( 1 ) );
CFIXCC_ASSERT_EQUALS( L"test", L"test" );
CFIXCC_ASSERT_EQUALS( 1.9999999f, 2.0f ); .

Teste care esueaza:
SomeClass* a = new SomeClass( 1 );
SomeClass* b = new SomeClass( 1 );
CFIXCC_ASSERT_EQUALS( a, b );
CFIXCC_ASSERT_EQUALS( L"test", L"" );
Valorile egale, pointerii nu
Visual Assert API pt C++



CFIXCC_ASSERT_EQUALS_MESSAGE

Similar lui CFIXCC_ASSERT_EQUALS

Valoare asteptata si cea actuala sunt vizibile in raport
CFIXCC_ASSERT_EQUALS_MESSAGE( 2.0f, myValue, "Compar %f cu 2.0", myValue );
Visual Assert API pt C++
Visual Assert API pt C++
CFIXCC_ASSERT_NOT_EQUALS
Comparatia pe baza operatorului !=
Pointerii se compara pe baza adreselor, exceptie char* care sunt
convertite la tipul string
CFIXCC_ASSERT_NOT_EQUALS( 1, 2 );
CFIXCC_ASSERT_NOT_EQUALS( L"test", L"" );

CFIXCC_ASSERT_NOT_EQUALS_MESSAGE
CFIXCC_ASSERT_NOT_EQUALS_MESSAGE( 2.0f, FloatValue,
Verificam ca %f nu e egal cu 2.0", FloatValue );

Visual Assert API pt C++
CFIXCC_ASSERT_LESS[_OR_EQUAL]
CFIXCC_ASSERT_LESS( 1, 2 );
CFIXCC_ASSERT_LESS( L"a", L"b" );
CFIXCC_ASSERT_LESS_OR_EQUAL( -1, 0 );
CFIXCC_ASSERT_LESS_OR_EQUAL( -1, -1 );

CFIXCC_ASSERT_LESS[_OR_EQUAL]_MESSAGE
CFIXCC_ASSERT_LESS_OR_EQUAL_MESSAGE( 2.0f, FloatValue,
"Checking that %f is smaller than or equal to 2.0", FloatValue );
Visual Assert API pt C++
CFIXCC_ASSERT_GREATER[_OR_EQUAL]
CFIXCC_ASSERT_GREATER( 3, 2 );
CFIXCC_ASSERT_GREATER( L"c", L"b" );
CFIXCC_ASSERT_GREATER_OR_EQUAL( 1, -1 );
CFIXCC_ASSERT_GREATER_OR_EQUAL( -1, -1 );

CFIXCC_ASSERT_GREATER[_OR_EQUAL]_MESSAGE
CFIXCC_ASSERT_GREATER_OR_EQUAL_MESSAGE( 2.0f,
FloatValue, "Checking that %f is greater than or equal to 2.0",
FloatValue );
Construirea unei suite de teste
TestFixture clasa de baza din care trebuie derivate toate clasele
pentru testare

Implementarea testelor se face adaugand metode cu nume diverse
la clasa de teste

Pentru initializarea datelor membre ale clasei derivate se pot
suprascrie metodele Before and After se apeleaza inainte si dupa
fiecare metoda din clasa de test

Pentru initializarea resurselor globale se pot folosi metodele SetUp
si TearDown ruleaza o singura data pe test

Declaratia clasei TestFixture
namespace cfixcc {
class TestFixture {
public:
TestFixture();
virtual ~TestFixture();
virtual void Before();
virtual void After();
static void SetUp();
static void TearDown();
};
}
Construirea unei suite de teste
Pentru fiecare clasa trebuie furnizata constructia
CFIXCC_BEGIN_CLASS/ CFIXCC_END_CLASS

CFIXCC_METHOD folosita pentru a adauga o metoda
de test la suita de teste

CFIXCC_METHOD(< metoda_de_test> )
O metoda de test are signatura void TestMethod();

Exemplu
#include <cfixcc.h>
class SimpleFixture : public cfixcc::TestFixture {
public:
void Method01() { ... }
void Method02() { ... }
};

CFIXCC_BEGIN_CLASS( SimpleFixture )
CFIXCC_METHOD( Method01 )
CFIXCC_METHOD( Method02 )
CFIXCC_END_CLASS()
Unit testing Integer
#include <cfixcc.h>
#include "Integer.h"

class IntegerFixture : public cfixcc::TestFixture
{
private:
Integer x;
public:
void Test()
{
CFIX_INCONCLUSIVE(__TEXT("Not implemented"));
}

void TestCopyConstructor(){
Integer a(2);
Integer b(a);
CFIXCC_ASSERT_EQUALS(a,b);
CFIXCC_ASSERT_NOT_EQUALS(b,Integer(5));

}
void TestOperatorPlusUnar(){
Integer a(6);
Integer x=+a;
CFIXCC_ASSERT_EQUALS(a,x);
CFIXCC_ASSERT_NOT_EQUALS(a,Integer(-3));
}

void TestOperatorMinusUnar(){
Integer a(-3);
Integer b=-a;
CFIXCC_ASSERT_EQUALS(b, Integer(3));
}


void TestOperatorPlusBinar(){
Integer y(3);
Integer suma=y+x;
CFIXCC_ASSERT_EQUALS(suma, Integer(3));
Integer z(5);
suma=y+z;
Integer exp(8);
CFIXCC_ASSERT_EQUALS(suma, exp);
CFIXCC_ASSERT_EQUALS_MESSAGE( exp,
suma, "Compar 8 cu ", suma );

}

void TestOperatorEgal(){
Integer z;
CFIX_ASSERT(x==z);
CFIX_LOG( L"Test egalitate" );
//CFIX_ASSERT(x==Integer(4));
}


};

CFIXCC_BEGIN_CLASS(IntegerFixture)
//CFIXCC_METHOD(Test)
CFIXCC_METHOD(TestCopyConstructor)
CFIXCC_METHOD(TestOperatorPlusUnar)
CFIXCC_METHOD(TestOperatorMinusUnar)
CFIXCC_METHOD(TestOperatorPlusBinar)
CFIXCC_METHOD(TestOperatorEgal)
CFIXCC_END_CLASS()

You might also like