1. INTRODUCCIÓN
Hasta ahora, se ha realizado el análisis del sistema (generando los DFD y el modelo E/R) y el diseño del sistema (generando el diagrama de estructura y el diseño lógico de la base de datos que, generalmente, es el modelo relacional). Además, es necesario definir la interfaz entre el usuario y el ordenador.
2. DISEÑO DE LA INTERFAZ DE USUARIO
2.1. Evolución histórica
La tecnología de interfaz de usuario, al igual que el hardware, ha pasado por una serie de generaciones [TESLER, 1991]. Estas generaciones contienen o parecen contener a las anteriores, y se pueden clasificar cronológicamente como sigue [NIELSEN, 1993]:
Hasta 1945: no existía ningún paradigma de interfaz de usuario, y se hacía acceso directo de forma manual al hardware.
1945–1955: programación en modo batch o por lotes. La primera generación de interfaces no era interactiva, ya que la interacción entre el sistema y el usuario se restringía a un único punto en el tiempo. Todos los mandatos del usuario tenían que ser especificados antes de que el usuario conociera el resultado de cualquiera de ellos. Se recomienda que tales modos batch proporcionen alguna opción al usuario para controlar continuamente el progreso del trabajo batch, de forma que pueda interrumpir o modificar el trabajo. Es muy frustante tener un trabajo grande ejecutándose y que, cuando vaya a finalizar, tenga que descartarse porque se debería haber modificado el último mandato. Actualmente estas interfaces han tenido un renacimiento en los sistemas de acceso por medio del intercambio de mensajes de correo electrónico.
1955–1965: lenguajes de mandatos. También denominadas interfaces en línea. Los sistemas de tiempo compartido se inventaron alrededor de 1960 como un medio para permitir a varios usuarios tener acceso simultáneo interactivo a un único servidor [LEE et al., 19921. Uno de los problemas principales de estos sistemas es la pequeña cantidad de recursos de ordenador disponibles para soportar la interfaz de cualquier usuario, por lo que, a menudo, se utilizan interfaces en línea. Éstas eran básicamente interfaces de una dimensión, en las que el usuario sólo podía interactuar con el ordenador en una línea que servía como línea de mandato. Cuando el usuario pulsaba la tecla de intro (Return o Enter), no se podía modificar la entrada. De forma similar, cuando el ordenador presentaba una salida al usuario, no se podía modificar para reflejar cambios en los datos. Estas interfaces se implementaron originalmente en las máquinas teletipos, aunque las últimas versiones utilizan pantallas tipo tern-únal. Debido a que las interfaces en línea no permitían a los usuarios navegar por la pantalla, la interacción se limitaba a diálogos pregunta-respuesta y a la introducción de mandatos con parámetros. La mayoría de las interfaces de usuario en línea se implementaban en lenguajes de mandatos y, aunque algunos de ellos son muy poderosos y permiten la construcción de secuencias de mandatos muy complicadas, desafortunadamente es normal que se olviden de los errores del usuario, ya que requieren que éste especifique el mandato deseado exactamente en el formato requerido.
1965–1980: pantallas completas con menús estrictamente jerárquicos. El espacio de diseño de la interfaz es de dos dimensiones. Un uso clásico de la pantalla completa es el de los diálogos para rellenar informes, en los que el usuario tiene un número de campos etiquetados que puede editar en la secuencia que desee. Estos diálogos todavía existen en las interfaces modernas en forma de cajas de diálogo, las cuales son más dinámicas que los informes tradicionales, ya que contienen menús desplegables y ayuda para que el usuario rellene el informe. Además de los menús, muchas de las interfaces de pantalla completa utilizan también las teclas de función como una forma de interacción. Estas teclas aceleran la interacción y existen tan pocas que los usuarios, generalmente, se las aprenden de memoria.
1980–1995: ventanas, iconos, menús y ratón. También denominadas interfaces gráficas de usuario. La mayoría de las interfaces actuales de usuario pertenecen a esta categoría, a veces denominada sistemas WIMP (Windows, Icons, Menus and Pointing device). Las interfaces windows añaden casi una tercera dimensión a las dos dimensiones inherentes a cada ventana debido a la posibilidad de superponer ventanas (está claro que superponer ventanas no es verdaderamente una tercera dimensión, ya que no es posible ver el contenido de la ventana que está debajo, por tanto, podríamos decir que tienen “dos dimensiones y media”). El estilo de interacción utilizado en muchas interfaces gráficas de usuario es la manipulación directa [SHNEIDERMAN, 1983], la cual se basa en la representación visual de los objetos del diálogo que tengan interés para el usuario. Esto permite al usuario controlar el diálogo con sólo mover los objetos por la pantalla y manipularlos con el ratón. Sin embargo, las interfaces de manipulación directa pueden resultar más difíciles de utilizar que las tradicionales, debido a que son más dependientes de un control fino sobre el ratón.
1995-Futuro: interfaces no basadas en mandatos. La próxima generación de interfaces ya se está desarrollando [NIELSEN, 1993b]. Es probable que la tendencia de las generaciones previas continúe, y que la dimensión de las interfaces de usuario aumente de 2.5 a 3 o más dimensiones. Las formas comunes de añadir una dimensión a las interfaces de usuario consisten en añadir tiempo (en forma de animación), sonido o voz, así como una verdadera tercera dimensión espacial en forma de sistemas de realidad virtual. Las dos predicciones más fáciles con respecto a la siguiente generación de interfaces de usuario son que incluirán una dimensionalidad más alta con más tipos de medios y que serán altamente portables y personales, a la vez que se utiliza tecnología de comunicaciones para conseguir una gran conectividad. Otro estilo de diálogo para las interfaces de usuario de la próxima generación puede ser el de las interfaces de usuario no basadas en mandatos. Todos los estilos de interfaz hasta ahora han tenido en común, al menos, el concepto de mandato, y se basaban en el principio de un diálogo explícito entre el usuario y el ordenador en el que el usuario ordenaba al ordenador que hiciese ciertas acciones específicas. Por el contrario, muchos esfuerzos actuales de investigación apuntan a sistemas que permitan al usuario centrarse en el dominio en lugar de tener que controlar al ordenador explícitamente. En estos sistemas futuros, el ordenador se encargará de tomar la responsabilidad de la interacción, basando sus acciones en sus observaciones del usuario, utilizando tecnologías como el seguimiento del ojo, reconocimiento de gestos y análisis semi-inteligente de las acciones del usuario.
2.2. Producción de prototipos preliminares y diálogos
El propósito de la interfaz es muy simple: recoger de los usuarios la información del sistema y ponerla a disposición de otros usuarios. La información recogida se llama entrada del sistema y se almacena en la base de datos para ponerla a disposición de los demás usuarios. La información suministrada se llama salida del sistema. Es decir, el diseño de interfaces cubre tanto las entradas como las salidas.
Las entradas y salidas pueden ser interactivas o por lotes. En una interfaz interactiva, el usuario se comunica directamente con el ordenador y la salida se obtiene muy poco tiempo después de la entrada. En el caso de entradas o salidas no interactivas, es decir, por lotes, las transacciones se reúnen en formularios en el punto de recepción y después se introducen en el ordenador al mismo tiempo. Estas transacciones se procesan y un tiempo después se producen las salidas, las cuales se pasan al usuario. Así, el tiempo transcurrido desde la introducción de los datos hasta que se obtiene una respuesta puede ser considerable.
El diseño de interfaz interactivo provoca un diálogo hombre-máquina que permite un intercambio rápido de información entre los ordenadores y sus usuarios humanos, mientras que la interfaz no interactiva utiliza un soporte de papel para contener la información en el que las entradas normalmente se realizan en formularios especialmente diseñados y las salidas se producen en un listado impreso.
Será necesario definir los formatos individuales de las pantallas utilizadas. En el caso de utilizar un paquete estándar, habrá que evaluar la posibilidad de adoptar el tipo de formato del producto. Entre los aspectos a considerar en los formatos de pantalla se destacan: encabezamiento, cuerpo principal, pie, teclas de función, teclas de ayuda y líneas de visualización de los mensajes de ayuda.
También hay que describir, de forma detallada, los diálogos entre pantallas y su encadenamiento. Para ello, es útil representarlas jerárquicamente, de forma que en los niveles superiores se representen los menús, y en los niveles inferiores las pantallas de diálogos, representativas de funciones o procesos concretos del sistema. En esta representación jerárquica nos interesa identificar los menús o diálogos concretos en función de los grupos de usuarios que los utilicen.
Será también necesario determinar los diálogos que se consideran críticos para un funcionamiento correcto del nuevo sistema. Los diálogos críticos se determinan en función de factores como: tipo de proyecto, grado de cambio con respecto al sistema actual, complejidad de los trabajos del sistema. Para ello, es útil tener en cuenta los siguientes criterios: frecuencia de uso de estos diálogos, acceso a gran número de entidades de datos del sistema, gran número de elementos de datos asociados con el diálogo, cambio en el modo habitual de trabajo en el sistema actual, diálogos comunes a diferentes grupos de usuarios, diálogos que contienen opciones complejas de navegación, etc.
Por último, habrá que realizar un prototipo dinámico que permita la simulación (introducción y validación de datos por pantalla) para los diálogos considerados como críticos. Como recomendaciones para realizar este prototipo se tendrá en cuenta: la determinación del punto de entrada a cada pantalla y sus posibilidades de navegación a otras, la especificación de los datos asociados a cada pantalla (longitud, reglas de validación, mensajes de ayuda, etc.), la evaluación de la consistencia del diseño, asegurando que toda la información necesaria para el usuario está contemplada en las pantallas, y la confirmación con el usuario de la validez de los diseños de pantalla realizados.
2.3. Ergonomía del diseño de la intefaz
El viaje al mundo del diseño de pantallas comienza con una discusión con el usuario, la parte más importante de cualquier sistema informatizado. Como hemos comentado, es de aceptación general que el sistema sería más fácil de utilizar si lo hubiera diseñado el usuario, por tanto, el diseño de la interfaz debe estimular al usuario haciéndolo cómplice del sistema.
El ser humano es un organismo complejo con una variedad de atributos que tienen una influencia importante en el diseño de pantallas [GALITZ, 1989]. Entre estos atributos, destacamos la percepción, la memoria, el aprendizaje, la capacidad y diferencias individuales. Por tanto, debe cultivarse la satisfacción personal y, consecuentemente, mejorar la aceptación del sistema, permitiendo que las personas mejoren sus conocimientos mientras utilizan el sistema.
Para realizar un buen trabajo, la interfaz con el ordenador debe ser, entre otras cosas, lo más fácil, amigable y agradable posible, y se debe usar un diálogo que se acerque al lenguaje natural en vez de la jerga informática. Entre las consideraciones a tener cuenta a la hora de diseñar pantallas se encuentran las siguientes:
Características deseadas: simplicidad, claridad y fácil de comprender. Será necesario tener claridad visual, de forma que los elementos estén agrupados de forma comprensible y con significado en vez de al azar y de forma confusa.
Saber dónde situar la información en la pantalla. Será necesario indicar un punto de partida obvio en la esquina superior izquierda de la pantalla, reservar áreas específicas de pantalla para diferentes tipos de información (como, por ejemplo, mandatos, mensajes de error, títulos y campos de datos, de forma que esta consistencia se mantenga en todas las pantallas) y proporcionar una composición que guste visualmente (es decir, que esté balanceada, sea simétrica, sea predecible, secuencial, simple, con agrupamientos, etc.).
Saber qué información situar en la pantalla. Para ello, hay que poner sólo la información que es esencial para la toma de una decisión o para la ejecución de una acción (¡No inundar al usuario con información!) y poner todos los datos relacionados con una tarea en una única pantalla (así el usuario no tiene que recordar datos de una pantalla a otra).
Saber cómo situar la información en la pantalla. Así, en cuanto a las fuentes de letras, se recomienda utilizar minúsculas para el texto con la letra inicial de la frase en mayúsculas; para las etiquetas, encabezamientos o subtítulos utilizar mayúsculas. En cuanto a las palabras, se recomienda no usar jerga, sino utilizar palabras cortas, familiares, etc. También es necesario saber como alinear y/o resaltar el texto y las palabras, dónde situar las ilustraciones, los campos de datos, etc.
La interfaz de entrada debe recoger todos los datos necesarios, sin introducir errores, para el sistema. De esta forma, la interfaz contiene una protección contra errores de entrada. Así mismo, también debe recoger los datos minimizando el número de teclas pulsadas por el usuario. Las entradas deben estar bien estructuradas y ser fáciles de comprender y utilizar. Se deben usar nombres precisos y permitir abreviaturas cuando se necesiten introducciones rápidas de datos. Se deben evitar las entradas repetitivas. Igualmente, el diseño de la salida asegura que se extraen todos los datos suministrados por el sistema y que esas salidas están estructuradas de forma que sean fáciles de leer.
El color añade una nueva dimensión a la facilidad de uso de la pantalla, ya que atrae la atención del usuario. Si se utiliza de forma adecuada, puede resaltar la organización lógica de una pantalla, facilitar la separación de componentes y acentuar las diferencias. Por el contrario, si se usa inadecuadamente, puede distraer y fatigar la visión debilitando la facilidad de uso del sistema. Por ejemplo, en las pantallas gráficas se recomienda no utilizar más de seis colores a la vez, evitar colores extremos (rojo y azul, amarillo y púrpura), evitar colores que no tengan contraste (blanco y amarillo, rojos, azules).
Para finalizar, diremos que el diseño de pantallas es un proceso ordenado que empieza en los requisitos y finaliza con la implementación.
3. PRUEBAS DEL SOFTWARE
Una de las características típicas del desarrollo de software basado en el ciclo de vida es la realización de controles periódicos, normalmente coincidiendo con los hitos del proyectos o la terminación de documentos. Estos controles pretenden una evaluación de la calidad de los productos generados (especificación de requisitos, documentos de diseño, etc.) para poder detectar posibles defectos cuanto antes. Sin embargo, todo sistema o aplicación, independientemente de estas revisiones, debe ser probado mediante su ejecución controlada antes de ser entregado al cliente. Estas ejecuciones o ensayos de funcionamiento, posteriores a la terminación del código del software, se denominan habitualmente pruebas.
Las pruebas constituyen un método más para poder verificar y validar el software. Se puede definir la verificación como [IEEE, 1990] “el proceso de evaluación de un sistema o de uno de sus componentes para determinar si los productos de una fase dada satisfacen las condiciones impuestas al comienzo de dicha fase”. Por ejemplo, verificar el código de un módulo significa comprobar si cumple lo marcado en la especificación de diseño donde se describe. Por otra parte, la validación es “el proceso de evaluación de un sistema o de uno de sus componentes durante o al final del proceso de desarrollo para determinar si satisface los requisitos especificados”. Así, validar una aplicación implica comprobar si satisface los requisitos marcados por el usuario. Podemos recurrir a la clásica explicación informal de Boehm de estos conceptos:
Verificación: ¿estamos construyendo correctamente el producto?
Validación: ¿estamos construyendo el producto correcto?
Como hemos dicho, las pruebas permiten verificar y validar el software cuando ya está en forma de código ejecutable. A continuación, expondremos algunas definiciones de conceptos relacionados con las pruebas.
3.1. Definiciones
Las siguientes definiciones son algunas de las recogidas en el diccionario IEEE en relación a las pruebas [IEEE, 1990], que complementamos con otras más informales:
Pruebas (test): “una actividad en la cual un sistema o uno de sus componentes se ejecuta 2 en circunstancias previamente especificadas, los resultados se observan y registran y se realiza una evaluación de algún aspecto”. Para Myers [MYERS, 1979], probar (o la prueba) es el “proceso de ejecutar un programa con el fin de encontrar errores”. El nombre “prueba”, además de la actividad de probar, se puede utilizar para designar “un conjunto de casos y procedimientos de prueba” [IEEE, 1990].
Caso de prueba (test case): “un conjunto de entradas, condiciones de ejecución y resultados esperados desarrollados para un objetivo particular como, por ejemplo, ejercitar un camino concreto de un programa o verificar el cumplimiento de un determinado requisito”. También se puede referir a la documentación en la que se describen las entradas, condiciones y salidas de un caso de prueba.
Defecto (defect, fault, “bug”): “un defecto en el software como, por ejemplo, un proceso, una definición de datos o un paso de procesamiento incorrectos en un programa”.
Fallo (failure): «La incapacidad de un sistema o de alguno de sus componentes para realizar las funciones requeridas dentro de los requisitos de rendimiento especificados».
Error (error): tiene varias acepciones:
La diferencia entre un valor calculado, observado o medido y el valor verdadero, especificado o teóricamente correcto. Por ejemplo, una diferencia de dos centímetros entre el valor calculado y el real.
Un defecto. Por ejemplo, una instrucción incorrecta en un programa.
Un resultado incorrecto. Por ejemplo, un programa ofrece como resultado de la raíz cuadrada de 36 el valor 7 en vez de 6.
Una acción humana que conduce a un resultado incorrecto (una metedura de pata). Por ejemplo, que el operador o el programador pulse una tecla equivocada.
Nosotros desecharemos las acepciones 2 y 3, ya que coinciden con las definiciones de defecto y fallo, para evitar equívocos. La relación entre error, fallo y defecto queda más clara en la Figura 12–1.
Figura 1. Relación entre error, defecto y fallo.
3.2. El proceso de prueba
El proceso de prueba comienza con la generación de un plan de pruebas en base a la documentación sobre el proyecto y la documentación sobre el software a probar. A partir de dicho plan, se entra en detalle diseñando pruebas específicas basándose en la documentación del software a probar. Una vez detalladas las pruebas (especificaciones de casos y de procedimientos), se toma la configuración del software (revisada, para confirmar que se trata de la versión apropiada del programa) que se va a probar para ejecutar sobre ella los casos. En algunas situaciones, se puede tratar de reejecuciones de pruebas, por lo que es conveniente tener constancia de los defectos ya detectados aunque aún no corregidos. A partir de los resultados de salida, se pasa a su evaluación mediante comparación con la salida esperada. A partir de ésta, se pueden realizar dos actividades:
La depuración (localización y corrección de defectos).
El análisis de la estadística de errores.
La depuración puede corregir o no los defectos. Si no consigue localizarlos, puede ser necesario realizar pruebas adicionales para obtener más información. Si se corrige un defecto, se debe volver a probar el software para comprobar que el problema está resuelto.
Por su parte, el análisis de errores puede servir para realizar predicciones de la fiabilidad del software y para detectar las causas más habituales de error y mejorar los procesos de desarrollo.
3.3. Técnicas de diseño de casos de prueba
El diseño de casos de prueba está totalmente mediatizado por la imposibilidad de probar exhaustivamente el software. Pensemos en un programa muy sencillo que sólo suma dos números enteros de dos cifras (del 0 al 99). Si quisiéramos probar, simplemente, todos los valores válidos que se pueden sumar, deberíamos probar 10.000 combinaciones distintas de cien posibles números del primer sumando y cien del segundo. Pensemos que aún quedarían por probar todas las posibilidades de error al introducir los datos (por ejemplo, teclear una letra en vez de un número). La conclusión es que, si para un programa tan elemental debemos realizar tantas pruebas, pensemos en lo que supondría un programa medio.
En consecuencia, las técnicas de diseño de casos de prueba tienen como objetivo conseguir una confianza aceptable en que se detectarán los defectos existentes (ya que la seguridad total sólo puede obtenerse de la prueba exhaustiva, que no es practicable) sin necesidad de consumir una cantidad excesiva de recursos (por ejemplo, tiempo para probar o tiempo de ejecución). Toda la disciplina de pruebas debe moverse, por lo tanto, en un equilibrio entre la disponibilidad de recursos y la confianza que aportan los casos para descubrir los defectos existentes. Este equilibrio no es sencillo, lo que convierte a las pruebas en una disciplina difícil que está lejos de parecerse a la imagen de actividad rutinaria que suele sugerir.
Ya que no se pueden probar todas las posibilidades de funcionamiento del software, la idea fundamental para el diseño de casos de prueba consiste en elegir algunas de ellas que, por sus características, se consideren representativas del resto. Así, se asume que, si no se detectan defectos en el software al ejecutar dichos casos, podemos tener un cierto nivel de confianza (que depende de la elección de los casos) en que el programa no tiene defectos. La dificultad de esta idea es saber elegir los casos que se deben ejecutar. De hecho, una elección puramente aleatoria no proporciona demasiada confianza en que se puedan detectar todos los defectos existentes. Por ejemplo, en el caso del programa de suma de dos números, elegir cuatro pares de sumandos al azar no aporta mucha seguridad a la prueba (una probabilidad de 4/10.000 de cobertura de posibilidades). Por eso es necesario recurrir a ciertos criterios de elección que veremos a continuación.
Existen tres enfoques principales para el diseño de casos:
El enfoque estructural o de caja blanca (véase la figura 2). Consiste en centrarse en la estructura interna (implementación) del programa para elegir los casos de prueba. En este caso, la prueba ideal (exhaustiva) del software consistiría en probar todos los posibles caminos de ejecución, a través de las instrucciones del código, que puedan trazarse.
El enfoque funcional o de caja negra (véase la figura 2). Consiste en estudiar la especificación de las funciones, la entrada y la salida para derivar los casos. Aquí, la prueba ideal del software consistiría en probar todas las posibles entradas y salidas del programa.
El enfoque aleatorio consiste en utilizar modelos (en muchas ocasiones estadísticos) que representen las posibles entradas al programa para crear a partir de ellos los casos de prueba. La prueba exhaustiva consistiría en probar todas las posibles entradas al programa.
Estos enfoques no son excluyentes entre sí, ya que se pueden combinar para conseguir una detección de defectos más eficaz. Veremos a continuación una presentación de cada uno de ellos.
Figura 2. Los enfoques de diseño de pruebas de caja blanca y de caja negra.
3.4. Pruebas estructurales. (Prueba de la caja blanca)
Como hemos dicho, las pruebas exhaustivas son impracticables. Podemos recurrir al clásico ejemplo de Myers [MYERS, 1979] de un programa de 50 líneas con 25 sentencias IF en serie, en el que el número total de caminos contiene 33,5 millones de secuencias potenciales (contando dos posibles salidas para cada IF tenemos 225 posibles caminos). El diseño de casos tiene que basarse en la elección de caminos importantes que ofrezcan una seguridad aceptable en descubrir defecto, y para ello se utilizan los llamados criterios de cobertura lógica. Antes de pasar a examinarlos, conviene señalar que estas técnicas no requieren el uso de ninguna representación gráfica específica del software, aunque es habitual tomar como base los llamados diagramas de flujo de control (flowgraph charts o flowcharts). Como ejemplo de diagrama de flujo junto al código correspondiente, véase la Figura 3.
En el recuadro adjunto pueden consultarse algunas recomendaciones para dibujar los grafos de flujo de los programas para poder generar los casos de prueba correspondientes. También existen herramientas que dibujan el grafo de flujo de un programa sólo con facilitar el código fuente del mismo como entrada.
espero y les haya servido saludos para EL INSTITUTO TECNOLOGICO SUPERIOR DE LOS REYES