Vous êtes sur la page 1sur 13

Guı́a de Unitarium4C v0.3.

4
Andreu Correa Casablanca
08 de Diciembre, 2010
Este texto ha sido escrito por Andreu Correa Casablanca <castarco@gmail.com> en un
entorno GNU/Linux gracias a Kile y LATEX 2ε .

Este texto está licenciado bajo la


Licencia Creative Commons Attribution-ShareAlike 3.0.
Contents
1 Introducción 1

2 Instalación 2

3 Cómo crear tests unitarios 3

4 Cómo extender Unitarium4C 4

A Tabla de funciones assert 5


A.1 Valores booleanos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
A.2 Valores numéricos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
A.3 Vectores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
A.4 Matrices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
A.5 Cadenas de texto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

B Convenciones de nomenclatura 9
B.1 Estructura de los nombres de funciones . . . . . . . . . . . . . . . . . . . . . . . 9
B.2 Abreviaturas de nombres de tipos . . . . . . . . . . . . . . . . . . . . . . . . . . 10

i
1 Introducción
Unitarium4C es una biblioteca escrita en lenguaje C con el objetivo de facilitar la creación de
tests unitarios de forma sencilla en dicho lenguaje (bajo la licencia .
Esta biblioteca nació en el contexto de una práctica de la asignatura de cálculo numérico
en la Universidad de Barcelona y uno de los principales objetivos del proyecto es que sea útil
especialmente para el desarrollo de software cientı́fico o ingenieril.
Actualmente la librerı́a soporta números enteros, en punto flotante, complejos, vectores y
matrices (con enteros, números de punto flotante y complejos) y cadenas de texto. Las funciones
de comparación permiten usar un factor de tolerancia, lo que puede resultar muy útil ya que
en muchos casos los resultados de ciertos cálculos no pueden ser exactos.
Unitarium4C se ha creado con la intención de que sea fácilmente extensible, para ello se ha
buscado crear un código lo suficientemente limpio, claro y autoexplicativo. Aunque el lenguaje
C está diseñado para ser usado dentro del paradigma de la programación estructurada (y poco
más), Unitarium4C está pensada siguiendo el paradigma de orientación a objetos con algunos
trazos de programación funcional.
En la última versión (0.3.4) de Unitarium4C se introdujeron nuevas macros que permiten
fabricar funciones assert en muy pocos pasos y de forma sencilla, intentando evitar las tareas
repetitivas.

1
2 Instalación
Aunque por el momento no han sido creados paquetes instalables para ningún sistema operativo,
la instalación de Unitarium4C es bastante sencilla. El proyecto no cuenta con página web
propia, pero el repositorio de código está alojado en www.gitorious.org.

1· En primer lugar descargaremos la versión 0.3.4 de Unitarium4c desde la dirección:

http://gitorious.org/unitarium4c/unitarium4c/archive-tarball/v0.3.4

o bién podemos descargar la última versión del repositorio (aunque lo desaconsejamos


porque todavı́a no se ha estabilizado suficientemente la nomenclatura) usando el siguiente
comando:

git clone git://gitorious.org/unitarium4c/unitarium4c.git unitarium4c

para ello deberéis tener instalado en vuestro sistema el programa Git1 .

2· En segundo lugar desempaquetamos el fichero y entramos en el directorio recien creado


(en caso que hayáis descargado el código con Git no tendréis que desempaquetar, lo que
resulta obvio). Podréis ver varios archivos (textos de licencia, changelogs y poco más) y
dos directorios (src y doc). En el directorio doc encontraréis este mismo manual, mientras
que en src es donde está la parte interesante.

3· Entramos en src, y solo tenemos que ejecutar como superusuario la orden

make install

la instalación ha sido completada :D .

Ahora los archivos de cabecera y las bibliotecas (estática y dinámica) ya son accesibles a
cualquier programa que queráis escribir con ellas. Es interesante que veáis el código de ejemplo
que hay en example.c, es bastante largo y a priori puede parecer complicado, pero la clave está
en que cada una de las funciones es un test diseñado para verificar el buen funcionamiento de
Unitarium4C, si analizáis la función main veréis que el proceso se reduce a crear funciones con
asserts e ”instalarlas” como tests en la función main.
Para compilar el programa de ejemplo solo tendréis que teclear make example, una vez
hecho ésto, con teclear ./example en la lı́nea de comandos éste se ejecutará. Aparecera una
lista en la que algunos términos aparecerán como OK y otros como FAILED, esto se ha hecho
deliberadamente para comprobar que los asserts fallan cuando tienen que hacerlo y no fallan
cuando no tienen que hacerlo. En particular, en ésta versión deberı́a haber 58 fallos (y 58
aciertos), alternados en grupos de 2. Si no es ası́ es que algo extraño ha sucedido.

1
Creado por Linus Torvalds, podéis encontrarlo en http://git-scm.com/, aunque la mayorı́a de distribu-
ciones GNU/Linux lo incluyen en sus repositorios. En Debian y Ubuntu lo podéis instalar con el comando
apt-get install git.

2
3 Cómo crear tests unitarios
Crear tests unitarios con Unitarium4C es muy sencillo. Básicamente, lo único que se tiene que
hacer es crear una función (que será el test), y en ella hacer las comprovaciones pertinentes
con las funciones assert. Una vez hecho ésto, se instalará el test en la función principal del
programa. He aquı́ un ejemplo:

1 // Test s o b r e v a l o r e s b o o l e a n o s
2 void Boolean_Tests ( ) {
3 assert_true ( 0 ) ;
4 assert_false ( 1 ) ;
5
6 assert_true ( 1 ) ;
7 assert_false ( 0 ) ;
8 }
9
10 // Test s o b r e i g u a l d a d e s e n t r e e n t e r o s
11 void Int_Tests ( ) {
12 int a , b ;
13
14 do {
15 a = rand ( ) ;
16 b = rand ( ) ;
17 } while ( a == b ) ;
18
19 assert_eq_int ( a , b ) ;
20 assert_eq_int ( b , a ) ;
21
22 assert_eq_int ( a , a ) ;
23 assert_eq_int ( b , b ) ;
24 }
25
26 // Funcion p r i n c i p a l
27 int main ( int argc , char ** argv ) {
28 // Annadimos l o s t e s t s que queremos e j e c u t a r
29 add_test ( Boolean_Tests , " Boolean Test " ) ;
30 add_test ( Int_Tests , " Int Test " ) ;
31
32 // Ejecutamos l o s t e s t s
33 exec_tests ( ) ;
34
35 // Mostramos l o s r e s u l t a d o s ( en l a l i n e a de comandos )
36 show_results ( argc , argv ) ;
37
38 // Liberamos r e c u r o s
39 clear_tests ( ) ;
40
41 // F i n a l i z a m o s e l programa
42 return 0 ;
43 }

Para ver qué funciones assert incorpora Unitarium4C podéis ir al apéndice A. También
podéis ver las convenciones de nomenclatura en el apéndice B. Las otras funciones importantes
son add test, exec tests, show results y clear tests, que están autoexplicadas en este
ejemplo.

3
4 Cómo extender Unitarium4C
Dado que todavı́a no se ha estandarizado ni estabilizado suficientemente la nomenclatura y
estructura interna de la biblioteca, esta sección permanecerá vacı́a. Ya hay métodos, pero
todos ellos son provisionales (por ello no las comentamos en el manual oficial).
En caso de querer extender la librerı́a siempre puedes contactar con el creador de Unitar-
ium4C o bucear un poco en el código. Además, cualquier contribución será bienvenida.

4
Apéndices

A Tabla de funciones assert


A.1 Valores booleanos
Por el momento sólo hay 2 funciones assert para valores lógicos. Se considera como cierto
cualquier valor entero diferente a 0, y falso el valor 0.

ˆ assert true (int boolean value) :


Indicará que ha habido un error en caso que boolean value sea 0.

ˆ assert false (int boolean value) :


Indicará que ha habido un error en caso que boolean value no sea 0.

A.2 Valores numéricos


Unitarium4C dispone de diversas funciones assert que permiten comparar ciertos valores numéricos,
incluyendo la posibilidad de ajustar la tolerancia de la comparación.

ˆ assert eq int (int a, int b) :


Sirve para comparar valores enteros (tipo int). Indicará que ha habido un error en caso
que a sea diferente de b.

ˆ assert eq int wtol (int a, int b, int tol) :


Sirve para comparar valores enteros (tipo int, con una cierta tolerancia). Indicará que ha
habido un error en caso que a difiera de b en una cantidad mayor al valor absoluto de
tol.

ˆ assert eq flt (float a, float b) :


Sirve para comparar valores racionales (tipo float). Indicará que ha habido un error en
caso que a sea diferente de b.

ˆ assert eq flt wtol (float a, float b, float tol) :


Sirve para comparar valores racionales (tipo float, con una cierta tolerancia). Indicará
que ha habido un error en caso que a difiera de b en una cantidad mayor al valor absoluto
de tol.

ˆ assert eq dbl (double a, double b) :


Sirve para comparar valores racionales (tipo double). Indicará que ha habido un error en
caso que a sea diferente de b.

ˆ assert eq dbl wtol (double a, double b, double tol) :


Sirve para comparar valores racionales (tipo double, con una cierta tolerancia). Indicará
que ha habido un error en caso que a difiera de b en una cantidad mayor al valor absoluto
de tol.

5
ˆ assert eq complex flt (complex float a, complex float b) :
Sirve para comparar valores complejos (tipo complex float). Indicará que ha habido un
error en caso que a sea diferente de b.

ˆ assert eq complex flt wtol


(complex float a, complex float b, complex float tol) :
Sirve para comparar valores complejos (tipo complex float, con una cierta tolerancia).
Indicará que ha habido un error en caso que a difiera de b en una cantidad mayor al valor
absoluto de tol.

ˆ assert eq complex dbl (complex double a, complex double b) :


Sirve para comparar valores complejos (tipo complex double). Indicará que ha habido un
error en caso que a sea diferente de b.

ˆ assert eq complex dbl wtol


(complex double a, complex double b, complex double tol) :
Sirve para comparar valores complex (tipo complex double, con una cierta tolerancia).
Indicará que ha habido un error en caso que a difiera de b en una cantidad mayor al valor
absoluto de tol.

A.3 Vectores
Unitarium4C dispone de diversas funciones assert que permiten comparar ciertos tipos de
vector, incluyendo la posibilidad de ajustar la tolerancia de la comparación.

ˆ assert eq int vector (int *a, int *b, int n) :


Sirve para comparar vectores de números enteros (tipo int* ). Indicará que ha habido un
error en caso que a sea diferente de b.

ˆ assert eq int vector wtol (int *a, int *b, int n, int tol) :
Sirve para comparar vectores de números enteros (tipo int*, con una cierta tolerancia).
Indicará que ha habido un error en caso que la distancia (con la norma del supremo) entre
a y b sea mayor al valor absoluto de tol.

ˆ assert eq flt vector (float *a, float *b, int n) :


Sirve para comparar vectores de números racionales (tipo float* ). Indicará que ha habido
un error en caso que a sea diferente de b.

ˆ assert eq flt vector wtol (float *a, float *b, int n, float tol) :
Sirve para comparar vectores de números racionales (tipo float*, con una cierta toleran-
cia). Indicará que ha habido un error en caso que la distancia (con la norma del supremo)
entre a y b sea mayor al valor absoluto de tol.

ˆ assert eq dbl vector (double *a, double *b, int n) :


Sirve para comparar vectores de números racionales (tipo double* ). Indicará que ha
habido un error en caso que a sea diferente de b.

6
ˆ assert eq dbl vector wtol (double *a, double *b, int n, double tol) :
Sirve para comparar vectores de números racionales (tipo double*, con una cierta toleran-
cia). Indicará que ha habido un error en caso que la distancia (con la norma del supremo)
entre a y b sea mayor al valor absoluto de tol.

ˆ assert eq complex flt vector (complex float *a, complex float *b, int n) :
Sirve para comparar vectores de números complejos (tipo complex float* ). Indicará que
ha habido un error en caso que a sea diferente de b.

ˆ assert eq complex flt vector wtol


(complex float *a, complex float *b, int n, complex float tol) :
Sirve para comparar vectores de números complejos (tipo complex float*, con una cierta
tolerancia). Indicará que ha habido un error en caso que la distancia (con la norma del
supremo sobre el vector, y la norma usual sobre los valores complejos) entre a y b sea
mayor al valor absoluto de tol.

ˆ assert eq complex dbl vector (complex double *a, complex double *b, int n) :
Sirve para comparar vectores de números complejos (tipo complex double* ). Indicará que
ha habido un error en caso que a sea diferente de b.

ˆ assert eq complex dbl vector wtol


(complex double *a, complex double *b, int n, complex double tol) :
Sirve para comparar vectores de números complejos (tipo complex double*, con una cierta
tolerancia). Indicará que ha habido un error en caso que la distancia (con la norma del
supremo sobre el vector, y la norma usual sobre los valores complejos) entre a y b sea
mayor al valor absoluto de tol.

A.4 Matrices
Unitarium4C dispone de diversas funciones assert que permiten comparar ciertos tipos de
matriz, incluyendo la posibilidad de ajustar la tolerancia de la comparación.

ˆ assert eq int matrix (int **a, int **b, int rows, int cols) :
Sirve para comparar matrices de números enteros (tipo int** ). Indicará que ha habido
un error en caso que a sea diferente de b.

ˆ assert eq int matrix wtol


(int **a, int **b, int rows, int cols, int tol) :
Sirve para comparar matrices de números enteros (tipo int**, con una cierta tolerancia).
Indicará que ha habido un error en caso que la distancia (con la norma del supremo) entre
a y b sea mayor al valor absoluto de tol.

ˆ assert eq flt matrix (float **a, float **b, int rows, int cols) :
Sirve para comparar matrices de números racionales (tipo float** ). Indicará que ha
habido un error en caso que a sea diferente de b.

ˆ assert eq flt matrix wtol


(float **a, float **b, int rows, int cols, float tol) :

7
Sirve para comparar matrices de números racionales (tipo float**, con una cierta toleran-
cia). Indicará que ha habido un error en caso que la distancia (con la norma del supremo)
entre a y b sea mayor al valor absoluto de tol.
ˆ assert eq dbl matrix (double **a, double **b, int rows, int cols) :
Sirve para comparar matrices de números racionales (tipo double** ). Indicará que ha
habido un error en caso que a sea diferente de b.
ˆ assert eq dbl matrix wtol
(double **a, double **b, int rows, int cols, double tol) :
Sirve para comparar matrices de números racionales (tipo double**, con una cierta tol-
erancia). Indicará que ha habido un error en caso que la distancia (con la norma del
supremo) entre a y b sea mayor al valor absoluto de tol.
ˆ assert eq complex flt matrix
(complex float **a, complex float **b, int rows, int cols) :
Sirve para comparar matrices de números complejos (tipo complex float** ). Indicará que
ha habido un error en caso que a sea diferente de b.
ˆ assert eq complex flt matrix wtol
(complex float **a, complex float **b, int r, int c, complex float tol) :
Sirve para comparar matrices de números complejos (tipo complex float**, con una cierta
tolerancia). Indicará que ha habido un error en caso que la distancia (con la norma del
supremo sobre matriz, y la norma usual sobre los valores complejos) entre a y b sea mayor
al valor absoluto de tol.
ˆ assert eq complex dbl matrix
(complex double **a, complex double **b, int rows, int cols) :
Sirve para comparar matrices de números complejos (tipo complex double** ). Indicará
que ha habido un error en caso que a sea diferente de b.
ˆ assert eq complex dbl matrix wtol
(complex double **a, complex double **b, int r, int c, complex double tol)
Sirve para comparar matrices de números complejos (tipo complex double**, con una
cierta tolerancia). Indicará que ha habido un error en caso que la distancia (con la norma
del supremo sobre la matriz, y la norma usual sobre los valores complejos) entre a y b sea
mayor al valor absoluto de tol.

A.5 Cadenas de texto


Aunque se preveé que en versiones posteriores Unitarium4C dé un mayor soporte al tratamiento
de cadenas de texto, por el momento solo hay disponible una sola función:
ˆ assert eq str (char *a, char *b) :
Sirve para comparar cadenas de texto. Indicará que ha habido un error en caso que el
texto de a sea diferente al texto de b. Es importante recalcar que sólo trabaja bien con
cadenas bien formateadas, pues no se impone ningún lı́mite en el tamaño de éstas, y de
no encontrar un 0 la función podrı́a causar un fallo de segmentación.

8
B Convenciones de nomenclatura
Si examináis la tabla de funciones assert del apéndice A podréis comprobar como todas las
funciones siguien un patrón regular que puede ayudarnos bastante a la hora de recordar los
nombres de las funciones.
Hemos realizado una clasificación sencilla de los criterios a tener en cuenta para la nomen-
clatura (abreviaturas de tipos y estructura de los nombres de funciones según su ámbito y
aplicación).

B.1 Estructura de los nombres de funciones


Todas las funciones de uso regular (es decir, que no sirvan para extender la propia librerı́a)
estarán escritas en minúsculas, y separando las palabras con barras bajas. El primer ejemplo
nos lo dan las funciones que debemos usar para añadir y ejecutar tests, ası́ como para mostrarlos
y liberar los recursos reservados: add test,exec tests, show results y clear tests.
Todas las funciones de assert seguirán el patrón:
assert tipoassert (valores a comprobar)
donde tipoassert indicará qué queremos comprobar en cada caso. Por el momento sólo hay
dos tipos generales, el que engloba la verificación de valores booleanos, y el que engloba las
comparaciones (de igualdad o equivalencia).
Las verificaciones de valores de verdad admiten solo la forma:
assert [true/false] (int boolean value)
Las comparaciones de igualdad o equivalencia toman la forma siguiente:
assert eq abreviaturadetipo[ opcional] (tipo a, tipo b[, opcional])
Para cada comparación se tendrá que conocer la abreviatura del tipo y ya estará.
Hay que tener en cuenta que tanto vectores como matrices precisan de información comple-
mentaria para ser procesadas (sus respectivos tamaños), por lo que donde en el caso general
escribirı́amos
tipo a, tipo b
escribiremos (en el caso de los vectores):
tipo a, tipo b, int n
donde n es el tamaño del vector. Y en el caso de las matrices escribiremos:
tipo a, tipo b, int rows, int cols
es decir, que añadiremos el número de filas y columnas, en ese orden.
Los tipos numéricos (y combinaciones de éstos, como vectores o matrices) por lo general
admiten una segunda forma, añadiendo wtol al final del nombre de la función y un parámetro
más del tipo que sea preciso (si se trata de vectores o matrices, el parámetro añadido tendrá el
tipo de los elementos individuales del vector o la matriz). Las funciones con la forma:
assert eq abrtipo wtol (tipo a, tipo b, tipo tol)
són las que admitiran una cierta tolerancia en las comparaciones indicada por el parámetro
tol.

9
B.2 Abreviaturas de nombres de tipos
Ciertos tipos básicos tienen definidas abreviaturas para ahorrar escritura (y, todo sea dicho,
alinear mejor el código), que son los siguientes:

char −→ chr
char* −→ str
int −→ int
float −→ flt
double −→ dbl
complex float −→ complex flt
complex double −→ complex dbl
Además, para los vectores, se añade como sufijo el texto vector, y en el caso de las matrices
matrix.

10