Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Etimología
Definición de software
El término «software» fue usado por primera vez en este sentido por John W. Tukey
en 1957. En la ingeniería de software y las ciencias de la computación, el software es
toda la información procesada por los sistemas informáticos: programas y datos.
o Sistemas operativos
o Controladores de dispositivos
o Herramientas de diagnóstico
o Servidores
o Utilidades
o Editores de texto
o Compiladores
o Intérpretes
o Enlazadores
o Depuradores
o Aplicaciones ofimáticas
o Software educativo
o Software empresarial
o Bases de datos
o Videojuegos
o Software médico
Se estima que, del total de proyectos software grandes emprendidos, un 28% fracasan,
un 46% caen en severas modificaciones que lo retrasan y un 26% son totalmente
exitosos. 7
Cuando un proyecto fracasa, rara vez es debido a fallas técnicas, la principal causa de
fallos y fracasos es la falta de aplicación de una buena metodología o proceso de
desarrollo. Entre otras, una fuerte tendencia, desde hace pocas décadas, es mejorar las
metodologías o procesos de desarrollo, o crear nuevas y concientizar a los
profesionales de la informática a su utilización adecuada. Normalmente los
especialistas en el estudio y desarrollo de estas áreas (metodologías) y afines (tales
como modelos y hasta la gestión misma de los proyectos) son los ingenieros en
software, es su orientación. Los especialistas en cualquier otra área de desarrollo
informático (analista, programador, Lic. en informática, ingeniero en informática,
ingeniero de sistemas, etc.) normalmente aplican sus conocimientos especializados
pero utilizando modelos, paradigmas y procesos ya elaborados.
Es común para el desarrollo de software de mediano porte que los equipos humanos
involucrados apliquen «metodologías propias», normalmente un híbrido de los
procesos anteriores y a veces con criterios propios.
Diseño
Codificación
Mantenimiento
En las anteriores etapas pueden variar ligeramente sus nombres, o ser más globales, o
contrariamente, ser más refinadas; por ejemplo indicar como una única fase (a los
fines documentales e interpretativos) de «análisis y diseño»; o indicar como
«implementación» lo que está dicho como «codificación»; pero en rigor, todas existen
e incluyen, básicamente, las mismas tareas específicas.
En el apartado 4 del presente artículo se brindan mayores detalles de cada una de las
etapas indicadas.
Para cada una de las fases o etapas listadas en el ítem anterior, existen sub-etapas (o
tareas). El modelo de proceso o modelo de ciclo de vida utilizado para el desarrollo
define el orden para las tareas o actividades involucradas6 también definen la
coordinación entre ellas, y su enlace y realimentación. Entre los más modelos
conocidos se puede mencionar: modelo en cascada o secuencial, modelo espiral,
modelo iterativo incremental. De los antedichos hay a su vez algunas variantes o
alternativas, más o menos atractivas según sea la aplicación requerida y sus
requisitos.7
Modelo cascada
El modelo en cascada puro difícilmente se utiliza tal cual, pues esto implicaría un
previo y absoluto conocimiento de los requisitos, la no volatilidad de los mismos (o
rigidez) y etapas subsiguientes libres de errores; ello sólo podría ser aplicable a
escasos y pequeños sistemas a desarrollar. En estas circunstancias, el paso de una
etapa a otra de las mencionadas sería sin retorno, por ejemplo pasar del diseño a la
codificación implicaría un diseño exacto y sin errores ni probable modificación o
evolución: «codifique lo diseñado sin errores, no habrá en absoluto variantes futuras».
Esto es utópico; ya que intrínsecamente el software es de carácter evolutivo9 ,
cambiante y difícilmente libre de errores, tanto durante su desarrollo como durante su
vida operativa.6
Fig. 2 - Modelo cascada puro o secuencial para el ciclo de vida del software.
Algún cambio durante la ejecución de una cualquiera de las etapas en este modelo
secuencial implicaría reiniciar desde el principio todo el ciclo completo, lo cual
redundaría en altos costos de tiempo y desarrollo. La figura 2 muestra un posible
esquema del modelo en cuestión.6
Sin embargo, el modelo cascada en algunas de sus variantes es uno de los actualmente
más utilizados10 , por su eficacia y simplicidad, más que nada en software de pequeño
y algunos de mediano porte; pero nunca (o muy rara vez) se lo usa en su "forma
pura", como se dijo anteriormente. En lugar de ello, siempre se produce alguna
realimentación entre etapas, que no es completamente predecible ni rígida; esto da
oportunidad al desarrollo de productos software en los cuales hay ciertas incertezas,
cambios o evoluciones durante el ciclo de vida. Así por ejemplo, una vez capturados y
especificados los requisitos (primera etapa) se puede pasar al diseño del sistema, pero
durante esta última fase lo más probable es que se deban realizar ajustes en los
requisitos (aunque sean mínimos), ya sea por fallas detectadas, ambigüedades o bien
por que los propios requisitos han cambiado o evolucionado; con lo cual se debe
retornar a la primera o previa etapa, hacer los reajuste pertinentes y luego continuar
nuevamente con el diseño; esto último se conoce como realimentación. Lo normal en
el modelo cascada será entonces la aplicación del mismo con sus etapas
realimentadas de alguna forma, permitiendo retroceder de una a la anterior (e incluso
poder saltar a varias anteriores) si es requerido.
Lo dicho es, a grandes rasgos, la forma y utilización de este modelo, uno de los más
usados y populares.6 El modelo cascada realimentado resulta muy atractivo, hasta
ideal, si el proyecto presenta alta rigidez (pocos cambios, previsto no evolutivo), los
requisitos son muy claros y están correctamente especificados.10
Hay más variantes similares al modelo: refino de etapas (más etapas, menores y más
específicas) o incluso mostrar menos etapas de las indicadas, aunque en tal caso la
faltante estará dentro de alguna otra. El orden de esas fases indicadas en el ítem
previo es el lógico y adecuado, pero adviértase, como se dijo, que normalmente habrá
realimentación hacia atrás.
Modelos evolutivos
El software evoluciona con el tiempo.11 9 Los requisitos del usuario y del producto
suelen cambiar conforme se desarrolla el mismo. Las fechas de mercado y la
competencia hacen que no sea posible esperar a poner en el mercado un producto
absolutamente completo, por lo que se aconsejable introducir una versión funcional
limitada de alguna forma para aliviar las presiones competitivas.
Los modelos «iterativo incremental» y «espiral» (entre otros) son dos de los más
conocidos y utilizados del tipo evolutivo.10
Se observa que existen actividades de desarrollo (para cada incremento) que son
realizadas en paralelo o concurrentemente, así por ejemplo, en la figura, mientras se
realiza el diseño detalle del primer incremento ya se está realizando en análisis del
segundo. La figura 5 es sólo esquemática, un incremento no necesariamente se
iniciará durante la fase de diseño del anterior, puede ser posterior (incluso antes), en
cualquier tiempo de la etapa previa. Cada incremento concluye con la actividad de
«operación y mantenimiento» (indicada como «Operación» en la figura), que es
donde se produce la entrega del producto parcial al cliente. El momento de inicio de
cada incremento es dependiente de varios factores: tipo de sistema; independencia o
dependencia entre incrementos (dos de ellos totalmente independientes pueden ser
fácilmente iniciados al mismo tiempo si se dispone de personal suficiente); capacidad
y cantidad de profesionales involucrados en el desarrollo; etc.
Bajo este modelo se entrega software «por partes funcionales más pequeñas», pero
reutilizables, llamadas incrementos. En general cada incremento se construye sobre
aquel que ya fue entregado.6
Ejemplo:
Como se dijo, el Iterativo Incremental es un modelo del tipo evolutivo, es decir donde
se permiten y esperan probables cambios en los requisitos en tiempo de desarrollo; se
admite cierto margen para que el software pueda evolucionar9 . Aplicable cuando los
requisitos son medianamente bien conocidos pero no son completamente estáticos y
definidos, cuestión esa que si es indispensable para poder utilizar un modelo Cascada.
Este modelo brinda cierta flexibilidad para que durante el desarrollo se incluyan
cambios en los requisitos por parte del usuario, un cambio de requisitos propuesto y
aprobado puede analizarse e implementarse como un nuevo incremento o,
eventualmente, podrá constituir una mejora/adecuación de uno ya planeado. Aunque
si se produce un cambio de requisitos por parte del cliente que afecte incrementos
previos ya terminados (detección/incorporación tardía) se debe evaluar la factibilidad
y realizar un acuerdo con el cliente, ya que puede impactar fuertemente en los costos.
La selección de este modelo permite realizar entregas funcionales tempranas al
cliente (lo cual es beneficioso tanto para él como para el grupo de desarrollo). Se
priorizan las entregas de aquellos módulos o incrementos en que surja la necesidad
operativa de hacerlo, por ejemplo para cargas previas de información, indispensable
para los incrementos siguientes.10
Modelo espiral
Región 3 - Tareas necesarias para evaluar los riesgos técnicos y de gestión del
proyecto.
Al inicio del ciclo, o proceso evolutivo, el equipo de ingeniería gira alrededor del
espiral (metafóricamente hablando) comenzando por el centro (marcado con ๑ en la
figura 6) y en el sentido indicado; el primer circuito de la espiral puede producir el
desarrollo de una especificación del producto; los pasos siguientes podrían generar un
prototipo y progresivamente versiones más sofisticadas del software.
Cada paso por la región de planificación provoca ajustes en el plan del proyecto; el
coste y planificación se realimentan en función de la evaluación del cliente. El gestor
de proyectos debe ajustar el número de iteraciones requeridas para completar el
desarrollo.
Una visión alternativa del modelo puede observarse examinando el «eje de punto de
entrada de proyectos». Cada uno de los circulitos (๏) fijados a lo largo del eje
representan puntos de arranque de los distintos proyectos (relacionados); a saber:
Cuando la espiral se caracteriza de esta forma, está operativa hasta que el software
se retira, eventualmente puede estar inactiva (el proceso), pero cuando se produce un
cambio el proceso arranca nuevamente en el punto de entrada apropiado (por ejemplo,
en «mejora del producto»).
El Espiral utiliza el MCP para reducir riesgos y permite aplicarlo en cualquier etapa
de la evolución. Mantiene el enfoque clásico (cascada) pero incorpora un marco de
trabajo iterativo que refleja mejor la realidad.
Este modelo requiere considerar riesgos técnicos en todas las etapas del proyecto;
aplicado adecuadamente debe reducirlos antes de que sean un verdadero problema.
Desventajas importantes:
Es difícil convencer a los grandes clientes que se podrá controlar este enfoque
evolutivo.
Este modelo no se ha usado tanto, como el Cascada (Incremental) o MCP, por lo que
no se tiene bien medida su eficacia, es un paradigma relativamente nuevo y difícil de
implementar y controlar.
Depuracion de programas
1. Introducción
Una de las últimas fases del ciclo de vida antes de entregar un programa para su
explotación, es la fase de pruebas.
Una de las sorpresas con las que suelen encontrar los nuevos programadores es la
enorme cantidad de tiempo y esfuerzo que requiere esta fase. Se estima que la mitad
del esfuerzo de desarrollo de un programa (tanto en tiempo como en gastos) se va en
esta fase. Si hablamos de programas que involucran vidas humanas (medicina,
equipos nucleares, etc) el costo de la fase de pruebas puede fácilmente superar el
80%.
1.2. Organización
Fases de prueba:
UNIDADES
Planteamientos:
o CAJA BLANCA
Cobertura:
de segmentos
de ramas
de condición/decisión
de bucles
o CAJA NEGRA
Cobertura de requisitos
INTEGRACIÓN
ACEPTACIÓN
La prueba de unidades se plantea a pequeña escala, y consiste en ir probando uno a
uno los diferentes módulos que constituyen una aplicación.
Las pruebas de integración y de aceptación son pruebas a mayor escala, que puede
llegar a dimensiones industriales cuando el número de módulos es muy elevado, o la
funcionalidad que se espera del programa es muy compleja.
El planteamiento ascendente evita tener que escribirse módulos ficticios, pues vamos
construyendo pirámides más y más altas con lo que vamos teniendo. Su desventaja es
que se centra más en el desarrollo que en las espectativas finales del cliente.
Estas clasificaciones no son las únicas posibles. Por ejemplo, en sistemas con mucha
interacción con el usuario es frecuente codificar sólo las partes de cada módulo que
hacen falta para una cierta funcionalidad. Una vez probada, se añade otra
funcionalidad y así hasta el final. Esto da lugar a un planteamiento más "vertical" de
las pruebas. A veces se conoce como "codificación incremental".
Por último, las pruebas de aceptación son las que se plantea el cliente final, que
decide qué pruebas va a aplicarle al producto antes de darlo por bueno y pagarlo. De
nuevo, el objetivo del que prueba es encontrar los fallos lo antes posible, en todo caso
antes de pagarlo y antes de poner el programa en producción.
2. Prueba de Unidades
¿Cómo se prueban módulos sueltos?
Normalmente cabe distinguir una fase informal antes de entrar en la fase de pruebas
propiamente dicha. La fase informal la lleva a cabo el propio codificador en su
despacho, y consiste en ir ejecutando el código para convencerse de que
"básicamente, funciona". Esta fase suele consistir en pequeños ejemplos que se
intentan ejecutar. Si el módulo falla, se suele utilizar un depurador para observar la
evolución dinámica del sistema, localizar el fallo, y repararlo.
Más adelante, cuando el módulo parece presentable, se entra en una fase de prueba
sistemática. En esta etapa se empieza a buscar fallos siguiendo algún criterio para que
"no se escape nada". Los criterios más habituales son los denominados de caja negra y
de caja blanca.
Se dice que una prueba es de caja negra cuando prescinde de los detalles del código y
se limita a lo que se ve desde el exterior. Intenta descubrir casos y circunstancias en
los que el módulo no hace lo que se espera de él.
Por oposición al término "caja negra" se suele denominar "caja blanca" al caso
contrario, es decir, cuando lo que se mira con lupa es el código que está ahí escrito y
se intenta que falle. Quizás sea más propio la denominación de "pruebas de caja
transparente".
Sinónimos:
pruebas estructurales
En estas pruebas estamos siempre observando el código, que las pruebas se dedican a
ejecutar con ánimo de "probarlo todo". Esta noción de prueba total se formaliza en lo
que se llama "cobertura" y no es sino una medida porcentual de ¿cuánto código hemos
cubierto?
Cobertura de segmentos
En la práctica, el proceso de pruebas termina antes de llegar al 100%, pues puede ser
excesivamente laborioso y costoso provocar el paso por todas y cada una de las
sentencias.
A la hora de decidir el punto de corte antes de llegar al 100% de cobertura hay que ser
precavido y tomar en consideración algo más que el índice conseguido. En efecto,
ocurre con harta frecuencia que los programas contienen código muerto o
inalcanzable. Puede ser que este trozo del programa, simplemente "sobre" y se pueda
prescindir de él; pero a veces significa que una cierta funcionalidad, necesaria, es
inalcanzable: esto es un error y hay que corregirlo.
Cobertura de ramas
Desde el punto de vista de cobertura de segmentos, basta ejecutar una vez, con éxito
en la condición, para cubrir todas las sentencias posibles. Sin embargo, desde el punto
de vista de la lógica del programa, también debe ser importante el caso de que la
condición falle (si no lo fuera, sobra el IF). Sin embargo, como en la rama ELSE no
hay sentencias, con 0 ejecuciones tenemos el 100%.
Estos criterios se extienden a las construcciones que suponen elegir 1 de entre varias
ramas. Por ejemplo, el CASE.
Nótese que si lograramos una cobertura de ramas del 100%, esto llevaría implícita
una cobertura del 100% de los segmentos, pues todo segmento está en alguna rama.
Esto es cierto salvo en programas triviales que carecen de condiciones (a cambio,
basta 1 sóla prueba para cubrirlo desde todos los puntos de vista). El criterio también
debe refinarse en lenguajes que admiten excepciones (por ejemplo, Ada). En estos
casos, hay que añadir pruebas para provocar la ejecución de todas y cada una de las
excepciones que pueden dispararse.
Cobertura de condición/decisión
Las condiciones 1 y 2 pueden tomar 2 valores cada una, dando lugar a 4 posibles
combinaciones. No obstante sólo hay dos posibles ramas y bastan 2 pruebas para
cubrirlas. Pero con este criterio podemos estar cerrando los ojos a otras
combinaciones de las condiciones.
Bastan las pruebas 2 y 3 para tener cubiertas todas las ramas. Pero con ellos sólo
hemos probado una posibilidad para la Condición1.
Nótese que no basta con cubrir cada una de las condciones componentes, si no que
además hay que cuidar de sus posibles combinaciones de forma que se logre siempre
probar todas y cada una de las ramas. Así, en el ejemplo anterior no basta con ejecutar
las pruebas 1 y 2, pues aun cuando cubrimos perfectamente cada posibilidad de cada
condición por separado, lo que no hemos logrado es recorrer las dos posibles ramas de
la decisión combinada. Para ello es necesario añadir la prueba 3.
El conjunto mínimo de pruebas para cubrir todos los aspectos es el formado por las
pruebas 3 y 4. Aún así, nótese que no hemos probado todo lo posible. Por ejemplo, si
en el programa nos colamos y ponemos AND donde queríamos poner OR (o
viceversa), este conjunto de pruebas no lo detecta. Sólo queremos decir que la
cobertura es un criterio útil y práctico; pero no es prueba exhaustiva.
Cobertura de bucles
Los bucles no son más que segmentos controlados por decisiones. Así, la cobertura de
ramas cubre plenamente la esencia de los bucles. Pero eso es simplemente la teoría,
pues la práctica descubre que los bucles son una fuente inagotable de errores, todos
triviales, algunos mortales. Un bucle se ejecuta un cierto número de veces; pero ese
número de veces debe ser muy preciso, y lo más normal es que ejecutarlo una vez de
menos o una vez de más tenga consecuencias indeseables. Y, sin embargo, es
extremadamente fácil equivocarse y redactar un bucle que se ejecuta 1 vez de más o
de menos.
1. 0 ejecuciones
2. 1 ejecución
3. más de 1 ejecución
1. 1 ejecución
2. más de 1 ejecución
Los bucles FOR, en cambio, son muy seguros, pues en su cabecera está definido el
número de veces que se va a ejecutar. Ni una más, ni una menos, y el compilador se
encarga de garantizarlo. Basta pues con ejecutarlos 1 vez.
También tiene "trampa" si contiene sentencias del tipo EXIT (que algunos lenguajes
denominan BREAK) o del tipo RETURN. Todas ellas provocan terminaciones
anticipadas del bucle.
Estos últimos párrafos hay que precisarlos para cada lenguaje de programación. Lo
peor son aquellos lenguajes que permiten el uso de sentencias GOTO. Tampoco
conviene confiarse de lo que prometen lenguajes como MODULA-2, que se supone
que prohiben ciertas construcciones arriesgadas. Los compiladores reales suelen ser
más tolerantes que lo que anuncian los libros.
Sinónimos:
pruebas funcionales
pruebas de entrada/salida
Las pruebas de caja negra están especialmente indicadas en aquellos módulos que van
a ser interfaz con el usuario (en sentido general: teclado, pantalla, ficheros, canales de
comunicaciones, etc etc) Este comentario no obsta para que sean útiles en cualquier
módulo del sistema.
El problema con las pruebas de caja negra no suele estar en el número de funciones
proporcionadas por el módulo (que siempre es un número muy limitado en diseños
razonables); sino en los datos que se le pasan a estas funciones. El conjunto de datos
posibles suele ser muy amplio (por ejemplo, un entero).
El problema está pues en identificar clases de equivalencia, tarea para la que no existe
una regla de aplicación universal; pero hay recetas para la mayor parte de los casos
prácticos:
los mismos criterios se aplican a las salidas esperadas: hay que intentar generar
resultados en todas y cada una de las clases.
Ejemplo: utilizamos un entero para identificar el día del mes. Los valores posibles
están en el rango [1..31]. Así, hay 3 clases:
2. números entre 1 y 31
Durante la lectura de los requisitos del sistema, nos encontraremos con una serie de
valores singulares, que marcan diferencias de comportamiento. Estos valores son
claros candidatos a marcar clases de equivalencia: por abajo y por arriba.
La experiencia muestra que un buen número de errores aparecen en torno a los puntos
de cambio de clase de equivalencia. Hay una serie de valores denominados "frontera"
(o valores límite) que conviene probar, además de los elegidos en el párrafo anterior.
Usualmente se necesitan 2 valores por frontera, uno justo abajo y otro justo encima.
3. Pruebas de Integración
Las pruebas estructurales de integración son similares a las pruebas de caja blanca;
pero trabajan a un nivel conceptual superior. En lugar de referirnos a sentencias del
lenguaje, nos referiremos a llamadas entre módulos. Se trata pues de identificar todos
los posibles esquemas de llamadas y ejercitarlos para lograr una buena cobertura de
segmentos o de ramas.
Las pruebas funcionales de integración son similares a las pruebas de caja negra. Aquí
trataremos de encontrar fallos en la respuesta de un módulo cuando su operación
depende de los servicios prestados por otro(s) módulo(s). Según nos vamos acercando
al sistema total, estas pruebas se van basando más y más en la especificación de
requisitos del usuario.
4. Pruebas de Aceptación
Estas pruebas las realiza el cliente. Son básicamente pruebas funcionales, sobre el
sistema completo, y buscan una cobertura de la especificación de requisitos y del
manual del usuario. Estas pruebas no se realizan durante el desarrollo, pues sería
impresentable de cara al cliente; sino una vez pasada todas las pruebas de integración
por parte del desarrollador.
La experiencia muestra que aún después del más cuidadoso proceso de pruebas por
parte del desarrollador, quedan una serie de errores que sólo aparecen cuando el
cliente se pone a usarlo. Los desarrolladores se suelen llevar las manos a la cabeza:
Sea como sea, el cliente siempre tiene razón. Decir que los requisitos no estaban
claros, o que el manual es ambiguo puede salvar la cara; pero ciertamente no deja
satisfecho al cliente. Alegar que el cliente es un inútil es otra tentación muy fuerte,
que conviene reprimir.
Las pruebas beta vienen despues de las pruebas alfa, y se desarrollan en el entorno del
cliente, un entorno que está fuera de control. Aquí el cliente se queda a solas con el
producto y trata de encontrarle fallos (reales o imaginarios) de los que informa al
desarrollador.
Las pruebas alfa y beta son habituales en productos que se van a vender a muchos
clientes. Algunos de los potenciales compradores se prestan a estas pruebas bien por
ir entrenando a su personal con tiempo, bien a cambio de alguna ventaja económica
(mejor precio sobre el producto final, derecho a mantenimiento gratuito, a nuevas
versiones, etc etc). La experiencia muestra que estas prácticas son muy eficaces.
Recorridos (walkthroughs)
Quizás es una técnica más aplicada en control de calidad que en pruebas. Consiste en
sentar alrededor de una mesa a los desarrolladores y a una serie de críticos, bajo las
órdenes de un moderador que impida un recalentamiento de los ánimos. El método
consiste en que los revisores se leen el programa línea a línea y piden explicaciones
de todo lo que no está meridianamente claro. Puede que simplemente falte un
comentario explicativo, o que detecten un error auténtico o que simplemente el código
sea tan complejo de entender/explicar que más vale que se rehaga de forma más
simple. Para un sistema complejo pueden hacer falta muchas sesiones.
Esta técnica es muy eficaz localizando errores de naturaleza local; pero falla
estrepitosamente cuando el error deriva de la interacción entre dos partes alejadas del
programa. Nótese que no se está ejecutando el programa, sólo mirándolo con lupa, y
de esta forma sólo se ve en cada instante un trocito del listado.
Si el programa es poco crítico (una aplicación personal, un juego, ...) puede que esto
sea suficiente. Pero si se trata de una aplicación militar o con riesgo para vidas
humanas, es de todo punto insuficiente.
Por ejemplo, en un sistema que admite una serie de órdenes (commands) se deben
probar los siguientes extremos:
En ciertos sistemas es conveniente saber hasta dónde aguantan, bien por razones
internas (¿hasta cuantos datos podrá procesar?), bien externas (¿es capaz de trabajar
con un disco al 90%?, ¿aguanta una carga de la CPU del 90?, etc etc)
Las pruebas, de caja negra, que se le pasan a un producto para detectar discrepancias
respecto a una norma de las descritas en el párrafo anterior se denominan de
conformidad u homologación. Suelen realizarse en un centro especialmente
acreditado al efecto y, si se pasan satisfactoriamente, el producto recibe un sello
oficial que dice: "homologado".
Todos los sistemas sufren una evolución a lo largo de su vida activa. En cada nueva
versión se supone que o bien se corrigen defectos, o se añaden nuevas funciones, o
ambas cosas. En cualquier caso, una nueva versión exige una nueva pasada por las
pruebas. Si éstas se han sistematizado en una fase anterior, ahora pueden volver a
pasarse automáticamente, simplemente para comprobar que las modificaciones no
provocan errores donde antes no los había.
El mínimo necesario para usar unas pruebas en una futura revisión del programa es
una documentación muy muy clara.
Las pruebas de regresión son particularmente espectaculares cuando se trata de probar
la interacción con un agente externo. Existen empresas que viven de comercializar
productos que "graban" la ejecución de una prueba con operadores humanos para
luego repetirla cuantas veces haga falta "reproduciendo la grabación". Y, obviamente,
deben monitorizar la respuesta del sistema en ambos casos, compararla, y avisar de
cualquier discrepancia significativa.
6. Depuración (debugging)
En general es mala idea "correr al depurador", tanto por el tiempo que se pierde
buceando sin una meta clara, como por el riesgo de corregir defectos intermedios sin
llegar a la raiz del problema. Antes de entrar en el depurador hay que delimitar el
error y sus posibles causas. Ante una prueba que falla, hay que identificar el dominio
del fallo, averiguar las características de los datos que provoca el fallo (y comprobar
experimentalmente que todos los datos con esas características provocan ese fallo, y
los que no las tienen no lo provocan).
Un plan de pruebas está constituido por un conjunto de pruebas. Cada prueba debe
Estas mismas ideas se suelen agrupar diciendo que un caso de prueba consta de 3
bloques de información:
1. El propósito de la prueba
Y todos y cada uno de esos puntos debe quedar perfectamente documentado. Las
pruebas de usar y tirar más vale que se tiren directamente, aún antes de usarlas.
Cubrir estos puntos es muy laborioso y, con frecuencia, tedioso, lo que hace
desagradable (o al menos muy aburrida) la fase de pruebas. Es mucho mas divertido
codificar que probar. Tremendo error en el que, no obstante, es fácil incurrir.
1. Pasar pruebas de caja negra analizando valores límite. Recuerde que hay que
analizar condiciones límite de entrada y de salida.
4. Medir la cobertura de caja blanca que se ha logrado con las fases previas y
añadir más pruebas de caja blanca hasta lograr la cobertura deseada.
Normalmente se busca una buena cobertura de ramas (revise los comentarios
expuestos al hablar de caja blanca).
Consiste en describir por escrito a nivel técnico los procedimientos relacionados con
el programa y su modo de uso.
Tipos de documentación
La guía técnica
La guía de uso
Este documento se hace desde la guía técnica pero se suprimen los tecnicismos y se
presenta de forma que sea entendible para el usuario que no sea experto en
informática.
La guía de instalación
Contexto
Tipos de mantenimiento
Perfectivo: son las acciones llevadas a cabo para mejorar la calidad interna de
los sistemas en cualquiera de sus aspectos: reestructuración del código,
definición más clara del sistema y optimización del rendimiento y eficiencia.
Adaptativo: son las modificaciones que afectan a los entornos en los que el
sistema opera, por ejemplo, cambios de configuración del hardware, software
de base, gestores de base de datos, comunicaciones, etc.
Correctivo: son aquellos cambios precisos para corregir errores del producto
software.