dijous, 31 de març del 2016

Optimitzación de programario

Diseño y realización de pruebas de software

Las pruebas son necesarias en la fabricación de cualquier producto industrial y el desarrollo de proyectos informáticos.
¿Quién vendería una aspiradora sin estar seguro que aspira correctamente?
¿Quién vendería una rádio digital sin haber comprobado que pueda sintonizar los canales?
De la misma manera, una aplicación informática no puede llegar a las manos del usuario final con errores, y menos si estas son visibles y claras como para poder haber sido detectadas por el desarrollador. Se daría la situación de falta de profesionalidad y disminuiría la confianza por parte de los usuarios, que podría dar problemas para futuras oportunidades. Cualquier miembro del equipo de trabajo de un proyecto informático puede cometer errores. Los errores, además, se pueden dar en cualquier fase del proyecto (análisis, diseño, codificación…). Algunos de estos fallos serán más determinantes que otros y tendrán más o menos implicaciones en el desarrollo futuro del proyecto.
Las fase de desarrollo de un proyecto son:
  • Toma de requerimientos.
  • Análisis.
  • Diseño.
  • Desarrollo.
  • Pruebas.
  • Finalización.
  • Transferencia.

¿Qué es la realización de pruebas?

La realización de pruebas es una fase del desarrollo de un proyecto de software y es imprescindible realizarla antes de finalizar el proyecto y hacer la transferencia del proyecto al usuario final.
Sólo faltaría que el proyecto no funcionase tal como quiere el cliente...

Consideraciones

  • Todas las fases establecidas en el desarrollo del software son importantes. Independientemente, deberíamos considerar la fase de pruebas como una fase muy trascendente y darle mucha más importancia de la que a veces se le da.
  • La falta o mala ejecución de alguna fase por parte de cualquier miembro del equipo de trabajo puede provocar que el resto del proyecto arrastra uno o varios errores que serán más o menos determinantes para el éxito de la empresa.
Teniendo en cuenta las fases habituales en el desarrollo de software (toma de requerimientos, análisis, diseño, desarrollo, pruebas, finalización y transferencia), los perfiles habituales de un equipo de trabajo en un proyecto de desarrollo de software son:
  • Jefe de proyecto.
  • Analista.
  • Diseñador.
  • Programadores.
  • Testeadores.

Posibles errores

Ejemplo 1:
El jefe del proyecto planifica mal las horas invertidas en el diseño de las interfaces y al final resulta que el diseñador invierte más del doble.
¿Qué pasará?
→ La repercusión en el proyecto sólo será a nivel de tiempo y coste. Puede que se pueda compensar en alguna tarea posterior.

Ejemplo 2:
El creador de la BD ha obviado un campo clave de una tabla principal y su vinculación con otra tabla.
¿Qué pasará?
→ Depende de cuando se detecte el error puede que se pueda solucionar modificando algunas líneas de código o puede que haga falta rehacer muchísima faena y hayamos trabajado muchas horas para nada.

Hay estudios que demuestran que un error no detectado al principio del desarrollo de un proyecto puede llegar a necesitar 50 veces más esfuerzos para solucionarlo que si se hubiese detectado a tiempo.

Validación

Es la actividad encargada de asegurarse que la aplicación informática obtenida es la que se había determinado inicialmente y es la que se quería construir.
La validación confirmará que la aplicación funciona tal como el cliente ha pedido.
¿El sistema hace lo que el cliente quiere?

Verificación

Es la actividad que comprueba el funcionamiento correcto del código programado. Se comprobará que tecnológicamente la aplicación informática se haya desarrollado de forma correcta.
¿El sistema hace lo que tiene que hacer?
Consideraciones
  • Estos conceptos están directamente relacionados con las pruebas que verifican formalmente la corrección de una aplicación informática.
  • A lo largo del proyecto de desarrollo del software el sistema necesita que sea verificado y validado en cada paso del proceso, partiendo de la verificación y validación del paso anterior y estableciendo la documentación adecuada para poder volver a validar y verificar en el paso siguiente.
En la siguiente imagen se pueden observar las diferencias entre lo que pide el usuario, lo que se programa y lo que se entrega al usuario, que al final es lo que se utilizará.

Clasificación de las pruebas

  • Pruebas unitarias: Se realizan en el momento de acabar cada módulo.
    • Pruebas de caja negra.
    • Pruebas de caja blanca.
    • Revisiones.
  • Pruebas de integración: Se realizan en finalizar todos los módulos, cuando se quieren integrar.
    • Pruebas de integración ascendientes.
    • Pruebas de integración descendente.
    • Pruebas de integración combinadas.
    • Pruebas de integración de big bang.
  • Pruebas de carga: Se realizan cuando la aplicación ya está terminada y integrada, y se pone en funcionamiento haciendo una carga de datos reales.
  • Pruebas de aceptación: Si el cliente ya tiene la aplicación y es él mismo quien hace las pruebas.
  • Pruebas del sistema: Si se realizan para validar la integración del software en el sistema existente del usuario (rendimiento/robustez/resistencia/seguridad/usabilidad).

Pruebas unitarias

Pruebas de caja negra

  • Hacen la comprobación del funcionamiento de un módulo por medio de su interfaz sin entrar a analizar el funcionamiento interno.
  • En ningún momento se está evaluando o accediendo al código. Sólo se pueden ver las respuestas de la función para múltiples opciones dadas. Para comprobar si el módulo comprueba correctamente se tendrán que hacer pruebas introduciendo:
    • Datos correctos.
    • Datos erróneos.
    • Datos equivalentes.
    • Valores extremos superiores e inferiores.
  • Técnicas para establecer el juego de pruebas:
    • Clases de equivalencia. Escoger casos de prueba para cada tipo o conjuntos de datos de entrada y salida.
    • Análisis de los valores límite.
    • Estudio de errores típicos.
    • Manejo de las interfaces gráficas (ventanas, botones, iconos, etc…).
  • Ventajas:
    • Son independientes del lenguaje. Por lo tanto, son válidas para todos los métodos de programación utilizados.

Pruebas de caja blanca

Se fijan en cómo se ha implementado una determinada codificación de un módulo o una aplicación. En estas pruebas se examinan los detalles internos de implementación del código.
Para poder examinar el interior del módulo se deberán verificar aspectos como:
  • Sentencias, condiciones, bucles, etc…
  • Estructura del código.
  • Optimización del código.
Técnicas para establecer el juego de pruebas.
  • Cobertura de flujo de control. Se encontraría el diagrama de flujo de control haciendo el camino inverso al que se hace cuando se programa y garantiza que, como mínimo, se pase una vez para cada camino del programa. A partir del diagrama de flujo se deberían de ir probando todas las posibilidades.
    • Camino simple.
    • Condiciones.
    • Bucles simples.
    • Bucles anidados.
  • Ventajas
    • Si se siguen todos los sugerimientos para diseñar los casos de prueba para cada elemento (camino simple, condiciones, etc …) del código programado se conseguirá un mínimo de garantías de eficacia.

Revisiones

Se basan en la inspección directa del código, ya sea por módulos o de manera completa. A diferencia de las anteriores no pone a prueba el código en tiempo de ejecución. Las revisiones también son importantes con tareas vinculadas al control de calidad, validación y verificaciones del sistema.
Se hace una revisión del código de manera sistematizada y siguiendo unas normas. En general lo hace el mismo programador.
Técnicas grupales:
  • Reuniones: La revisión la hacen los mismos desarrolladores.
  • Canales externos: La revisión la hacen revisores expertos.
  • Inspecciones: La revisión la hacen los desarrolladores y revisores externos guiados por un moderador.
Ventajas.
  • Documentación del código.
  • Separación de las interfaces gráficas de usuarios y la implementación del código.
  • Simplificación de la integración entre módulos ya que será menos probable que hayan errores en los módulos independientes.

Pruebas de integración

Ascendentes

Estas pruebas comienzan combinando en grupos las unidades o módulos para ir probandolos. Se van probando diferentes agrupaciones por niveles y así sucesivamente hasta llegar a integrar todos los niveles.
Para llegar a este objetivo se necesita diseñar programas impulsores o controladores de pruebas que permiten simular el comportamiento de los módulos superiores.
Estos deberían de ser fáciles de construir porque solamente tienen la misma interfaz pero no hacen la misma función.
Su finalidad es poder ejecutar el módulo o grupos de módulos que se están probando.

Descendentes

En primer lugar se prueban los módulos del nivel superior y después se van integrando los componentes de la capa o nivel inferior y así sucesivamente.
En estos casos, es necesario diseñar módulos ficticios, simuladores de pruebas que emulan el comportamiento y tienen la misma interfaz que los reales. Son bastante más difíciles de construir porque necesitamos hacer la interficie y la función de cada módulo.

Combinada

Estas pruebas combinan la integración ascendente y descendente. Los módulos individuales se prueban tanto con los controladores como en ficticios y después se van probando las capas inferiores y superiores sustituyendo el controlador y ficticios para los módulos que ya se han probado. Habitualmente en la integración combinada en los niveles superiores se hace uso de una estrategia descendente y en los inferiores se aplica una estrategia ascendente.

Big bang

En primer lugar se prueban todos los métodos individualmente y después se integran todos los componentes o módulos del sistema y se hacen las pruebas.
Todo y que es una estrategia bastante simple de aplicar tiene la desventaja de que cuando se descubre un error es muy difícil de localizar y corregir.

Pruebas de carga

Objetivos

Comprobar el rendimiento y la integridad de la aplicación acabada con datos reales. Se trata de simular el entorno de programación de la aplicación. Para curarnos en salud y minimizar posibles errores en la fase de aceptación, cuando el producto tiene que ser usado por un gran número de clientes o usuarios finales se suelen utilizar las siguientes técnicas.

Pruebas alfa

Consisten en invitar a los clientes a probar el sistema en un entorno de desarrollo. Por el hecho de estar en un entorno controlado, el cliente siempre tiene el soporte de un experto para ayudarle a utilizar el sistema o analizar resultados.

Pruebas beta

Se desarrollan después de las anteriores en el entorno del cliente. El cliente se encuentra solo con el producto y trata de encontrar errores para informar a desarrolladores.

Pruebas de aceptación

Obtener la aprobación del cliente sobre la calidad de funcionamiento del sistema desarrollado y probado.

Pruebas del sistema

El objetivo es validar la aplicación cuando ya la ha aceptado el usuario y integrado con el resto de su sistema.
Tipos de prueba
  • Pruebas de rendimiento.
  • Pruebas de resistencia.
  • Pruebas de robustez.
  • Pruebas de seguridad.
  • Pruebas de usabilidad.
  • Pruebas de instalación.

Pruebas de regresión

El objetivo es detectar posibles nuevos errores o problemas que puedan salir al introducir cambios o mejoras en el programario. Vendrían a ser las típicas versiones de la misma aplicación.

Pruebas de humo

Describe la validación de los cambios de código en el software antes que los cambios en el código se registren en la documentación del proyecto. Por eso, antes de ejecutar las pruebas de humo se suele hacer una revisión del código.

Casos de prueba

Los casos de prueba definen cómo se llevarán a cabo las pruebas, especificando entre otros:
el tipo de pruebas, las entradas de las pruebas, los resultados esperados o las condiciones bajo las cuales se deberían desarrollar.
Los casos de prueba también siguen un ciclo de vida clásico:
  • Definición de los casos de prueba.
  • Creación de los casos de prueba.
  • Selección de los valores para los tests.
  • Ejecución de los casos de prueba.
  • Comparación de los resultados obtenidos con los resultados esperados.

Procedimientos de prueba

Los procedimientos de prueba especifican cómo se podrán llevar a cabo los casos de prueba o parte de estos de forma independiente o de forma conjunta, estableciendo las relaciones entre ellos y el orden en que se tendrán que atender.

plaprobes.PNG








dimecres, 2 de març del 2016

Lectura y escritura de ficheros en Java

Podemos hacer la lectura y escritura de ficheros con FileInputStream, que va carácter a carácter.
public class Stream {
public static void main(String[] args) throws IOException {

    FileInputStream in = null;
    FileOutputStream out = null;

    try {
        in = new FileInputStream("entrada.txt");
        out = new FileOutputStream("sortida.txt");
        int c;

        while ((c = in.read()) != -1) {
            System.out.println(c);
            out.write(c);
        }
    } finally {
        if (in != null) {
            in.close();
        }
        if (out != null) {
            out.close();
        }
    }
}
}
o podemos utilizar las lecturas con buffered.

public class ReaderWriter {
public static void main(String[] args) throws IOException {

    BufferedReader inputStream = null;
    PrintWriter outputStream = null;

    try {
        inputStream = new BufferedReader(new FileReader("entrada.txt"));
        outputStream = new PrintWriter(new FileWriter("sortida.txt"));

        String l;
        while ((l = inputStream.readLine()) != null) {
            System.out.println(l);
            outputStream.println(l);
        }
    } finally {
        if (inputStream != null) {
            inputStream.close();
        }
        if (outputStream != null) {
            outputStream.close();
        }
    }
}
}