Está en la página 1de 9

3.

DEPURACIÓN Y REALIZACIÓN DE PRUEBAS

3.1. HERRAMIENTAS DE DEPURACIÓN.

La depuración permite identificar y corregir errores de programación mediante la


ejecución controlada del software.
Esta tarea la realiza el depurador.
Con el depurador se puede ver progreso del programa paso a paso, observándolos
valores de nuestros métodos, variables, funciones etc, en cada momento, tambien
permite establecer puntos de control que permiten interrumpir la ejecución de un
programa, mostrándonos los valores en el momento de la interrupción

3.2. ANÁLISIS DE CÓDIGO.

Siempre debemos asegurarnos que nuestro código funcionará correctamente aunque


realmente, siempre cometemos errores de funcionalidad , coherencia y en el propio
código.
Para identificar los errores en tiempo real utilizaremos en analizador esatico de
código.

3.2.1 Analizador ESTÁTICO DE CÓDIGO.

El analizador estático de código tiene 3 formas de indicarnos que algo va mal

• Errores
• advertencias
• mensajes

ejemplo: error de conversión:


int números= new int números[2];

Imposibilidad de convertir implícitamente el tipo int [] en int.


En cuanto a las advertencias, nos solemos encontrar con el errores de código que
provienen de la creación de una regla que calidad una convención a la hora de
realizar una operación concreta. Ej: division por cero.

Nosotros también podemos definir un conjunto de reglas personalizado:


nuevo>archivo→conjunto de reglas de análisis de código.
Ademas de establecer

Contratos de código:

Son un modo de generar advertencias y mensajes para los casos que consideremos.
Así podemos estar atentos a aquellos casos en los que hayamos pensado.
Para ello se utiliza System.Diagnostics.Contract que permitirá usar los en todos
Ensure y Requieres para nuestros propósitos

Ejemplo: calcular dimension del Array. Metodo ensure:

Public static int ObtenerDimension(){

Contract.Ensures(Contract.Result<int>()>0);
//codigo del metodo

return dimension;
}

Ejemplo: dimensiona dicho array mediante un valor pasado por parámetro.

Método Requieres:

public static void DimensionarArray(int[] array, int dimension){

contract.Requieres<Argument Exception>(dimension>0);
//codigo del metodo
}

se nos avisa si hemos roto la regla en algun caso, por ejemplo, asignando el valor 0

3.3. Casos de prueba

Condiciones que se establecen para comprobar si la aplicación funciona según lo


esperado.

Primeramente tienen un enfoque genérico al que se le van a añadiendo nuevas


condiciones.

Ejemplo: generación de un archivo de texto a partir de un formulario.


El enfoque genérico seria comprobar en un primer momento que se a creado
correctamente el archivo de texto . Las condiciones que se pueden añadir es si se
escribe correctamente los datos en el archivo de texto a partir de los datos del
formulario.

Los casos de prueba suelen tener un formato concreto para llevar su seguimiento e
informe especificando que es lo que se prueba, cuales son las condiciones premisas,
cual es el resultado esperado y cual es el resultado obtenido.
Un posible formato es:

ID ¿Que? Descripción Requisitos Resultado Resultado


esperado obtenido
001 APP Carga Que exista ok ok
fichero

Existen diversos tipos de casos de prueba que se define por la naturaleza de la


pruebas y no por el tipo de operaciones que conlleva la prueba. Por ejemplo: aunque
las pruebas de caja blanca vayan sumamente ligadas al procedimiento en si como una
correcta evaluación de un condicional y las pruebas de caja negra se realicen desde el
punto de vista del usuario final, podemos estar comprobando la misma operación y
los mismos datos aunque sea desde un punto diferente

3.3.1 CAJA BLANCA


Las pruebas de caja blanca se centra en el funcionamiento interno del programa,
observando y comprobando como se realiza una operación.

Son siempre lsa primeras pruebas que hay que realizar, pues revisan la estructura y
funcionalidad interna del programa. Asi se puede encontrar defectos basicos de
software no relacionados con la innterfaz del usuario.

Existen diversos tipos de pruebas:

. Prueba del camino básico: se basa en el principio que establece que cualquier
diseño procedimental se puede representar mediante un grafo de flujo. La
complejidad ciclomática de dicho grafo establece el numero de caminos
independientes. Cada uno de estos caminos se corresponde con un nuevo conjunto de
sentencias o una nueva condición.

El funcionamiento de este método consiste en definir los diferentes bloques para cada
camino posible y obtener los diferentes caminos para recorrelo por todas las opciones
posibles evitando saltarnos ninguna(examinar todos los caminos posibles y sus tutas
sin dejarnos ninguno).
Ejemplo: tenemos un programa que comprueba si son números pares y, de ser así.
Comprueba si son múltiplos recíprocos, Si los dos son impares, comprueba también
si son múltiplos de 3, y si no es ninguna de las anteriores, comprueba también si son
múltiplos recíprocos.
Tenemos 5 bloques:

• Inicio
• son los dos pares
• son los dos impares
• uno es par y otro es impar
• son múltiplos recíprocos
• son múltiplos de tres

por lo tanto tenemos tres posibles caminos:

• inicio> son los dos pares>son los dos múltiplos recíprocos(1,2,5).


• Inicio>son los dos impares > son múltiplos de tres(1,3,6).
• Inicio>uno es par y otro impar>son múltiplos recíprocos(1,4,5).

Los caminos posibles nos indican 3 cosas: tienen la misma complejidad, uno de los
caminos es redundante (el(1,2,5)y el(1,4,5)) y tenemos que comprobar tres caminos
para cubrir todas las posibilidades. Si ajustamos los condicionales, para fusionar el
bloque 2 con el bloque 4, tendríamos dos caminos de la misma complejidad.

• Prueba de condiciones: evalúan los casos posibles, en este caso deforma que
solo provengan de condicionales. Se estipula que si un mismo conjunto de
casos de prueba evaluá correctamente una condición o serie de condiciones, se
utiliza un método muy similar a una tabla de verdad, en donde se especifica
también la operación relacional.
Para que las pruebas sean efectivas, no deben ser redundantes, por lo que al
hacer la tabla de verdad hay que tener presentes las condiciones
cortocircuitadas. De este modo, para evaluar la expresión del estilo(E1||E2),
solo deberíamos evaluar el valor de E2 cuando E1 sea falso, ya que cuando al
expresión E1 es verdadera la comprobación termina por no ser necesario
evaluar el valor E2.
• Prueba de bucles: no evalúan como el resto de pruebas de caja blanca las
condiciones de dicho bucle, sino las posibilidades que nos ofrece. Todos los
bucles tienen una condición que nos establece la cantidad de interacciones que
nos va a realizar dicho bucle. Para evaluar correctamente todas las opciones,
tenemos que valorar los siguientes comportamientos para un bucle con”n”
iteraciones :
◦ El flujo del programa no entra ninguna vez al bucle.
◦ pasa una vez por el bucle.
◦ pasa dos veces por el bucle.
◦ pasa m veces por el bucle, siendo m<n.
◦ Hace n-1 y n+2 iteraciones en el bucle.
Para los bucles anidados, hay que realizar dichas evaluaciones en el bucle mas
interno e ir subiendo nivel a nivel, Primero de manera independiente y luego de
forma coherente con el resto de bucles de los que depende por la anidación.

Si se desea realizar correctamente las pruebas de caja blanca para bucles no


estructurados, se deben re diseñar, para que se ajusten a las condiciones de
programación estructurada.

3.3.2 CAJA NEGRA


Las pruebas de caja negra se enfocan en los métodos de entrada y salida de la
aplicación, no en
cuestión de formato, sino de validar y controlar los datos de entrada para evitar
errores y
obtener los resultados esperados.
Estas pruebas deben realizarse mediante el uso de la interfaz de la aplicación, ya que
es en el
controlador de la interfaz donde se deben validar los datos de entrada.

• Partición equivalente: consiste en dividir y separar los campos de entrada


según el tipo de dato y kas restricciones que conllevan.
Para evitar una cantidad de pruebas excesiva, se definen unas pruebas comunes
dependiendo del tipo de dato del campo en cuestión, Así, se agrupan los campos en
diferentes abiertas de pruebas, asegurando realizar ls pruebas, se pueden centrar la
división en 4 campos:

• Si el campo debe encontrarse en un rango, se especifica una clase de


quivalencia valida y dos invalidas(los limites inferiores y superiores.
• Si el campo requiere de una entrada especifica, se define una clase de
equivalencia valida y dos invalidas
• si el campo especifica a un elemento de un conjunto, se define una clase de
equivalencia valida y otra invalida.
• Si el campo especifica una condición de entrada lógica, se define una clase
de equivalencia valida y otra invalida.


.Análisis de valores límite: es una técnica equivalente a la partición
equivalente. Indica
que, si especificamos un rango delimitado de valores o un número de
valores
específicos, también se deberá probar por el valor inmediatamente superior
e
inmediatamente inferior de dichas cotas. Si nuestras cotas de valores son
“a” y “b”,
deberemos probar los valores “a-1”, “a+1”, “b-1” y “b+1”.
También hay que realizar la misma operación en las condiciones que estén
delimitadas
en tamaños, como por ejemplo un array de dimensión 5.
Para estas cuestiones y criterios, hay que aplicar estos valores en la salida
de la
aplicación para evitar errores en los límites de los elementos en donde
escribimos la
salida de la aplicación.

3.3.3 Rendimiento

Las pruebas de rendimiento miden el tiempo que le ha tomado a la aplicación realizar una acción
específica. Aunque depende de la máquina donde se está ejecutando la aplicación, sigue
teniendo validez, ya que permite probar y controlar el tiempo para un equipo concreto como
realizar operaciones de diferentes formas y ver cuál conlleva un mejor rendimiento.
Para realizar estas mediciones, se puede usar un cronómetro llamado StopWatch. Con él se
puede ver lo que ha tardado la aplicación en ejecutar los comandos mediante milisegundos,
aunque también se pueden usar los ticks o ciclos de proceso. Solamente hay que instanciar el
cronómetro y arrancarlo para que comience a medir.
En este programa , se utiliza un algoritmo que recorre una colección y guarda en
otra lista los valores de dicha colección.

La operación realizada con LINQ tarda mucho mas que si se utiliza un filtrado
“manual”. No siempre lo mas sencillo es mas eficaz, En muchas ocasiones la
busqueda que realiza el gestor de una base de dadtos es mas eficaz que cualquier
filtrafo u ordenacion mediante código.
En ocasiones, la Heurista de la operación nos impedirá obtener caminos mas cortos
para mejorar el rendimiento, pero no conviene caer en esta mala praxis, ya que a la
larga se produciran errores de rendimiento.

3.3.4 COHERENCIA
Las pruebas de coherencia son subjetivas, es decir, no están ligadas a la propagación
ni a los datos en si mismos, Se enfocan en el estudio del flujo de trabajo(workflow)
de la aplicación de un modo coherente.

Con ellas comprobamos si la funcionalidad de la aplicación es correcta y no si la


aplicación funciona correctamente.

Ejemplo: Supongamos que estamos desarrollando una aplicación que gestionará los
empleados y pedidos de un restaurante de comida a domicilio. Los empleados tienen
un”tipo” que especifica su función en la empresa, como”cocina”o”repartidor”. Por
ellos, aunque nuestra aplicación establezca perfectamente un empleado asignado para
repartir el pedido, no tiene sentido si el empleado asignado es un cocinero, por tanto
la aplicación no es coherente, puesto que funciona correctamente, sin errores, pero
permite operaciones que no tienen sentido en el ámbito sobre el que trabajamos .

Vamos a especificarlo mas. Imaginemos que los pedidos tienen un


campo”observaciones” para que el cliente exponga información adicional sobre el
pedido.¿tendría sentido que se pueda rellenar ese campo una vez se ha servido el
pedido? Dependiendo del uso de la aplicación, podría tener sentido o no. Si solo
pueden ser observaciones sobre el pedido en si mismo, no tendría sentido una vez
recibido este, pero si esas observaciones son valores sobre el servicios, si tendrían
sentidos. La conclusión es que hay que ser específicos y explícitos.
Cuando surgen dudas por la ambigüedad de uso de workflow de una aplicación, suele
ser un problema de diseño, los diagramas de secuencia deberían dejar bien claro el
flujo del programa , pero no siempre es así, ya que en ocasiones las peticiones
ambiguas y en ocasiones tan especificas que complican y ofuscan el trabajo.

3.4 PRUEBAS UNITARIAS

las pruebas unitarias son pruebas de

son pruebas individuales para un método o clase, realizadas de manera sistemática a


modo de batería de pruebas, donde conocemos los datos de entrada y sabemos cual
seria el resultado esperado.

Hoy en día para esta tarea existe la programación de pruebas automáticas que se crea
cada vez que se implementa una nueva funcionalidad o método, y las que nos
permiten ejecutar las baterías de pruebas de una manera ordenada visualizando todos
los resultados.

Estas pruebas imprescindibles en el desarrollo colaborativo

3.4.1 Metodologia

Las pruebas deberían implementarse d emanera sistematica con nada nueva


funcionalidad que se añada, teniendo en cuenta las pruebas actualizadas en casa
momento.Es importante que las pruebas se realicen y ejecuten de manera
incremental, por lo que en este modo aunque hallamos comprobado la funcionalidad
anterior en varias ocasiones con los resultados esperados comprobaríamos que todas
las pruebas que dicho funcionamiento no se ha visto alterado
Antes de implementar una nueva funcionalidad, primero hay que pensar como
deberia probarla para revisar que se ejecuta correctamente. Esto nos permite llevar un
desarrollo en el que tenemos las ideas muy claras y se pueden crear las pruebas
inmediatamente después de codificar la funcionalidad sin que el rendimiento se vea
afectado.

3.4.2 Nunit
Nunit es una aplicación disponible como extensión que permitirá la integración con el
entorno de desarrollo.
El instalador nos proveerá de las dll necesarias en el sistema. Para poder utilizarlo, se
debe agregar la referencia a “nunit.framework” e incluir el espacio de nombres en
nuestras clases test.
Después se instala extensión de VS para integrar los resultados en el sistema. Se
busca “nunit” desde el administrador de extensiones y se instala.
Con esto, se tendría el IDE preparado para trabajar con Nunit.
Para ver un ejemplo del uso de NUnit se ve su funcionamiento mediante un
proyecto. Crearemos un nuevo proyecto, una biblioteca de clases por ejemplo,
Dentro de dicho proyecto, crearemos las clases. En una implementaremos diversos
diversos métodos

También podría gustarte