26
1 RESUMEN LABORATORIO DE PROGRAMACIÓN – PARCIAL 1 TEMA 1: PARADIGMAS DE PROGRAMACIÓN Paradigma de programación - Una forma - Un modelo - Describe estilos Un paradigma de programación es una propuesta tecnológica adoptada por una comunidad de programadores que trata de resolver uno o varios problemas claramente delimitados. La resolución de estos problemas debe suponer un avance significativo en al menos un parámetro que afecte a la ingeniería de software. Un paradigma de programación es una colección de modelos conceptuales que juntos modelan el proceso de diseño y determinan, al final, la estructura de un programa. Tipos de paradigmas: - Imperativo (estructurado): C / Basic - Orientado a Objetos: Smalltalk, java, C++ - Lógico: Prolog - Funcional: Scheme o Haskell - Otros Cada paradigma cuenta con: - Una forma de analizar el problema - Una forma de diseñar la solución. o Herramientas o Modelos - IDEs (Entorno Integrado de Desarrollo). - Métricas. - Forma de Documentar. - Un LENGUAJE adecuado Programación estructurada La programación estructurada se basa en una metodología de desarrollo de programas llamada refinamientos sucesivos: Se plantea una operación como un todo y se divide en segmentos más sencillos o de menor complejidad. Una vez terminado todos los segmentos del programa, se procede a unificar las aplicaciones realizadas por el pool de programadores. La programación estructurada propone segregar los procesos en estructuras lo más simple posibles, las cuales se conocen como secuencia, selección e interacción. Combinando esquemas sencillos se pueden llegar a construir sistemas amplios y complejos pero de fácil entendimiento. Demuestra que todo programa puede escribirse utilizando únicamente las tres estructuras básicas de control siguientes: • Secuencia: instrucciones ejecutadas sucesivamente, una detrás de otra. • Selección: bifurcación condicional de una o más operaciones. La instrucción condicional con doble alternativa, de la forma "if condición then instrucción 1, else instrucción 2". • Iteración: el bucle condicional "while condición do instrucción", ejecuta la instrucción repetidamente mientras la condición se cumpla. Esta técnica de programación conlleva las siguientes ventajas: a) El coste de resolver varios subproblemas de forma aislada es con frecuencia menor que el de abordar el problema global. b) Facilita el trabajo simultáneo en paralelo de distintos grupos de programadores. c) Posibilita en mayor grado la reutilización del código en futuras aplicaciones. PARADIGMA IMPERATIVO (filmina) Serie de instrucciones

Laboratorio de Informatica 2

Embed Size (px)

DESCRIPTION

Archivo / Paradigmas de Programacion / Software Factory / Debugging / Testing-----------------------------------------------------------Apunte proveniente de la cátedra Laboratorio de Informatica 2 - Universidad Tecnologica Nacional - Facultad Regional Mendoza - Argentina-----------------------------------------------------------Profesor Julio Monetti

Citation preview

Page 1: Laboratorio de Informatica 2

1

RESUMEN LABORATORIO DE PROGRAMACIÓN – PARCIAL 1 TEMA 1: PARADIGMAS DE PROGRAMACIÓN Paradigma de programación

- Una forma - Un modelo - Describe estilos

Un paradigma de programación es una propuesta tecnológica adoptada por una comunidad de programadores que trata de resolver uno o varios problemas claramente delimitados. La resolución de estos problemas debe suponer un avance significativo en al menos un parámetro que afecte a la ingeniería de software.

Un paradigma de programación es una colección de modelos conceptuales que juntos modelan el proceso de diseño y determinan, al final, la estructura de un programa.

Tipos de paradigmas:

- Imperativo (estructurado): C / Basic - Orientado a Objetos: Smalltalk, java, C++ - Lógico: Prolog - Funcional: Scheme o Haskell - Otros

Cada paradigma cuenta con:

- Una forma de analizar el problema

- Una forma de diseñar la solución.

o Herramientas

o Modelos

- IDEs (Entorno Integrado de Desarrollo).

- Métricas.

- Forma de Documentar.

- Un LENGUAJE adecuado

Programación estructurada La programación estructurada se basa en una metodología de desarrollo de programas llamada refinamientos sucesivos: Se plantea una operación como un todo y se divide en segmentos más sencillos o de menor complejidad. Una vez terminado todos los segmentos del programa, se procede a unificar las aplicaciones realizadas por el pool de programadores.

La programación estructurada propone segregar los procesos en estructuras lo más simple posibles, las cuales se conocen como secuencia, selección e interacción. Combinando esquemas sencillos se pueden llegar a construir sistemas amplios y complejos pero de fácil entendimiento.

Demuestra que todo programa puede escribirse utilizando únicamente las tres estructuras básicas de control siguientes:

• Secuencia: instrucciones ejecutadas sucesivamente, una detrás de otra.

• Selección: bifurcación condicional de una o más operaciones. La instrucción condicional con doble alternativa, de la forma "if condición then instrucción 1, else instrucción 2".

• Iteración: el bucle condicional "while condición do instrucción", ejecuta la instrucción repetidamente mientras la condición se cumpla.

Esta técnica de programación conlleva las siguientes ventajas:

a) El coste de resolver varios subproblemas de forma aislada es con frecuencia menor que el de abordar el problema global.

b) Facilita el trabajo simultáneo en paralelo de distintos grupos de programadores.

c) Posibilita en mayor grado la reutilización del código en futuras aplicaciones.

PARADIGMA IMPERATIVO (filmina)

• Serie de instrucciones

Page 2: Laboratorio de Informatica 2

2

• La orientación es hacia los estados.

• Elementos: abstracción procedimental, asignación, ciclos, …

• Un cómputo se expresa mediante modificaciones implícitas a la memoria.

• Las variables sirven como abstracción de celdas de memoria.

• Los resultados intermedios se almacenan en memoria.

• El control se basa en la iteración.

result := 1;

while n > 0 do

result := result * m;

n := n-1;

end while

Características del paradigma imperativo:

EFECTOS LATERALES: La existencia de estos efectos por una aparte, hacen que los programas no sean seguros puesto que cualquier posición de memoria puede ser actualizada de forma no adecuada, y otra parte, el concepto de una única memoria global actualizada de forma repetida por las instrucciones del programa dificulta la portabilidad y reusabilidad de código.

LIMITACION de APLICACIÓN: Su operativa se ajusta únicamente a aquellos problemas de naturaleza algorítmica clásica, similares en ejecución al de los cálculos matemáticos que no abordan con solvencia muchos problemas interesantes para resolver con la computadora.

CELDA DE MEMORIA ("variable") para almacenar valores. El componente principal de la arquitectura es la memoria, compuesto por un gran número de celdas donde se almacenan los datos. Las celdas tienen nombre (concepto de variable) que las referencian, y sobre los que se producen efectos de lado y definiciones de alias.

OPERACIONES DE ASIGNACIÓN: Estrechamente ligado a la arquitectura de la memoria, se encuentra la idea de que cada valor calculado debe ser "almacenado", es decir asignado a una celda. Esta es la razón de la importancia de la sentencia de asignación en el paradigma imperativo.

REPETICIÓN: Un programa imperativo, normalmente realiza su tarea ejecutando repetidamente una secuencia de pasos elementales, ya que en este modelo computacional la única forma de ejecutar algo complejo es repitiendo una secuencia de instrucciones.

Lenguajes usados para programación estructurada: COBOL, BASIC, C, PASCAL

Programación Lógica (programación declarativa)

La programación lógica, junto con la funcional, forma parte de lo que se conoce como programación declarativa.

La ecuación de Robert Kowalski establece la idea esencial de la programación lógica: algoritmos = lógica + control. Es decir, un algoritmo se construye especificando conocimiento en un lenguaje formal (lógica de primer orden), y el problema se resuelve mediante un mecanismo de inferencia (control) que actúa sobre aquél.

El lenguaje Prolog es el representante principal de este paradigma.

Prolog cuenta con dos tipos de estructuras: términos y sentencias.

- Los términos pueden ser constantes, variables o functores: • Constantes, representadas por una cadena de caracteres, pueden ser números o cualquier cadena que comience en

minúscula. • Variables, son cadenas que comienzan con una letra mayúscula. • Los functores, son identificadores que empiezan con minúscula, seguidos de una lista de parámetros (términos) entre

paréntesis, separados por comas.

- Las sentencias son reglas o cláusulas. Hay hechos y consultas. • Un hecho establece una relación entre objetos, y es la forma más sencilla de sentencia. • Una regla permite definir nuevas relaciones a partir de otras ya existentes.

PARADIGMA LOGICO (filmina)

Page 3: Laboratorio de Informatica 2

3

• Cómputo se expresa mediante la búsqueda de pruebas o por definición de predicados recursivos y anidados.

• No hay memoria implícita

• Los resultados intermedios se pasan mediante unificación.

• Control basado en recursión.

pot(M,0,1).

pot(M,N,R) :- resta(N,1,N1),

pot(M,N1,RT),

prod(M,RT,R).

Características del paradigma lógico:

- Construidos únicamente por expresiones lógicas, puede tener un solo valor de verdad verdadero o falso. - El orden de ejecución de las instrucciones no tiene nada que ver con el orden en que fueron escritas, a diferencia de los

lenguajes imperativos y funcionales como Lisp, en todos los mencionados, las instrucciones se ejecutan normalmente en orden secuencial.

- PROCESO DE INFERENCIA: Un lenguaje lógico usa dos tipos de elementos para inferir. Estos son: Hechos y reglas de inferencia, los dos son definidos en el programa lógico por el usuario.

- CAPACIDAD DE LOS LENGUAJES LÓGICOS: Un lenguaje lógico, como puede ser Prolog, permite contestar preguntas con respuestas “Sí”, “No”, o con elementos que satisfagan condiciones.

- UN LENGUAJE LÓGICO TIENE HECHOS, REGLAS DE INFERENCIA Y VARIABLES. Los hechos y reglas de inferencia se componen en general de proposiciones o predicados. Los predicados no se combinan de cualquier manera, sino que lo hacen como clausulas de Horn. Estas son un conjunto de predicados unidos por operadores lógicos OR, AND (o, y) que implican un solo predicado no negado.

Programación Funcional

• Colección de funciones que se combinan mediante composición de forma compleja para construir nuevas funciones. • Un programa es declarativo: no importa el cómo sino el qué. • La orientación es hacia la evaluación. • Elementos de programación: composición, orden superior, recursión. • Lenguajes: Impuros y estrictos. Puros y Perezosos. • Un cómputo se expresa a través de la aplicación y composición de funciones. • No hay memoria implícita • Los resultados intermedios se pasan directamente a otras funciones. • Control basado en recursión.

pot m 0 = 1

pot m (n+1) = m * (pot m n)

• Todo programa es visto como una función • Las subrutinas también toman la forma de una función. • Finalmente se ve toma la aplicación como una composición de funciones. • Principales Lenguajes: LISP, HASKELL

Como se realiza el cómputo en el lenguaje funcional

El Cómputo en el lenguaje Funcional se realiza por medio de funciones aritméticas que no maneja datos mutables o de estado. La diferencia con la programación imperativa es que las funciones imperativas pueden tener efectos secundarios, al cambiar el valor de cálculos realizados previamente. Por esta razón carecen de transparencia referencial, es decir, la misma expresión lingüística puede resultar en valores diferentes en diferentes momentos dependiendo del estado del programa siendo ejecutado. Con código funcional, en contraste, el valor generado por una función depende exclusivamente de los argumentos alimentados a la función. Al eliminar los efectos secundarios se puede entender y predecir el comportamiento de un programa mucho más fácilmente, y esta es una de las principales motivaciones para utilizar la programación funcional.

Los programas escritos en un lenguaje funcional están constituidos únicamente por definiciones de funciones entendiendo éstas como funciones puramente matemáticas, en las que se verifican ciertas propiedades como la transparencia referencial y por tanto, la carencia total de efectos laterales.

Page 4: Laboratorio de Informatica 2

4

Características de la programación funcional

- Los programas escritos en un lenguaje funcional están constituidos únicamente por definiciones de funciones, puramente matemáticas.

- Posee transparencia referencial y carece de efectos laterales, esto quiere decir que no modifica el estado de su entorno y que una expresión puede ser reemplazada por su valor; esto requiere que la expresión no tenga efecto colateral y que sea pura, o sea, que siempre retorne el mismo resultado con la misma entrada.

- Inexistencia de asignaciones de variables y falta de construcciones estructuradas como la secuencia o la iteración - Permite definiciones simples. - Facilita el estudio de aspectos computacionales. - Su carácter formal facilita la demostración de propiedades.

Programación Orientada a objetos

• Colección de objetos que interactúan intercambiando mensajes que transforman estados. • Elementos de programación: modelado de objetos, clases, herencia, encapsulamiento. • Un cómputo se expresa mediante intercambio de mensajes entre objetos. • Los objetos se agrupan en clases, las cuales se agrupan en jerarquías. • Los resultados se pasan como parámetros a mensajes.

Lenguajes usados para programación orientada a objetos: C++, VB.NET, JAVA, SMALLTALK, ADA

Características de la programación orientada a objetos

- ABSTRACCIÓN: Extraer las propiedades esenciales de un objeto que lo distinguen de los demás tipos de objetos y proporciona fronteras conceptuales definidas respecto al punto de vista del observador. Es la capacidad para encapsular y aislar la información de diseño y ejecución.

- ENCAPSULAMIENTO: Es el proceso de almacenar en un mismo compartimiento (una caja negra) los elementos de una abstracción (toda la información relacionada con un objeto) que constituyen su estructura y su comportamiento. Esta información permanece oculta tanto para los usuarios como para otros objetos y puede ser accedida solo mediante la ejecución de los métodos adecuados.

- HERENCIA: Es la propiedad que permite a los objetos construirse a partir de otros objetos. La clase base contiene todas las características comunes. Las sub-clases contienen las características de la clase base más las características particulares de la sub-clase. Si la sub-clase hereda características de una clase base, se trata de herencia simple. Si hereda de dos o más clases base, herencia múltiple.

- POLIMORFISMO: Literalmente significa "cualidad de tener más de una forma". En poo, se refiere al hecho que una misma operación puede tener diferente comportamiento en diferentes objetos. En otras palabras, diferentes objetos reaccionan al mismo mensaje de modo diferente.

LENGUAJE DE PROGRAMACIÓN

Un lenguaje de programación" es un lenguaje diseñado para describir el conjunto de acciones consecutivas que un equipo debe ejecutar. Por lo tanto, un lenguaje de programación es un modo práctico para que los seres humanos puedan dar instrucciones a un equipo.

El lenguaje utilizado por el procesador se denomina lenguaje máquina. Se trata de datos tal como llegan al procesador, que consisten en una serie de 0 y 1 (datos binarios).

El lenguaje máquina, por lo tanto, no es comprensible para los seres humanos, razón por la cual se han desarrollado lenguajes intermediarios comprensibles para el hombre. El código escrito en este tipo de lenguaje se transforma en código máquina para que el procesador pueda procesarlo.

El ensamblador fue el primer lenguaje de programación utilizado. Es muy similar al lenguaje máquina, pero los desarrolladores pueden comprenderlo. No obstante, este lenguaje se parece tanto al lenguaje máquina que depende estrictamente del tipo de procesador utilizado (cada tipo de procesador puede tener su propio lenguaje máquina). Así, un programa desarrollado para un equipo no puede ser portado a otro tipo de equipo. El término "portabilidad" describe la capacidad de usar un programa de software en diferentes tipos de equipos. Para poder utilizar un programa de software escrito en un código ensamblador en otro tipo de equipo, a veces será necesario volver a escribir todo el programa.

La ejecución de un programa con compilador requiere de dos etapas:

1) Traducir el programa simbólico a código máquina

2) Ejecución y procesamiento de los datos.

Otros lenguajes de programación utilizan un programa intérprete o traductor, el cual analiza directamente la descripción simbólica del programa fuente y realiza las instrucciones dadas.

El intérprete en los lenguajes de programación simula una máquina virtual, donde el lenguaje de máquina es similar al lenguaje fuente.

Page 5: Laboratorio de Informatica 2

5

La ventaja del proceso interprete es que no necesita de dos fases para ejecutar el programa, sin embargo su inconveniente es que la velocidad de ejecución es más lenta ya que debe analizar e interpretar las instrucciones contenidas en el programa fuente.

Por lo tanto, un lenguaje de programación tiene varias ventajas:

* es mucho más fácil de comprender que un lenguaje máquina.

* permite mayor portabilidad, es decir que puede adaptarse fácilmente para ejecutarse en diferentes tipos de equipos.

Principales formas de control en programación lógica, orientada a objetos y secuencial (imperativa)

Secuenciales: instrucciones secuenciales, bifurcación condicional – if y la iteración - while

Objetos: paso de mensajes entre objetos

Lógica: Hechos y reglas.

Sintaxis de un lenguaje

Un programa en cualquier lenguaje se puede concebir como un string de caracteres escogidos de algún conjunto o alfabeto de caracteres. Las reglas que determinan si un string es un programa válido o no, constituyen la sintaxis de un lenguaje.

Sintaxis: descripción del conjunto de cadenas de símbolos que serían considerados programas válidos.

Semántica de un lenguaje

Las reglas que determina el significado de los programas constituyen la semántica de los lenguajes de programación.

Un lenguaje de máquina tiene su semántica definida por el computador. Un programa en lenguaje de máquina "significa" exactamente lo que el computador hace cuando el programa "corre" o se ejecuta. Sin embargo, con un lenguaje de alto nivel no se puede dejar que el computador defina la semántica del lenguaje, puesto que no es posible "correr programas y ver" hasta que se tenga un compilador.

No se puede tener un compilador y saber qué es correcto hasta haber definido lo que los programas significan. Este enfoque interpretativo para definir la semántica de los lenguajes de programación consiste en postular una máquina abstracta y proveer reglas para la ejecución de programas sobre esta máquina abstracta. Así, estas reglas definen el significado de los programas.

Usualmente, la máquina abstracta se caracteriza por un estado consistente de todos los objetos datos, sus valores, y los programas con sus contadores de programa. Las reglas semánticas especifican cómo el estado es transformado por las diversas construcciones de los lenguajes de programación.

Semántica: descripción del significado de instrucciones y expresiones del lenguaje.

QUE ASPECTOS SE TIENEN EN CUENTA PARA ELEGIR UN PARADIGMA DE PROGRAMACION

Los aspectos que hay que tener en cuenta son inherentes al problema o producto específico que debamos responder. Depende de distintos factores como lo es el tipo de programa que queremos realizar, la plataforma para la cual queremos que sirvan nuestros programas, incluso siendo poco objetivos también entra el gusto por un lenguaje en especifico o por la compañía detrás del lenguaje.

Hay lenguajes que fueron pensados para resolver problemas más específicos, y que tienen en teoría un uso más acotado. Ejemplo de esto es el lenguaje MATLAB, que tiene un soporte específico en las operaciones de vectores y matrices que son fundamentales para la ingeniería y los problemas científicos.

Por otro lado, lenguajes de alto nivel como C le aseguran al programador una respuesta más rápida para el proceso de información que el lenguaje JAVA, pero la portabilidad que ofrece JAVA supera las posibilidades multiplataforma de C, ya que con sólo tener la máquina virtual de java instalada en el sistema el mismo programa va a correr sin problemas, mientras que C necesita estar compilado para cada SO.

Básicamente hay que plantear las características del producto y analizar el tipo de desarrollo que se va a llevar a cabo.

EJEMPLOS

A- Se necesita un programa que obtenga las raíces de una ecuación de segundo grado. Por ejemplo:

Paradigma: Estructurado

Lenguaje de programación: C

Plataforma: SO Linux.

Page 6: Laboratorio de Informatica 2

6

Características computadora: PC, SEMPRON 140 2.7 GHz

B- Almacene las fichas de inscripción de los socios de un club.

Paradigma: Orientada a Objetos

Lenguaje: PHP, porque sirve para la realización de sitios web dinámicos

Base de datos: Mysql

C- Un programa que juegue a las damas

Paradigma: Lógico

Lenguaje: Prolog

Características computador: PC, SEMPRON 140 2.7 GHz

D- Un programa que multiplique matrices

Paradigma: Imperativo

Lenguaje: C

E- Mantener la historia clínica de pacientes de un hospital

Paradigma: Orientado a Objetos

Lenguaje: Java

Computadora: PC, AMD SEMPRON 140.

SO: Linux

Base de datos: MYSQL.

Servidor: Intel XEON

SO: SUSE Linux Enterprise Server

F- Un cliente nos solicita un programa para la carga de información, donde sus clientes llenarán una ficha para actualizar sus datos (domicilio, datos filiatorios, gustos sobre los productos que consume, etc). Cantidad de clientes: 1262.

Paradigma de programación: Orientado a Objetos

Lenguaje propuesto: Java

Base de datos: MySql. Necesitamos la base de datos para almacenar la información y en el caso que el cliente tenga más de una computadora para registrar la información esto no nos limite.

G- Un geólogo nos solicita un programa que debe invertir una matriz que él mismo nos provee a través de un fichero de texto. Actualmente realiza esta operación utilizando una planilla de cálculos, pero el proceso demora demasiado tiempo. El resultado servirá como entrada a otra aplicación. Cantidad aproximada de elementos de la matriz: 55000.

Lenguaje de programación: C

Paradigma: Estructurado

H- Un ingeniero estudia la transferencia de calor sobre una placa metálica. Este proceso implica la resolución de un sistema de ecuaciones lineales de grandes dimensiones. Por otro lado, el ingeniero quiere ver los resultados de la distribución del calor en forma gráfica sobre un dibujo coloreado.

Paradigma estructurado

Se propone para resolver este problema MATLAB porque esta aplicación está orientada al cálculo científico técnico y permite resolver numerosos problemas aplicados y mostrar los resultados gráficamente con poco esfuerzo de programación, por lo que es un estándar en el desarrollo de aplicaciones de cálculo en ingeniería.

Está disponible para las plataformas Unix, Windows y Apple Mac OS X

Page 7: Laboratorio de Informatica 2

7

TEMA 2: FICHERO O ARCHIVO DE DATOS Definición de FICHERO

Un archivo o fichero informático es un conjunto de bits almacenado en un dispositivo. Un archivo es identificado por un nombre y la descripción de la carpeta o directorio que lo contiene. Es una manera de organizar los recursos usados para almacenar permanentemente datos en un sistema informático.

Un fichero es un conjunto de datos estructurados que pueden estar almacenados en un soporte de datos de forma que puedan ser tratados o utilizados de forma individual o global. Cada fichero se tiene que identificar con un nombre. Los elementos que forman un fichero se llaman registros y dichos registros se definen como la unidad mínima de información completa de un fichero.

CARACTERÍSTICAS DE LOS ARCHIVOS

- Independencia de la información respecto de los programas - La información almacenada es permanente - Un archivo puede ser accedido por distintos programas en distintos momentos o al mismo tiempo - Gran capacidad de almacenamiento.

CLASIFICACION DE LOS ARCHIVOS

- Permanentes o Maestros: Estos contienen información que varia poco. En algunos casos es preciso actualizarlos periódicamente.

- De Movimientos: Se acercan para actualizar los archivos maestros. Sus registros son de tres tipos: alta, bajas y modificaciones.

- De Maniobra o Trabajo: Tienen una vida limitada, normalmente menor que la duración de la ejecución de un programa. Su utilizan como auxiliares de los anteriores.

SEGÚN SU FUNCION.

a. Archivos Permanentes: Son aquellos cuyo registros sufren pocas o ninguna variación a lo largo del tiempo, se dividen en: - Constantes: Están formados por registros que contienen campos fijos y campos de baja frecuencia de variación en

el tiempo. - De Situación: Son los que en cada momento contienen información actualizada. - Históricos: Contienen información acumulada a lo largo del tiempo de archivos que han sufridos procesos de

actualización o bien acumulan datos de variación periódica en el tiempo. Ejemplo: Fichero que guarda los movimientos que se produjeron en las cuentas de un banco en 1.991. Almacena datos del usuario de un banco (nombre, apellido, dni, número de cuenta, registros de la cuenta del cliente, transacciones, operaciones realizadas – extracciones, depósitos – etc.) Accede a esos datos a través de un servidor, tanto el cliente de un banco como sus empleados.

b. Archivos de Movimiento: Son aquellos que se utilizan conjuntamente con los maestros (constantes), y contienen algún campo común en sus registros con aquellos, para el procesamiento de las modificaciones experimentados por los mismos.

c. Archivo de Maniobra o Transitorio: Son los archivos creados auxiliares creados durante la ejecución del programa y borrados habitualmente al terminar el mismo.

SEGÚN SUS ELEMENTOS.

a. Archivo de Entrada: Una colección de datos localizados en un dispositivo de entrada. b. Archivo de Salida: Una colección de información visualizada por la computadora. c. Constantes: están formados por registros que contienen campos fijos y campos de baja frecuencia de variación en el tiempo.

Fichero Maestro

Contienen informaciones que están variando con frecuencia y es necesario mantener al día permanentemente. La frecuencia de actualización o puesta al día de estos ficheros es elevada. Ejemplo: Fichero que contiene información del estado de las cuentas de los clientes de un banco.

Ejemplo: Inventario de una biblioteca. Almacena datos de socios (nombre y apellido, dni, dirección, número de socio, teléfono, email, fecha de egreso, fecha de devolución), datos de libros (título, número, género, autor, editorial). Estos datos son accedidos por el bibliotecario a través de una base de datos.

Page 8: Laboratorio de Informatica 2

8

Fichero de Maniobra

Son ficheros auxiliares creados durante la ejecución de programas o aplicaciones. El fin de estos ficheros es el de obtener cierta información que posteriormente será procesada para conseguir unos resultados esperados o calculados. Su período de vida es aún más corto que el de los ficheros de movimiento o transición, pues son destruidos antes de que el programa o la aplicación correspondiente finalicen su ejecución y el usuario no puede verlos.

Por ejemplo un fichero auxiliar que contiene la clasificación de un fichero de inventario para hacer un listado estadístico anual. Finalizado el proceso de listado, es destruido.

Se utilizan para almacenar provisionalmente resultados intermedios que serán utilizados posteriormente en el mismo proceso, o en un proceso diferente. La vida de estos ficheros termina en el momento en que finaliza, el proceso para el que fueron creados.

Ejemplo: Tratamiento fotográfico de una imagen. Almacena modificaciones sobre la imagen original, ya sea cambios de colores, transparencias, recortes, redimensiones, etc. Accede a esos datos Photoshop por ejemplo.

Medio de almacenamientos

Datos de una matriz con números flotantes: Archivo de texto plano

Una planilla de alumnos conteniendo nombre y documento: Base de datos, archivo delimitado

Una planilla de artículos conteniendo nombre, precio, nombre del proveedor, nivel de stock: Planilla de cálculos

Datos que genera nuestro programa para que otro usuario en Internet los utilice: Socket

Las temperaturas promedio de toda la semana: Archivo de texto plano, archivo delimitado

Las temperaturas promedio del mes para cada uno de los departamentos de la provincia: Archivo de texto plano, archivo delimitado

La ficha de clientes de nuestra empresa: nombre, nombres de los hijos, antigüedad, cargo: Base de datos, archivo delimitado

Datos generados por nuestro programa, pero que van a ser explotados por un segundo programa: Socket

Acceso a los archivos

Se refiere al método utilizado para acceder a los registros de un archivo prescindiendo de su organización.

Acceso secuencial: La forma más simple de estructura de archivo es el archivo secuencial. En este tipo de archivo, los registros se sitúan físicamente en el dispositivo en el orden en el que se van escribiendo, uno tras otro y sin dejar huecos entre sí. El acceso a los registros también debe hacerse en orden, de modo que para acceder al registro N es necesario pasar primero por el registro 1, luego por el 2, luego por el 3, y así hasta llegar al registro N.

Si el programa necesita acceder a registros individuales y no consecutivos, el acceso secuencial ofrece un rendimiento pobre y es preferible el acceso directo, que luego veremos.

Los archivos secuenciales (sobreentiéndase “archivos de acceso secuencial”) tienen un indicador de posición (o cursor) que señala qué registro fue el último que se accedió. Al abrir el archivo, el indicador se sitúa en el primer campo del primer registro. Cada acceso sobre el archivo desplazará el indicador de posición hacia el siguiente registro, hasta que ya no haya más registros que leer.

Cuando un archivo secuencial se abre para escribir datos en él, el indicador de posición se sitúa justo después del último byte del mismo, de manera que los datos sólo se pueden añadir al final.

La organización secuencial cuenta con varias ventajas:

- Es la más sencilla de manejar para el programador. - Si hay que acceder a un conjunto de registros consecutivos, o a todo el archivo, es el método más rápido. - No deja espacios entre registro y registro, por lo que se optimiza el uso del espacio en la memoria secundaria.

Pero también tiene algunos inconvenientes serios, como:

- Para consultar datos individuales, hay que recorrer todo el archivo desde el principio. Es decir, el acceso a registros individuales es, en general, lento.

Page 9: Laboratorio de Informatica 2

9

- Las operaciones de inserción y eliminación de registros solo pueden hacerse al final del archivo. Hacerlas con registros intermedios representa mover grandes bloques de información y, por lo tanto, consumir mucho tiempo.

Cantidad de búsquedas = N

Acceso directo o relativo: Explotan la capacidad de los discos para acceder directamente a cualquier bloque de dirección conocida. Como en los archivos secuenciales y secuenciales indexados, se requiere un campo clave en cada registro. Sin embargo, aquí no hay concepto de ordenamiento secuencial.

Cuando uno de los archivos contiene un número reducido de líneas resulta más eficiente emplear archivos de acceso directo, porque permiten reunir la información sin tener que visitar el archivo completo.

Un archivo se accesa directamente cuando el programa que lo utiliza especifica directamente la posición dentro del archivo que se accesará. Por ejemplo el programa puede leer la línea número 200, luego la línea 50000 y más tarde la línea 1.

En un archivo relativo existe una relación predecible entre la llave usada para identificar un registro y su localización dentro del archivo. Sin embargo es importante comprender que el ordenamiento lógico de los registros no necesita tener ninguna relación con su secuencia física. Los registros no necesariamente aparecen físicamente ordenados de acuerdo al valor de sus llaves.

Cada registro puede leerse / escribirse de forma directa solo con expresar su dirección en el fichero por él numero relativo del registro o por transformaciones de la clave de registro en él numero relativo del registro a acceder.

Acceso por índice: El archivo secuencial indexado mantiene las características básicas de los archivos secuenciales: los registros están organizados en una secuencia basada en un campo. Dos características se añaden: un índice del archivo para soportar los accesos aleatorios y un archivo de desbordamiento (overflow). El índice provee una capacidad de búsqueda para llegar rápidamente a las proximidades de un registro deseado. El archivo de desbordamiento (overflow) es similar al archivo de registro usado en un archivo secuencial, pero está integrado de forma que los registros del archivo de desbordamiento se ubican en la dirección de un puntero desde el registro precedente. En la estructura secuencial indexada más simple, se usa un solo nivel de indexación. El índice, en este caso, es un archivo secuencial simple. Cada registro del archivo índice tiene dos campos: un campo clave, que es el mismo que el campo clave del archivo principal y un puntero al archivo principal. Para encontrar un campo específico se busca en el índice hasta encontrar el valor mayor de la clave que es igual o precede al valor deseado de la clave. La búsqueda continúa en el archivo principal a partir de la posición indicada por el puntero.

Acceso dinámico: es cuando se accede a un archivo de cualquiera de las formas descriptas, acceso secuencial, directo o indexado.

BUSQUEDA BINARIA

Es necesario poder hacer búsquedas de registros en los archivos, siguiendo algún criterio o patrón.

Cuando hacemos una búsqueda de algún registro, ésta se hace principalmente a través de las llaves primarias.

Como se mencionó en la sección 5.4 se pueden realizar búsquedas secuenciales o de acceso directo.

Las búsquedas secuenciales son demasiado lentas ya que tienen que recorrer todo o casi todo el archivo; aún cuando se encuentre algún resultado podríamos saber de antemano que existe la posibilidad de encontrar más registros que cumplan con el criterio de búsqueda, de ahí que se deba continuar recorriendo todo el archivo.

Por otro lado las búsquedas por acceso directo son extremadamente rápidas, ya que podemos ir al "offset" deseado dentro del archivo, desafortunadamente esto requiere un método o fórmula para saber ubicar donde se encuentra un registro en el archivo.

De manera que si buscamos el registro de la persona con ID 35 sabremos que es el registro 35 del archivo y solo habría que multiplicarlo por su longitud (para el caso de registros de longitud fija) para obtener el desplazamiento que debemos hacer para leer del disco dicho registro.

Pero desafortunadamente este "método" no es muy adecuado en todos lo casos ya que no hay muchas maneras de garantizar que cada registro tendrá una posición única.

Ej. Si queremos hacer búsquedas de registros que no tienen números y solo texto (nombre, dirección, ciudad), la manera de relacionarlos con el lugar que ocupan en disco puede volverse demasiado complicado, aunque sigue siendo una opción.

Page 10: Laboratorio de Informatica 2

10

Por otro lado cuando se habla de búsquedas en memoria primaria, donde los accesos son mucho más rapidos, se han desarrollado algoritmos que garantizan el encontrar registros ágilmente. Tal es el caso de la Búsqueda Binaria cuyo tiempo de búsqueda es de O(log2 n).

El algoritmo de Búsqueda Binaria se basa en la metodología "divide y vencerás", de manera que dado un arreglo de registros "ordenados" podemos buscar rápidamente alguno partiendo el arreglo a la mitad y viendo en que mitad podría estar dicho registro, y a su vez esa mitad es dividida en 2 y así sucesivamente hasta encontrar el registro.

Para el caso de un archivo este algoritmo sería de gran utilidad:

Si por ejemplo tenemos un archivo de 2000 registros y quisiéramos hacer una búsqueda secuencial, ésta nos tomaría en promedio:

Para una búsqueda secuencial 1/2 n = 1000 comparaciones

Para una búsqueda binaria 1 + log2 2000 = 11 comparaciones

A simple vista luce mucho más atractiva la búsqueda binaria, pero hay un "precio" que pagar, el tener que ordenar el archivo.

Nota: recordemos que no es lo mismo ordenar un arreglo en memoria, que un conjunto de registros en disco, lo segundo es considerablemente más lento.

Diferencia entre planilla de cálculos y base de datos

Ejemplos: aplicación administrativa y aplicación financiera.

Si bien el concepto es básicamente el mismo, la organización de datos en tablas y campos, ambas aplicaciones podrían almacenar sus datos tanto en una planilla de cálculo como en una base de datos ésta última ofrece mayores ventajas.

En las hojas de cálculo te permiten ingresar datos, manejarlos y hacer que ella misma realice cálculos mediante un software especifico, mientras que las bases de datos por lo general utilizan un intérprete o motor de bases de datos que permite a otros lenguajes acceder a ellas mediante instrucciones como SQL y poder interactuar con ellas de forma externa.

En una base de datos es mucho más sencillo encontrar la información. Puede preguntar a la base de datos (por ejemplo, cuántas personas han aceptado venir a mi evento o qué cliente compró qué producto) y obtener una respuesta inmediatamente. Las bases de datos no sólo almacenan información, también solucionan problemas, responden a preguntas y toman decisiones. Puede crear fórmulas y cálculos para analizar la información y, de esta forma, creará informes rápidos que mejorarán la forma de compartir sus opiniones. Otra ventaja de las bases de datos es la impresión flexible. Las bases de datos permiten crear de manera más sencilla etiquetas de correo, informes, facturas, identificaciones para eventos y formularios de entrada de datos.

La base de datos a diferencia de la planilla de cálculo permite trabajar a multiusuarios permitiendo proveer servicio y procesamiento a múltiples usuarios simultáneamente.

Ventajas de una base de datos frente a una planilla de cálculos

- Independencia lógica y física de los datos. - Redundancia mínima. - Acceso concurrente por parte de múltiples usuarios. - Integridad de los datos. - Consultas complejas optimizadas. - Seguridad de acceso y auditoria. - Respaldo y recuperación. - Acceso a través de lenguajes de programación estándar.

• Control sobre la redundancia de datos:

Los sistemas de ficheros almacenan varias copias de los mismos datos en ficheros distintos. Esto hace que se desperdicie espacio de almacenamiento, además de provocar la falta de consistencia de datos. En los sistemas de bases de datos todos estos ficheros están integrados, por lo que no se almacenan varias copias de los mismos datos. Sin embargo, en una base de datos no se puede eliminar la redundancia completamente, ya que en ocasiones es necesaria para modelar las relaciones entre los datos.

• Consistencia de datos:

Page 11: Laboratorio de Informatica 2

11

Eliminando o controlando las redundancias de datos se reduce en gran medida el riesgo de que haya inconsistencias. Si un dato está almacenado una sola vez, cualquier actualización se debe realizar sólo una vez, y está disponible para todos los usuarios inmediatamente. Si un dato está duplicado y el sistema conoce esta redundancia, el propio sistema puede encargarse de garantizar que todas las copias se mantienen consistentes.

• Compartición de datos:

En los sistemas de ficheros, los ficheros pertenecen a las personas o a los departamentos que los utilizan. Pero en los sistemas de bases de datos, la base de datos pertenece a la empresa y puede ser compartida por todos los usuarios que estén autorizados.

• Mantenimiento de estándares:

Gracias a la integración es más fácil respetar los estándares necesarios, tanto los establecidos a nivel de la empresa como los nacionales e internacionales. Estos estándares pueden establecerse sobre el formato de los datos para facilitar su intercambio, pueden ser estándares de documentación, procedimientos de actualización y también reglas de acceso.

• Mejora en la integridad de datos:

La integridad de la base de datos se refiere a la validez y la consistencia de los datos almacenados. Normalmente, la integridad se expresa mediante restricciones o reglas que no se pueden violar. Estas restricciones se pueden aplicar tanto a los datos, como a sus relaciones, y es el SGBD (sistema de gestión de base de datos) quien se debe encargar de mantenerlas.

• Mejora en la seguridad:

La seguridad de la base de datos es la protección de la base de datos frente a usuarios no autorizados. Sin unas buenas medidas de seguridad, la integración de datos en los sistemas de bases de datos hace que éstos sean más vulnerables que en los sistemas de ficheros.

• Mejora en la accesibilidad a los datos:

Muchos SGBD proporcionan lenguajes de consultas o generadores de informes que permiten al usuario hacer cualquier tipo de consulta sobre los datos, sin que sea necesario que un programador escriba una aplicación que realice tal tarea.

• Mejora en la productividad:

El SGBD proporciona muchas de las funciones estándar que el programador necesita escribir en un sistema de ficheros. A nivel básico, el SGBD proporciona todas las rutinas de manejo de ficheros típicas de los programas de aplicación. El hecho de disponer de estas funciones permite al programador centrarse mejor en la función específica requerida por los usuarios, sin tener que preocuparse de los detalles de implementación de bajo nivel.

• Mejora en el mantenimiento:

En los sistemas de ficheros, las descripciones de los datos se encuentran inmersas en los programas de aplicación que los manejan. Esto hace que los programas sean dependientes de los datos, de modo que un cambio en su estructura, o un cambio en el modo en que se almacena en disco, requiere cambios importantes en los programas cuyos datos se ven afectados. Sin embargo, los SGBD separan las descripciones de los datos de las aplicaciones. Esto es lo que se conoce como independencia de datos, gracias a la cual se simplifica el mantenimiento de las aplicaciones que acceden a la base de datos.

• Aumento de la concurrencia:

En algunos sistemas de ficheros, si hay varios usuarios que pueden acceder simultáneamente a un mismo fichero, es posible que el acceso interfiera entre ellos de modo que se pierda información o se pierda la integridad. La mayoría de los SGBD gestionan el acceso concurrente a la base de datos y garantizan que no ocurran problemas de este tipo.

• Mejora en los servicios de copias de seguridad:

Muchos sistemas de ficheros dejan que sea el usuario quien proporcione las medidas necesarias para proteger los datos ante fallos en el sistema o en las aplicaciones. Los usuarios tienen que hacer copias de seguridad cada día, y si se produce algún fallo, utilizar estas copias para restaurarlos. En este caso, todo el trabajo realizado sobre los datos desde que se hizo la última copia de seguridad se pierde y se tiene que volver a realizar. Sin embargo, los SGBD actuales funcionan de modo que se minimiza la cantidad de trabajo perdido cuando se produce un fallo.

Page 12: Laboratorio de Informatica 2

12

TEMA 3: SOFTWARE FACTORY

Software factory: Es una empresa que hace análisis y desarrollo de aplicaciones en múltiples plataformas tecnológicas.

Outsourcing de software: es el proceso en el cual una firma identifica una porción de su proceso de negocio que podría ser desempeñada más eficientemente por otra corporación, la cual es contratada para desarrollar esa porción de negocio.

Arquitectura de múltiples capas: la arquitectura cliente/servidor tiene 2 tipos de nodos en la red: cliente y servidores. Algunas redes disponen de 3 redes: clientes que interactúan con los usuarios finales, servidores de aplicación que procesan los datos para los clientes y servidores de la base de datos que almacenan los datos para los servidores de aplicación.

La ventaja de la arquitectura de n-capas es que separa hacia fuera el proceso, eso ocurre para mejorar el balance de la carga en los diversos servidores. La desventaja es que pone más carga en la red, debido a una mayor cantidad de tráfico de la red. Es mucho más difícil programar y probar el software que en arquitectura de dos niveles porque tienen que comunicarse más dispositivos para terminar la transacción de un usuario.

Arquitectura orientada a servicios: Es un concepto de arquitectura de software que define la utilización de servicios para dar soporte a los requisitos del negocio. Brinda una forma de invocación de servicios (comúnmente web) que facilita la interaccion entre diferentes sistemas propios o de terceros.

Proyecto de software: es el proceso de gestión para la creación de un sistema o software, la cual encierra un conjunto de actividades, una de las cuales es la estimación. La estimación es la base de todas las demás actividades de planificación del proyecto y sirve como guía para una buena ingeniería de sistemas. Al estimar se tiene en cuenta los procedimientos técnicos, los recursos, los costos y planificación.

Los primeros ítems a tener en cuenta en el diseño de un proyecto es:

-Identificación de necesidades

-Estudio de viabilidad: económica, técnica y legal

-Análisis económico y técnico

-Modelado de la arquitectura del sistema

-Especificaciones del sistema

Principales recursos a tener en cuenta al diseñar el proyecto

-Recursos humanos: son seleccionados según la evaluación del ámbito del software y las habilidades que tengan para ser participes del desarrollo. El número de personas se determina según la estimación del esfuerzo del proyecto.

-Reutilización de los recursos de software, componentes, es importante para minimizar costos y tiempo de desarrollo.

-El entorno que soporta un proyecto software incorpora hardware y software. El hardware proporciona una plataforma para soportar las herramientas de software utilizadas para desarrollar los productos de trabajo.

Estudio de factibilidad

Factibilidad se refiere a la disponibilidad de los recursos necesarios para llevar a cabo los objetivos o metas señalados. Generalmente la factibilidad se determina sobre un proyecto. El estudio de factibilidad, es una de las primeras etapas del desarrollo de un sistema informático.

Page 13: Laboratorio de Informatica 2

13

El estudio incluye los objetivos, alcances y restricciones sobre el sistema, además de un modelo lógico de alto nivel del sistema actual (si existe). A partir de esto, se crean soluciones alternativas para el nuevo sistema, analizando para cada una de éstas, diferentes tipos de factibilidades.

Los tipos de factibilidades básicamente son:

* Factibilidad técnica: si existe o está al alcance la tecnología necesaria para el sistema.

* Factibilidad económica: relación beneficio costo.

* Factibilidad operacional u organizacional: si el sistema puede funcionar en la organización.

Para cada solución factible, se presenta una planificación preliminar de su implementación. Estos resultados se entregan a la gerencia, quienes son los que aprueban la realización del sistema informático.

El estudio de factibilidad, es una tarea que suele estar organizada y realizada por los analistas de sistemas. El estudio consume aproximadamente entre un 5% y un 10% del costo estimado total del proyecto, y el período de elaboración del mismo varía dependiendo del tamaño y tipo de sistema a desarrollar.

Una evaluación de los costos de desarrollo, comparado con los ingresos netos o beneficios obtenidos del producto o sistema desarrollado.

Viabilidad económica: un estudio de funciones, rendimiento y restricciones que puedan afectar la realización de un sistema aceptable.

Viabilidad técnica

Viabilidad legal: determinar cualquier posibilidad de infraccion, violación o responsabilidad legal en que se podría incurrir al desarrollar el sistema.

Alternativas: una evaluación de los enfoques alternativos del desarrollo del producto o sistema.

El estudio de viabilidad puede documentarse como un informe aparte para el alta de gerencia.

Ciclo de vida de desarrollo de un sistema. Relación con cada uno de los responsables de un proyecto.

1- Identificar problemas, oportunidades y objetivos:

Responsables: Analista, Cliente, Líder del Proyecto

2- Determinar información y requerimientos:

Métodos interactivos, métodos no intrusivos, preguntas (quien, que, donde, cuando y como), se confirma la idea que se tiene de la organización y sus objetivos.

Responsables: Analista, Cliente, Líder del Proyecto, trabajadores y gerentes del área de operaciones

3- Analizar necesidades del sistema

Crear los diagramas de flujo de datos, diagramas de procesos, desarrollar un diccionario de datos, analizar las decisiones estructuradas que se hayan tomado, preparar y presentar la propuesta del sistema.

Responsables: Analista, Cliente, Líder del Proyecto

4- Diseñar el sistema recomendado

Diseñar la interfaz del usuario, diseño de salidas, diseño de entradas, diseño de controles del sistema, diseñar archivos y/o base de datos del sistema, especificaciones de archivos y detalles de procedimiento, arboles o tablas de la decisión del producto.

Responsables: Analista, Cliente, Líder del Proyecto, diseñador, operadores

5- Desarrollar y documentar el software

Page 14: Laboratorio de Informatica 2

14

Diseñar y documentar el software usando diagramas de estructura, pseudo código, giagramas Nassi-Schneiderman; comunicar al programador lo que se requiere programar.

6- Testear y mantener el sistema

Probar y eliminar errores de los programas antes de que se entregue a los usuarios; probar el sistema informático con datos de muestra y luego con datos reales; gran parte del trabajo del programador consiste en el mantenimiento.

Responsables: Analista, Líder del Proyecto, diseñador de sistema, programadores

7- Implementar y evaluar el sistema

Capacitar a los usuarios en el manejo del sistema; conversión gradual del sistema anterior al actual; comprar e instalar los equipos necesarios; convertir los archivos del formato antiguo al nuevo; instalar el sistema; puesta en producción del nuevo sistema

Responsables: Analista, Líder del Proyecto, diseñador, programadores, operadores, cliente

En la carpeta tengo la siguiente lista de roles:

Analista de sistemas, ingeniero de sistemas, programador, diseñador, tester, técnicos, redes, DBA, cliente, perito, asesor legal, QA, asesor contable, consultoría, gerente de la empresa.

Roles y responsabilidades

Administrador del proyecto: administra y controla los recursos asignados a un proyecto, con el propósito de que se cumplan correctamente los planes definidos. Los recursos asignados pueden ser: recursos humanos, económicos, tecnológicos, etc. El administrador puede dirigir más de un proyecto. El foco de una buena administración está en el control y la coordinación de los diferentes eventos y actividades de un proyecto.

Analistas: se encarga del análisis de un proyecto de software, descomponiendo el problema en subproblemas de menor complejidad. Como el experto del problema es el cliente se hace necesario trabajar junto con el cliente para realizar el análisis y especificación del sistema a construir.

Para que el trabajo del analista tenga sentido para todos los integrantes del grupo se hace necesario ponerse de acuerdo en la forma como se realizara la especificación, así como la forma en que el grupo la entenderá. Esto sugiere el uso de un estándar en la etapa de análisis.

Una de las razone más frecuentes del fracaso de un desarrollo es la de realizar un análisis pobre. Debido al insuficiente esfuerzo dedicado a conocer y especificar el sistema que desea el cliente, los desarrolladores construyen sistemas que no cuentan con las características que el cliente desea.

Diseñadores: Es el encargado de realizar el diseño del sistema. Entre sus funciones esta:

- Generar el diseño arquitectónico y diseño detallado del sistema - Generar prototipos rápidos del sistema - Generar el documento de diseño arquitectónico de software y mantenerlo actualizado durante el proyecto - Velar porque el producto final se ajuste al diseño realizado

El propósito del diseño es la construcción de un sistema que cumpla con los requisitos: satisfaga una especificación funcional dada, cumpla con las limitaciones del medio receptor y uso de recursos, cumpla los requisitos implícitos y explícitos de rendimiento y uso de recursos, satisfaga criterios de diseño implícitos y explícitos en la forma del artefacto construido.

Programadores: Deben construir la especificación del sistema en código fuente ejecutable utilizando uno o más lenguajes de programación, así como las herramientas de software de apoyo a la programación.

Tester: su objetivo es detectar y eliminar los errores y defectos del sistema en construcción. Es el encargado de asegurar la calidad de un producto.

Entre sus tareas están:

Page 15: Laboratorio de Informatica 2

15

- Construir y aplicar los planes de prueba unitarios, de modulo, de sistema y aceptación parcial, manteniéndolos actualizados durante el proyecto.

- Velar por la completitud y exactitud de todos los documentos del proyecto. - Coordinar las inspecciones - Velar por la adhesión al estándar aportado para el desarrollo - Velar por la calidad del producto final

Aseguradores de calidad: Los factores dominantes en la administración de proyectos de software son los tiempos y costos de desarrollo, existiendo peligro en esto ya que al crecer la presión por cumplir con las fechas y reducir los costos es la calidad del producto el que sufre. Cuando se acelera el desarrollo del sistema generalmente se acorta lo considerado “no esencial” usualmente son las actividades de verificación y testeo, resultando un producto de calidad reducida. Para evitar esto debe haber un convencimiento de considerar la calidad como una meta final dentro del cumplimiento de los plazos y costos. La calidad es un atributo a cumplir por el desarrollador.

Administrador de configuración: Es una disciplina que se aplica tradicionalmente al desarrollo de sistemas de hardware, al desarrollo de elementos de hardware o sistemas de hardware/software. Su aplicación en conjunto con otras disciplinas lleva el desarrollo de sistemas en forma ordenada y estructurada.

Aplica vigilancia a:

- Identificar y documentar características funcionales y físicas de ítems de configuración - Auditar los ítems de configuración para verificar cumplimiento de las especificaciones, control de interfaces y documentos - Controlar cambios a los ítems - Registrar y reportar información necesaria para administrar ítems de configuración - Mantener el repositorio del proyecto actualizado con las últimas versiones de todos los entregables del proyecto. - Administrar el software utilizado para el control de versiones - Definir y controlar perfiles de acceso a los archivos del proyecto - Velar por la completitud y exactitud del repositorio del proyecto

Ingeniero de validación y verificación: Una de las metas necesarias en el desarrollo del proyecto es garantizar que el software que evoluciona continúe satisfaciendo las expectativas de los usuarios durante dicho proceso. Para lograr esta meta es necesario aplicar prácticas de ingeniería de software durante la evolución del producto. La mayoría de estas prácticas tratan de crear y modificar software para maximizar la probabilidad de satisfacer las expectativas de sus usuarios. Otras prácticas tratan de asegurar que el producto cumplirá con las expectativas de dichos usuarios, conocidas como validación y verificación del software.

Validación se refiere al proceso de evaluación del software al final de su proceso de desarrollo para asegurar que está libre de fallas y cumple con sus requisitos. Una falla se define como un comportamiento incorrecto.

V&V es una ayuda para determinar que los requisitos del usuario han sido implementados correctamente. El objetivo principal es analizar y testear el software en forma completa durante el desarrollo para determinar que el software ejecuta sus funcionalidades correctamente, que no ejecute funciones no definidas, y proveer información sobre su calidad y confiabilidad. En conclusión las personas que hacen el V&V deben evaluar que tan bien el software está cumpliendo con sus requisitos técnicos y sus objetivos de seguridad y confiabilidad.

Las tareas del V&V son analizar, revisar, demostrar y testear todas las salidas del desarrollo del software.

Documentador: Durante el proceso de desarrollo del software se genera una gran cantidad de documentación, dicha documentación debe ser almacenada en el repositorio del proyecto. La documentación sirve, entre otras cosas, para conocer la historia del proyecto, estos no se escriben al final del proyecto, se van generando junto con las diferentes fases del proyecto. A medida que avanza los documentos deben ir siendo modificados para mantener el estado de los documentos a la par del proyecto, los documentos van evolucionando para mostrar el estado más reciente del desarrollo del proyecto. Sin embargo el objetivo principal de la documentación es actuar como medio de comunicación entre los miembros del equipo, incluyendo al cliente, además también sirve para reducir la distorsión de ideas, ayudar al control del proyecto, almacenar la lógica de las decisiones y hacer visibles tanto las capacidades como las limitaciones del sistema.

Ingeniero de manutención: La manutención es la última fase del proceso de desarrollo, sin embargo toma una parte importante del presupuesto destinado al desarrollo. A medida que se desarrollan más programas, la cantidad de esfuerzo y recursos dedicados a la manutención crecerá. Al final algunas empresas pueden llegar a encontrarse con la barrera de la manutención, no pudiendo abordar nuevos proyectos debido a que todos sus recursos están dedicados a mantener programas antiguos.

Page 16: Laboratorio de Informatica 2

16

Solo el 20% del trabajo de manutención es usado arreglando errores. El 80% restante se utiliza adaptando sistemas existentes a cambios en su ambiente externo, realizando mejoras pedidas por usuarios y realizando reingeniería del sistema para usos futuros.

Se pueden distinguir distintos tipos de documentación según el público objetivo y el tipo de contenido:

- Documentación de arquitectura y diseño: proporcionan una visión general de cómo se va a desarrollar el proyecto y porque se hace de ese modo, se suelen generar en las fases iniciales y deben ser revisados al producirse cambios. La idea es disponer de una descripción del sistema donde se enumeran los componentes, la justificación de su elección, la funcionalidad esperada y las relaciones entre ellos.

- Documentación técnica: documenta el código, algoritmos, interfaces, etc. Es más detallada y es escrita mientras se implementa; usualmente lo más cómodo es mantenerla junto al código fuente.

- Documentación de usuario final: es una documentación que se entrega al usuario final, tanto usuarios avanzados como no. No suele tener relación con el código fuente, solo describe cómo usar los programas producidos, por lo que puede ser redactado por personas que no hayan estado involucradas en el desarrollo del sistema.

Cliente: cliente, usuario y usuario final suelen ser utilizados como sinónimos. Un cliente es aquella persona responsable de llevar a cabo el buen desempeño del proyecto, por parte de la empresa que contrata el desarrollo. El cliente debe representar los derechos y asumir los deberes de dicha empresa ante el equipo de desarrollo. Por lo tanto debe estar presente en todas las fases del desarrollo del producto y realizar todas las actividades que se esperan de él, aceptación provisional y final.

Por otro lado los usuarios corresponden a las personas que están operando día a día un sistema de software. Es la persona que conoce el problema y utiliza la herramienta. Un cliente y un usuario no siempre son lo mismo, ya que el cliente puede que no opere el sistema.

Un usuario final se refiere a aquella persona que utiliza el sistema, pero que es desconocida y no identificable. Paso esto en sistemas de información de uso masivo, como atención bancaria por internet, apoyo al comercio electrónico, etc.

En el desarrollo de software tener clientes comprometidos es vital para el éxito del proyecto, quien participe en todas las etapas y compartiendo deberes y responsabilidades.

Herramientas de un IDE durante el ciclo de vida de un sistema

Testeo del producto: JUnit, proporciona información sobre la calidad del producto bajo prueba, permitiendo a la empresa conocer y comprender los riesgos de implementación del software. Estas pruebas pueden implementar en cualquier momento del proceso de desarrollo. Sin embargo la mayoría de los test se producen después de que los requisitos han sido definidos y el proceso de codificación se ha completado. El encargado de estas tareas es el QA.

Documentación del producto: Es el texto escrito que acompaña al software en un proyecto. Algunas herramientas: doxygen, robodoc o naturaldocs (para multiples lenguajes) o epydoc, javadoc, perlpod (para lenguajes específicos).

Refactorización del código: Se usa a menudo para describir la modificación del código fuente sin cambiar su comportamiento, lo que se conoce como limpiar el código. Se realiza a menudo como parte del proceso de desarrollo del software: los desarrolladores alternan la inserción de nuevas funcionalidades y casos de prueba con la refactorización del código para mejorar su consistencia interna y su claridad.

Es la parte del mantenimiento del código que no arregla errores ni añade funcionalidad. El objetivo, es mejorar la facilidad de compresión del código o cambiar su estructura y diseño y eliminar código muerto, para facilitar el mantenimiento en un futuro. Netbeans trae consigo la herramienta Refactor ubicada en el menú principal o en el menú secundario, facilitando mover campos, métodos o clases en todo sin romper cosas.

Page 17: Laboratorio de Informatica 2

17

TEMA 4: DEBUGGING

Debugging (depuración) Es el proceso metodológico para encontrar y reducir errores o defectos en un programa informático o en una pieza de hardware.

La tarea de depuración de un error de software, suele requerir los siguientes pasos.

• Reconocer que ese error existe (un programa puede contener errores que jamás serán detectados). • Aislar la fuente del error. • Identificar la causa del error. • Determinar una solución para el error. • Aplicar la solución. • Probar el programa.

Los programas para la depuración son llamados depuradores o debugger, permiten ejecutar un programa, hacer pausas, volver a comenzarlo, ejecutarlo por partes, ver o cambiar los valores de las variables, etc.

Breakpoint (punto de parada) Es una pausa intencional y controlada durante la ejecución de un programa.

Pausar la ejecución de un programa permite conocer más acerca de su comportamiento, especialmente en ese instante que fue pausado. En el estado de pausa se pueden comprobar el estado de la memoria, las variables, los archivos, etc. relacionados al programa, permitiendo descubrir errores o comprender su comportamiento.

Un punto de interrupción se puede hacer inmediatamente antes de que un comando específico se ejecute, o inmediatamente después, o cuando se lee, escribe o modifica una ubicación específica en la memoria, también cuando se cumple un tiempo específico, cuando se presiona una determinada tecla o cuando ocurre un evento determinado.

Algunos programas depuradores permiten crear fácilmente puntos de interrupción, permitiéndonos ver el estado de las variables, entre otros datos, en el preciso momento que se realiza la pausa.

Los puntos de interrupción son uno de los conceptos más importantes en la depuración. Representan marcadores en el código en el que desea la ejecución del programa se detenga.

Tipo de Breakpoints:

Class: Permite detener la ejecución del programa cuando una clase se carga o descarga de la máquina virtual de Java. Cuando se agrega un punto de interrupción de clases, se aplica a cualquier código que se ejecuta durante la depuración.

Exception: Permite detener la ejecución del programa cuando se detecta una excepción, o simplemente se encuentran en el código que se ejecuta en la máquina JavaVirtual.

Method: Permite detener el programa cuando la ejecución del mismo entre o salga de uno o más métodos de una clase específica.

- Method Entry

- Method Exit

- Method Entry or Exit

Thread: Este tipo de punto de interrupción se puede configurar para detener la ejecución del programa si se inicia un subproceso o acabados. Esto puede ser extremadamente útil en la programación de aplicaciones cliente-servidor o servidores de multiproceso.

Field: Puede configurar este tipo de punto de interrupción para detener la ejecución del programa cuando acceda a un método, a un atributo o a ambos.

Page 18: Laboratorio de Informatica 2

18

Paso a paso

Step over: (F8) Corre el programa línea por línea para inspeccionar las variables, con la excepción de que si ve una llamada a un método no pasa por dicho método siguiendo a la siguiente línea.

Step into: (F7) Corre el programa línea por línea metiéndose dentro de cada método.

Step out: (Ctrl + F7) Si estaba ejecutando paso a paso y ha sido trasladado dentro de un método con Step Out se puede volver al procedimiento que se llamó.

Test Unitario (Ejemplo Junit) Un test unitario es un trozo de código desarrollado con el único objetivo de verificar que una rutina o función de nuestro código está funcionando según esperamos.

En definitiva, lo que Unit Test pretende es tener trozos de código que se encargarán de testear por separado y de forma independiente cada uno de los métodos de las distintas clases que compongan el programa desarrollado, para que cuando se haga alguna modificación en el código, posibles errores derivados de esa modificación puedan ser identificados y corregidos de manera rápida y eficaz.

La idea general que se destila de los tests unitarios es que si todas las partes de un código funcionan por separado, lo más probable es que el global que componen también funcione. Igualmente, siempre será necesario realizar un testeo general (o pruebas de integración) de la aplicación para comprobar que el todo que hemos compuesto funciona correctamente.

Algunas ventajas de usar Test Unitarios son:

- Facilita los cambios en la aplicación ya que las pruebas nos asegurarán que los nuevos cambios no han introducido errores.

- Simplifica la integración permitiendo llegar a la fase de integración con un grado alto de seguridad de que el código está funcionando correctamente.

- Documenta el código. Las propias pruebas son un libro abierto sobre el funcionamiento de la función y los resultados esperados.

- Separación de la interfaz y la implementación. Dado que la única interacción entre los casos de prueba y las unidades bajo prueba son las interfaces de estas últimas, se puede cambiar cualquiera de los dos sin afectar al otro.

- Los errores están más acotados y son más fáciles de localizar: dado que prepara un test para cada función que puede desenmascararlo.

- Aceleran el desarrollo del software debido a que ayuda a tener un código desacoplado, cada una de las funciones están pensadas para devolver un resultado que podrá ser testeado.

Traza y Aserción Ambas son técnicas básicas de depuración. Luego que detectamos un comportamiento incorrecto, tenemos que determinar el punto exacto del error.

Para facilitar dicha tarea se pueden utilizar técnicas llamadas “programación defensiva” y que son:

- Aserciones - Trazas de valores - Trazas de flujo de ejecución

La utilización de trazas y aserciones, en conjunto con la utilización de programas especialmente diseñados para depurar código (llamados Debuggers), facilitan la tediosa tarea de la localización y reparación del fallo.

Aserciones: La técnica de las aserciones (o afirmaciones) consiste en sembrar el código de chequeos de condiciones que suponemos deben cumplirse, de forma que si algo no es normal, lo detectemos lo antes posible, por sí mismo, en vez de tener que estar trazando marcha atrás las causas que han llevado a un fallo. Por ejemplo, puede controlarse que un puntero no valga NULL al inicio de una función que asume el puntero inicializado como precondición.

Cuando una variable toma un valor inesperado (erróneo en definitiva), el código de aserción despliega un mensaje indicando el problema y se detiene la ejecución del problema. De este modo, las consecuencias se pueden apreciar inmediatamente evitando que el programa arrastre el error durante un tiempo antes que se aprecie un fallo de ejecución o entregue un resultado final equivocado.

Page 19: Laboratorio de Informatica 2

19

Las aserciones suponen un trabajo extra para el programador, trabajo que se compensa durante el desarrollo y las pruebas; pero que parece redundante cuando el programa ha sido exhaustivamente probado y simplemente queremos que produzca resultados a la mayor velocidad posible. En otras palabras, queremos eliminar las aserciones cuando entremos en producción. No obstante, si teniendo un programa en producción se detecta una situación de fallo, conviene reactivar las aserciones para poder afinar rápidamente dónde está el origen del problema.

En resumen, las aserciones deberían poder activarse y desactivarse con comodidad para afrontar con el mismo código las situaciones de depuración de errores y de producción.

Trazas de valores: Son los listados que se generan cuando ejecutamos el código y nos van informando los valores que van tomando las variables. Por supuesto que acá también el programador tiene que escribirlas y determinar qué variables quiere examinar.

Trazas de flujos de ejecución: Al igual que las anteriores, éstas producen listados con marcas que nos indican por donde o que secciones del código se han ejecutado. También aquí es conveniente determinar qué secciones del código son relevantes pues no resulta muy razonable dejar trazas para cada línea de programa.

Ejemplo

//Aserción: una pregunta que nosotros esperamos que sea verdadera //La desventaja es que ensucia el código //JUnit limpia esto, porque se escribe en la clase hermana if (valorObtenido == valorEsperado) System.out.println("Correcto"); //Impresión de una traza

Que se debe considerar para depurar un programa en JAVA Para poder realizar la depuración en java se debe tener activado “Generate Debugging Info” en las propiedades del proyecto. Sin esta opción activada cuando se quiera generar un breakpoint sobre el código el IDE va a mostrar un error “Invalid LineBreakpoint DebugNotEnabled.java : 23”.

Programas de depuración - JDebugTool - JSwat - Omniscient Debugging - Xdebug — PHP debugger and profiler (configurable en Netbeans) - VB Watch Debugger — debugger for Visual Basic 6.0 - SoftICE: debugger para Windows (corre en modo kernel sin que Windows lo detecte). - Debugger for MySQL

Programa de debugger que usa NetBeans por defecto Java Platform Debugger Architecture (JPDA) es una colección de APIs que proporciona una infraestructura para depurar aplicaciones de J2SE. Incluye tres APIs:

- Java Debug Interface (JDI): Interfaz Java de alto nivel que incluye soporte de depuración remota. - Java Debug Wire Protocol (JDWP): Define el formato de la información y las solicitudes transferidas entre el proceso que

se está depurando y el front-end del depurador. - Java Virtual Machine Tools Interface (JVM TI): Una interfaz nativa que define los servicios de una máquina virtual Java.

Proporciona herramientas tales como depuradores y profilers. JVM TI se introdujo en J2SE 5.0 y sustituye JVMDI y JVMPI. JVMDI fue eliminado en Java SE 6 y JVMPI será eliminado en Java SE 7.

NetBeans Debugging Variables: La ventana Variables locales permite realizar el seguimiento del valor de todas las variables y objetos durante una sesión de depuración. Ser capaz de realizar el seguimiento del valor de todas las variables y objetos puede resultar muy valioso en la depuración permitiendo controlar los valores a medida que se crean y modifican a lo largo de todas las clases y métodos.

Watches: Es una característica de depuración que le permite especificar una declaración Java y seguimiento de su valor durante una sesión de depuración. Puede seguir los campos, objetos o expresiones en una ventana llamada la ventana Watches. Los relojes persisten a través de sesiones de depuración, por lo que no tiene que reiniciar ellos cada vez que los necesite. Esto puede ayudar en la depuración de los problemas persistentes en el.

Page 20: Laboratorio de Informatica 2

20

Call Stack: En la pila de llamadas se almacenan los métodos que son llamadas durante la depuración del programa y la línea donde se encuentra posicionado el punto de interrupción dentro del método.

Loaded Classes: muestra una lista de todas las clases utilizadas en el programa.

Breakpoint: En la ventana de puntos de interrupción se enumeran los puntos de interrupción en la actualidad fijados en todos los proyectos abiertos. La columna muestra una casilla de verificación para cada punto de interrupción. Si se selecciona, a continuación, el punto de interrupción estará habilitado, de lo contrario se desactivará.

Session: Se puede utilizar la ventana de sesiones para ver y detener todas las sesiones de depuración activa. La ventana de sesiones mostrará una lista de las sesiones de depuración actual. La ventana de sesión muestra el nombre de cada sesión, el estado actual que se encuentra, y la codificación del lenguaje.

Thread:

Sources: muestra la ruta donde se encuentra ubicado el proyecto y el JDK. La ruta de los archivos en uso durante la ejecución de la depuración del programa.

Debugging: Proporciona información sobre el punto de interrupción durante la depuración. La clase que está ejecutando, el método que está llamando, la línea donde se encuentra ubicado el Breakpoint.

TEMA 5: TESTING Testing El desarrollo de sistemas de software implica una serie de actividades de producción en las que las posibilidades de que aparezca el fallo humano son enormes. Los errores pueden empezar a darse desde el primer momento del proceso, en el que los objetivos pueden estar especificados de forma errónea o imperfecta, así en posteriores pasos de diseño y desarrollo. Debido a la imposibilidad humana de trabajar y comunicarse de forma perfecta, el desarrollo de software ha de ir acompañado de una actividad que garantice la calidad.

Las pruebas del software son un elemento crítico para la garantía de calidad del software y representa una revisión final de las especificaciones, del diseño y de la codificación.

Una vez generado el código fuente, el software debe ser probado para descubrir y corregir el máximo de errores posibles antes de su entrega al cliente. El objetivo es diseñar una serie de casos de prueba que tengan una alta probabilidad de encontrar errores. Las pruebas de software facilitan una guía sistemática para diseñar pruebas que comprueben la lógica interna de los componentes del software y verifiquen los dominios de entrada y salida del programa para descubrir errores en la funcionalidad, el comportamiento y rendimiento.

El software debe probarse desde dos perspectivas diferentes:

1- La lógica interna del programa se comprueba utilizando técnicas de diseño de casos de prueba de “caja blanca”. 2- Los requisitos del software se comprueba utilizando técnicas de diseño de casos de prueba de “caja negra”.

En ambos casos se intenta encontrar el mayor número de errores con la menor cantidad de esfuerzo y tiempo.

¿Que se obtiene?

Se documenta un conjunto de casos de prueba, diseñador para comprobar la lógica interna y los requisitos externos. Se determinan los resultados esperados y se guardan los resultados obtenidos.

Los casos de prueba deben abarcar todo el desarrollo.

1. La prueba es el proceso de ejecución de un programa con la intención de descubrir un error.

2. Un buen caso de prueba es aquel que tiene una alta probabilidad de mostrar un error no descubierto hasta entonces.

3. Una prueba tiene éxito si descubre un error no detectado hasta entonces.

Page 21: Laboratorio de Informatica 2

21

Estrategias de prueba • De Caja Blanca • De Caja Negra • Descendente • Ascendente • Incremental • Prueba de Estrés

Principios del testing En general, es impráctico, y a menudo imposible encontrar todos los defectos en un programa, ya que habría que probar todas las combinaciones de entrada, correctas e incorrectas, dadas en general por el número infinito de casos de prueba.

Por otro lado habría que probar todos los caminos posibles dentro de un programa, que pueden contener lazos (en general el número de casos de prueba no es infinito, pero usualmente puede considerarse como tal).

Testing es una tarea extremadamente creativa e intelectualmente desafiante.

Desde un punto de vista económico es imposible probar un programa para encontrar todos los defectos. Ni siquiera para los programas más triviales.

Evitar casos de prueba espontáneos y que no dejan registro, de hacerlo así solo se pierde el tiempo.

No planificar un caso de prueba bajo el supuesto tácito que no se encontrarán defectos.

La probabilidad de existencia de más defectos en una sección de un programa es proporcional al número de defectos ya detectados en dicha sección.

Objetivos de las pruebas • Encontrar defectos en el software

• Una prueba tiene éxito si descubre un defecto

• Una prueba fracasa si hay defectos pero no los descubre

Organización para las pruebas de software • Especificar requerimientos del producto en forma cuantificable antes de comenzar el testing.

• Establecer explícitamente los objetivos del testing.

• Comprender a los usuarios y desarrollar un perfil para cada categoría.

• Desarrollar un plan que enfatice pruebas de ciclo rápido.

• Construir software robusto que se diseñe para probarse a sí mismo.

• Usar revisiones técnicas formales.

• Desarrollar un enfoque de mejoramiento continuo para el proceso de testing.

Cada prueba debe • Dejar claro qué tipo de propiedades se quieren probar (corrección, robustez, fiabilidad, amigabilidad, etc.).

• Dejar claro cómo se mide el resultado.

• Especificar en qué consiste la prueba (hasta el último detalle de cómo se ejecuta).

• Definir cuál es el resultado que se espera (identificación, tolerancia,...). Cómo se decide que el resultado es acorde con lo esperado?

• Las pruebas angelicales carecen de utilidad, tanto si no se sabe exactamente lo que se quiere probar, o si no está claro cómo se prueba, o si el análisis del resultado se hace a ojo.

Tipos

• Pruebas de Verificación o Ver si cumple las especificaciones de diseño

• Pruebas de Validación o Ver si cumple los requisitos del análisis

Prueba de caja negra Se refiere a las pruebas que se llevan a cabo sobre la interfaz del software. O sea, los casos de prueba pretenden demostrar que las funciones del software son operativas, que la entrada se acepta de forma adecuada y que se produce un resultado correcto, así como que la integridad de la información externa (por ejemplo, archivos de datos) se mantiene. Una prueba de caja negra examina algunos aspectos del modelo fundamental del sistema sin tener mucho en cuenta la estructura lógica interna del software.

Page 22: Laboratorio de Informatica 2

22

La prueba de caja negra permite al ingeniero del software obtener conjuntos de condiciones de entrada que ejerciten completamente todos los requisitos funcionales de un programa. La prueba de caja negra no es una alternativa a las técnicas de prueba de caja blanca. Más bien se trata de un enfoque complementario que intenta descubrir diferentes tipos de errores que los métodos de caja blanca.

La prueba de caja negra intenta encontrar errores de las siguientes categorías: (1) funciones incorrectas o ausentes, (2) errores de interfaz, (3) errores en estructuras de datos o en accesos a bases de datos externas, (4) errores de rendimiento y (5) errores de inicialización y de terminación.

Concepto y terminología

• Pruebas en que se conoce sólo la interfaz

• Caja negra (black box: caja opaca)

• Se procura ejercitar cada elemento de la interfaz

Algunas clases de pruebas

• Cubrimiento → invocar todas las funciones (100%)

• Clases de equivalencia de datos

• Pruebas de valores límite

Prueba de caja blanca La prueba de caja blanca del software se basa en el minucioso examen de los detalles procedimentales. Se comprueban los caminos lógicos del software proponiendo casos de prueba que ejerciten conjuntos específicos de condiciones y/o bucles. Se puede examinar el «estado del programa» en varios puntos para determinar si el estado real coincide con el esperado o mencionado.

• Concepto y terminología

• Pruebas en que se conoce el código a probar

• Caja blanca (clear box: caja clara o transparente)

• Se procura ejercitar cada elemento del código

• Algunas clases de pruebas

• Pruebas de cubrimiento

• Pruebas de condiciones

• Pruebas de bucles

Pruebas de cubrimiento

• Ejecutar al menos una vez cada sentencia

• Se necesitan varios casos de prueba o Determinar posibles “caminos” independientes o Cada condición debe cumplirse en un caso y en otro no. En general, se necesitan tantos casos como condiciones,

más uno (número ciclomático)

• Puede ser imposible cubrir el 100% o Código que nunca se ejecuta: condiciones imposibles o Ejemplo: detección y notificación de errores internos en un código sin errores

Pruebas de condiciones

• Cumplir o no cada parte de cada condición

• Se necesitan varios casos de prueba o Determinar expresiones simples en las condiciones o Una por cada operando lógico o comparación o Cada expresión simple debe cumplirse en un caso y en otro no, siendo decisiva en el resultado

• Puede ser imposible cubrir el 100% o Expresiones simples no independientes

Pruebas de bucles

• Conseguir números de repeticiones especiales

Page 23: Laboratorio de Informatica 2

23

• Bucles simples o Repetir cero, una y dos veces o Repetir un número medio (típico) de veces o Repetir el máximo-1, máximo y ¡máximo +1!

• Bucles anidados o Repetir un número medio (típico) los bucles internos, el mínimo los externos, y variar las repeticiones del bucle

intermedio ensayado. o Ensayarlo con cada nivel de anidamiento

PRUEBAS INTEGRALES

Un neófito del mundo del software podría, una vez que se les ha hecho la prueba de unidad a todos los módulos, cuestionar de forma aparentemente legítima lo siguiente: «Si todos funcionan bien por separado, ¿por qué dudar de que funcionen todos juntos?» Por supuesto, el problema es «ponerlos juntos» (interacción). Los datos se pueden perder en una interfaz; un módulo puede tener un efecto adverso e inadvertido sobre otro; las subfunciones, cuando se combinan, pueden no producir la función principal deseada; la imprecisión aceptada individualmente puede crecer hasta niveles inaceptables; y las estructuras de datos globales pueden presentar problemas.

La prueba de integración es una técnica sistemática para construir la estructura del programa mientras que, al mismo tiempo, se llevan a cabo pruebas para detectar errores asociados con la interacción. El objetivo es coger los módulos probados mediante la prueba de unidad y construir una estructura de programa que esté de acuerdo con lo que dicta el diseño.

A menudo hay una tendencia a intentar una integración no incremental; es decir, a construir el programa mediante un enfoque de big bang. Se combinan todos los módulos por anticipado. Se prueba todo el programa en conjunto. ¡Normalmente se llega al caos! Se encuentran un gran conjunto de errores. La corrección se hace difícil, puesto que es complicado aislar las causas al tener delante el programa entero en toda su extensión.

La integración incremental es la antítesis del enfoque del «big bang». El programa se construye y se prueba en pequeños segmentos en los que los errores son más fáciles de aislar y de corregir, es más probable que se puedan probar completamente las interfaces y se puede aplicar un enfoque de prueba sistemática. En las siguientes secciones se tratan varias estrategias de integración incremental diferentes.

• Pruebas integrales descendentes

Se integran los módulos moviéndose hacia abajo por la jerarquía de control, comenzando por el módulo de control principal (programa principal). Los módulos subordinados (subordinados de cualquier modo) al módulo de control principal se van incorporando en la estructura, bien de forma primero-en-profundidad, o bien de forma primero-en-anchura.

• Pruebas integrales ascendentes

La prueba de la integración ascendente, como su nombre indica, empieza la construcción y la prueba con los módulos atómicos (es decir, módulos de los niveles más bajos de la estructura del programa). Dado que los módulos se integran de abajo hacia arriba, el proceso requerido de los módulos subordinados siempre está disponible y se elimina la necesidad de resguardos.

PRUEBA DE ESTRÉS (RESISTENCIA)

Durante los pasos de prueba anteriores, las técnicas de caja blanca y de caja negra daban como resultado la evaluación del funcionamiento y rendimiento normales del programa. Las pruebas de resistencia están diseñadas para enfrentar a los programas con situaciones anormales.

La prueba de resistencia ejecuta un sistema de forma que demande recursos en cantidad, frecuencia o volúmenes anormales. Por ejemplo: (1) diseñar pruebas especiales que generen diez interrupciones por segundo, cuando las normales son una o dos; (2) incrementar las frecuencias de datos de entrada en un orden de magnitud con el fin de comprobar cómo responden las funciones de entrada; ( 3 ) ejecutar casos de prueba que requieran el máximo de memoria o de otros recursos; (4) diseñar casos de prueba que puedan dar problemas en un sistema operativo virtual o (5) diseñar casos de prueba que produzcan excesivas búsquedas de datos residentes en disco. Esencialmente, el responsable de la prueba intenta romper el programa.

TEST UNITARIO

La prueba de unidad centra el proceso de verificación en la menor unidad del diseño del software: el componente software o módulo.

Page 24: Laboratorio de Informatica 2

24

Consideraciones sobre la prueba de unidad:

Se prueba la interfaz del módulo para asegurar que la información fluye de forma adecuada hacia y desde la unidad de programa que está siendo probada.

Se examinan las estructuras de datos locales para asegurar que los datos que se mantienen temporalmente conservan su integridad durante todos los pasos de ejecución del algoritmo.

Se prueban las condiciones límite para asegurar que el módulo funciona correctamente en los límites establecidos como restricciones de procesamiento.

Se ejercitan todos los caminos independientes (caminos básicos) de la estructura de control con el fin de asegurar que todas las sentencias del módulo se ejecutan por lo menos una vez. Y, finalmente, se prueban todos los caminos de manejo de errores.

Además de las estructuras de datos locales, durante la prueba de unidad se debe comprobar (en la medida de lo posible) el impacto de los datos globales sobre el módulo.

Las pruebas del camino básico y de bucles son técnicas muy efectivas para descubrir una gran cantidad de errores en los caminos.

En programación, una prueba unitaria es una forma de probar el correcto funcionamiento de un módulo de código. Esto sirve para asegurar que cada uno de los módulos funcione correctamente por separado. Luego, con las Pruebas de Integración, se podrá asegurar el correcto funcionamiento del sistema o subsistema en cuestión.

La idea es escribir casos de prueba para cada función no trivial o método en el módulo de forma que cada caso sea independiente del resto.

Características:

- Automatizable: no debería requerirse una intervención manual. Esto es especialmente útil para integración continua. - Completas: deben cubrir la mayor cantidad de código. - Repetibles o Reutilizables: no se deben crear pruebas que sólo puedan ser ejecutadas una sola vez. También es útil para

integración continua. - Independientes: la ejecución de una prueba no debe afectar a la ejecución de otra. - Profesionales: las pruebas deben ser consideradas igual que el código, con la misma profesionalidad, documentación, etc.

Ventajas

El objetivo de las pruebas unitarias es aislar cada parte del programa y mostrar que las partes individuales son correctas. Proporcionan un contrato escrito que el trozo de código debe satisfacer. Estas pruebas aisladas proporcionan cinco ventajas básicas:

- Fomentan el cambio: Las pruebas unitarias facilitan que el programador cambie el código para mejorar su estructura (lo que se ha dado en llamar refactorización), puesto que permiten hacer pruebas sobre los cambios y así asegurarse de que los nuevos cambios no han introducido errores.

- Simplifica la integración: Puesto que permiten llegar a la fase de integración con un grado alto de seguridad de que el código está funcionando correctamente. De esta manera se facilitan las pruebas de integración.

- Documenta el código: Las propias pruebas son documentación del código puesto que ahí se puede ver cómo utilizarlo. - Separación de la interfaz y la implementación: Dado que la única interacción entre los casos de prueba y las unidades bajo

prueba son las interfaces de estas últimas, se puede cambiar cualquiera de los dos sin afectar al otro, a veces usando objetos mock (mock object) para simular el comportamiento de objetos complejos.

- Los errores están más acotados y son más fáciles de localizar: dado que tenemos pruebas unitarias que pueden desenmascararlos.

Limitaciones

Es importante darse cuenta de que las pruebas unitarias no descubrirán todos los errores del código. Por definición, sólo prueban las unidades por sí solas. Por lo tanto, no descubrirán errores de integración, problemas de rendimiento y otros problemas que afectan a todo el sistema en su conjunto.

Herramientas

o JUnit: Entorno de pruebas para Java creado por Erich Gamma y Kent Beck. Se encuentra basado en SUnit creado originalmente para realizar pruebas unitarias para el lenguaje Smalltalk.

Page 25: Laboratorio de Informatica 2

25

o TestNG: Creado para suplir algunas deficiencias en JUnit. o JTiger: Basado en anotaciones, como TestNG. o SimpleTest: Entorno de pruebas para aplicaciones realizadas en PHP. o PHPUnit: framework para realizar pruebas unitarias en PHP. o CPPUnit: Versión del framework para lenguajes C/C++. o NUnit: Versión del framework para la plataforma.NET. o FoxUnit: framework OpenSource de pruebas unitarias para Microsoft Visual FoxPro o MOQ : Framework para la creación dinámica de objetos simuladores (mocks).

PRUEBAS DE VALIDACIÓN

La validación puede definirse de muchas formas, pero una simple (aunque vulgar) definición es que la validación se consigue cuando el software funciona de acuerdo con las expectativas razonables del cliente.

Las expectativas razonables están definidas en la Especificación de Requisitos del Software -un documento que describe todos los atributos del software visibles para el usuario. La especificación contiene una sección denominada-. «Criterios de validación ». La información contenida en esa sección forma la base del enfoque a la prueba de validación.

Criterios de validación:

La validación del software se consigue mediante una serie de pruebas de caja negra que demuestran la conformidad con los requisitos. Un plan de prueba traza la clase de pruebas que se han de llevar a cabo, y un procedimiento de prueba define los casos de prueba específicos en un intento por descubrir errores de acuerdo con los requisitos. Tanto el plan como el procedimiento estarán diseñados para asegurar que se satisfacen todos los requisitos funcionales, que se alcanzan todos los requisitos de rendimiento, que la documentación es correcta e inteligible y que se alcanzan otros requisitos (por ejemplo, portabilidad, compatibilidad, recuperación de errores, facilidad de mantenimiento).

Una vez que se procede con cada caso de prueba de validación, puede darse una de las dos condiciones siguientes: (1) las características de funcionamiento o de rendimiento están de acuerdo con las especificaciones y son aceptables; o (2)’se descubre una desviación de las especificaciones y se crea una lista de deficiencias.

Las desviaciones o errores descubiertos en esta fase del proyecto raramente se pueden corregir antes de la terminación planificada. A menudo es necesario negociar con el cliente un método para resolver las deficiencias.

Prueba alfa y beta

La prueba alfa se lleva a cabo, por un cliente, en el lugar de desarrollo. Se usa el software de forma natural con el desarrollador como observador del usuario y registrando los errores y los problemas de uso. Las pruebas alfa se llevan a cabo en un entorno controlado. La prueba beta se lleva a cabo por los usuarios finales del software en los lugares de trabajo de los clientes. A diferencia de la prueba alfa, el desarrollador no está presente normalmente. Así, la prueba beta es una aplicación «en vivo» del software en un entorno que no puede ser controlado por el desarrollador. El cliente registra todos los problemas (reales o imaginarios) que encuentra durante la prueba beta e informa a intervalos regulares al desarrollador. Como resultado de los problemas informados durante la prueba beta, el desarrollador del software lleva a cabo modificaciones y así prepara una versión del producto de software para toda la clase de clientes.

Características:

- Comprobar que se satisfacen los requisitos - Se usan la mismas técnicas, pero con otro objetivo - No hay programas de prueba, sino sólo el código final de la aplicación - Se prueba el programa completo - Uno o varios casos de prueba por cada requisito o caso de uso especificado - Se prueba también rendimiento, capacidad, etc. (y no sólo resultados correctos) - Pruebas alfa (desarrolladores) y beta (usuarios)

PRUEBAS DE VERIFICACIÓN

La verificación se refiere al conjunto de actividades que aseguran que el software implementa correctamente una función específica. La validación se refiere a un conjunto diferente de actividades que aseguran que el software construido se ajusta a los requisitos del cliente.

Page 26: Laboratorio de Informatica 2

26

PRUEBA DE REGRESIÓN

Cada vez que se añade un nuevo módulo como parte de una prueba de integración, el software cambia. Se establecen nuevos caminos de flujo de datos, pueden ocurrir nuevas E/S y se invoca una nueva lógica de control. Estos cambios pueden causar problemas con funciones que antes trabajaban perfectamente. En el contexto de una estrategia de prueba de integración, la prueba de regresión es volver a ejecutar un subconjunto de pruebas que se han llevado a cabo anteriormente para asegurarse de que los cambios no han propagado efectos colaterales no deseados.

• Repetir las pruebas tras cada modificación o Repetir sólo pruebas de verificación

Pruebas de unidades Pruebas de integración

o Conservar y actualizar los programas de prueba o Usar herramientas de ejecución automática de las pruebas

MOCK OBJECT

En la programación orientada a objetos se llaman objetos simulados (pseudoobjetos, mock object, objetos de pega) a los objetos que imitan el comportamiento de objetos reales de una forma controlada. Se usan para probar a otros objetos en pruebas de unidad que esperan mensajes de una clase en particular para sus métodos.

En los test de unidad, los objetos simulados se usan para simular el comportamiento de objetos complejos cuando es imposible o impracticable usar al objeto real en la prueba. De paso resuelve el problema del caso de objetos interdependientes, que para probar el primero debe ser usado un objeto no probado aún, lo que invalida la prueba: los objetos simulados son muy simples de construir y devuelven un resultado determinado y de implementación directa, independientemente de los complejos procesos o interacciones que el objeto real pueda tener.

Los objetos simulados se usan en lugar de objetos reales que tengan algunas de estas características:

o Devuelven resultados no determinísticos (por ejemplo la hora o la temperatura) o Su estado es difícil de crear o reproducir (por ejemplo errores de conexión) o Es lento (por ejemplo el resultado de un cálculo intensivo o una búsqueda en una BBDD) o El objeto todavía no existe o su comportamiento puede cambiar. o Debería incluir atributos o métodos exclusivamente para el testeo.

Los objetos simulados para imitar al objeto real deben imitar su misma interfaz.

Esto es útil cuando quieres probar una clase que usa otras clases. En lugar de emplear las clases reales, utilizamos sus simulaciones. De este modo, nos evitamos las posibles interferencias de su funcionamiento sobre los resultados del test y garantizamos que sólo probamos el código de la clase en cuestión.

Ejemplo: probar un Controller que usa un Component.

Lo que tenemos que hacer son básicamente dos cosas:

- Crear una simulación o Mock del Component - Asociar el Component simulado al Controller