**Materia - Evento:** Ingeniería de Software 1 - Obligatorio 2 **Código grupo - Docente:** M4A - Docente: Martin Solari **Estudiantes del equipo:** Chia Hung Hsieh, Poladura Guillermo, Sanguinetti Jimena **Fecha de entrega:** 25/06/2020 [**URL del repositorio**](https://github.com/ORT-FIS-202003/ob2-hsieh-poladura-sanguinetti.git) --- Índice ====== 1. [**Metodología general del obligatorio**](#metodología-general-del-obligatorio) 2. [**Calidad de código**](#calidad-de-código) 2.1 [**Estándares de codificación**](#Estándares-de-codificación) 2.2 [**Analizador estático de código**](#Analizador-estático-de-código) 3. [**Prueba unitaria**](#Prueba-unitaria) 4. [**Interfaz de usuario**](#Interfaz-de-usuario) 4.1 [**Herramientas de verificación de estándares de accesibilidad**](#Herramientas-de-verificación-de-estándares-de-accesibilidad) 4.2 [**Análisis heurístico**](#Análisis-heurístico) 4.3 [**Pruebas con usuarios**](#Pruebas-con-usuarios) 5. [**Construcción**](#Construcción) 5.1 [**Funcionalidades**](#Funcionalidades) 5.2 [**Proceso de Build**](#Proceso-de-build) 6. [**Testing funcional**](#Testing-funcional) 6.1 [**Casos de prueba**](#Casos-de-prueba) 6.2 [**Testing exploratorio**](#Testing-exploratorio) 7. [**Reporte de defectos**](#Reporte-de-defectos) 7.1 [**Estrucutra del issue**](#Estrucutra-del-issue) 7.2 [**Informe de issues**](#Informe-de-issues) 7.3 [**Estado general de la calidad de código**](#Estado-general-de-la-calidad-de-código) 8. [**Conclusiones**](#Conclusiones) Metodología general del obligatorio =================================== A la fecha del presente obligatorio, se mantienen las medidas sanitarias para contener la pandemia, por lo que se evitó el contacto presencial; recurrimos nuevamente a herramientas telemáticas que hicieron posible alcanzar los objetivos planteados, sin mayores dificultades. Para comenzar con esta segunda parte del trabajo, una de las primeras decisiones tomadas por el equipo fue el uso de la IDE _Intellij_ para implementar el código _JAVA_ dado su interfaz amigable y completitud de herramientas de soporte al lenguaje, y _Visual Studio Code_ para el código _HTML_ por su simplicidad y facilidad aplicación de extensiones. Se utilizó _Google Docs_ para la creación de archivos de texto, y _Zoom_ para realizar videoconferencias colaborativas durante el proceso de desarrollo, y _GitHub_ para el versionado de los códigos tanto de _HTML_ como _JavaScript_. Cada _commit_ es realizado cuando se termina una reunión colaborativa o cuando uno de los integrantes quiere corregir algún defecto específico respondiendo a un _issue_. En el repositorio se trabajaron con 3 ramas, para diferenciar claramente los diferentes trabajos, estos fueron: 1. Rama develop. Se encuentra la documentación, que se actualiza en paralelo con los trabajos realizados en las otras dos ramas. 2. Rama java. Se realiza el desarrollo de las funcionalidades del sistema, incluyendo el registro de perros para adoptar, buscar perros para adoptar y la funcionalidad de registro de adoptante. Los _commits_ se hacen en cada cicle de desarrollo en conjunto o cuando se resuelve un _issue_ pendiente. 3. Rama web. En esta rama se desarrolla toda la interfaz de usuario con _HTML_ y _Material Design_, se aplica la misma política de _commits_ que en la rama java. [**Volver al Índice**](#índice) Calidad de código ================== El uso de un estándar de codificación es uno de los aspectos que forman la calidad del código, es de gran importancia a la hora de desarrollar, y más en un trabajo en equipo, donde hay más de una persona realizando modificaciones casi simultáneamente, ya que impacta fuertemente en la legibilidad del código, y consecuentemente, en la velocidad y correctitud de compresión de la misma. Si bien intentamos participar los tres integrantes en todas las modificaciones, no es posible realizarlo a todo momento, razón por la cual notamos que es completamente imprescindible tener ciertas pautas claras y bien definidas antes de comenzar. Además de facilitar y hacer posible el trabajo en equipo, es una práctica que también facilita el mantenimiento del código tanto corto como largo plazo. Si bien este obligatorio no abarca la etapa de mantenimiento, es importante el aprendizaje de las buenas prácticas de codificación para el futuro. Estándares de codificación: --------------------------- Para poder alcanzar la calidad deseada apelamos a la simplicidad y a la coherencia del código mediante varias técnicas y buenas prácticas: * Indentación predeterminada. Antes de comenzar a codificar, los tres integrantes realizamos los ajustes necesarios en la IDE utilizada para que el tamaño de la indentación sea de 2 espacios. Esto es utilizado para determinar cierta jerarquía y estructura de control, a su vez mejorando la consistencia del código. * Límite de columna. Otra configuración que se estandarizó antes de comenzar, fue el largo de cada línea de código; definimos un largo de 120 caracteres por línea, de manera que no sea tan extenso el recorrido visual horizontal. Esto permite visualizar cada línea con una cota conceptual limitada, de modo que sea más fácil de conceptualizar y comprender. * Nomenclatura de elementos y funciones. En el espíritu de mejorar la legibilidad, se eligieron nombres descriptivos, cortos y concretos, a su vez, se utilizó un único idioma para redactarlos (en español), para dar uniformidad y concordancia entre las estructuras. * Uso de _camelCase_. Para nombrar los elementos que requieren más de una palabra para su descripción, se utilizó la metodología _camelCase_ para una veloz deserción de las mismas. * Uso de mayúsculas y minúsculas. En _JAVA_, los nombres de las clases comienzan con mayúscula, los paquetes, las funciones y las variables comienzan con minúscula. En _HTML_, los ids y las clases fueron nombradas en minúscula. * Uso de comentarios. Se llevó a cabo el uso de comentarios para facilitar la lectura del código, teniendo en cuenta el efecto opuesto que puede causar en caso de que se utilice en casos innecesarios. * Único punto de retorno en las funciones para no evitar dificultad de análisis. * Nombre de archivos en _HTML_. Se utilizó nombres estandarizados de los elementos de _HTML_, _javascript_ y _Material Design_, ya que esto mejora el nivel de aceptación de la página por Google, y por lo tanto la visibilidad de ella. * Elementos con accesibilidad determinada. Tanto públicos como privados, teniendo en cuenta que los públicos pueden dificultar el mantenimiento del código. * Orden de atributos. Los atributos de clase se piden con un orden específico por relevancia y aparecen correspondientemente en las clases en _JAVA_. En el código del CSS, por otra parte, se respeta un orden alfabético de los atributos. Analizador estático de código: ------------------------------ Se utilizó la herramienta _lintern_, específicamente _SonarLint 4.8.0.18115_ **SonarLint:** Es una extensión para IDE's (en nuestro caso, _IntelliJ_) que opera sobre una variedad de lenguajes de programación (en nuestro caso, _JAVA_), indicando errores y vulnerabilidades de seguridad a medida que se escribe el código, brindando además una guía concisa para la corrección de los mismos. La extensión informa los problemas detectados indicando una categoría y un nivel de severidad: * **Categorías** * **Bug**: Error de codificación que podría conducir a comportamientos no deseados y problemas de rendimiento. Debe ser solucionado inmediatamente. * **Vulnerability**: Problema de seguridad que podría significar una posible apertura que un atacante podría aprovechar * **Code Smell**: Violación de algún principio de codificación limpia (buenas prácticas de codificación) que puede hacer al código confuso y conducir a problemas de mantenimiento * **Niveles de severidad** * **Info**: No se trata de un error ni de un defecto de calidad, solo un hallazgo. * **Minor**: Leve defecto de calidad que puede afectar ligeramente la productividad del desarrollador (Ej: líneas de código demasiado largas, declaraciones de "switch" que contienen menos de 3 casos, etc.). * **Major**: Defecto de calidad significativo, que puede tener un gran impacto en la productividad del desarrollador (Ej: cobertura de código insuficiente, bloques duplicados, parámetros no utilizados, etc.). * **Critical**: Tanto un error con baja probabilidad de afectar el comportamiento de la aplicación en producción o un problema que representa una falla de seguridad (Ej: un bloque "catch" vacío, SQL injection, etc.) El código debe revisarse de inmediato. * **Blocker**: Error con una alta probabilidad de afectar el comportamiento de la aplicación en producción (Ej: pérdidas de memoria, conexiones JDBC no cerradas, etc.) El código debe corregirse de inmediato. Al analizar cada clase, SonarLint informó de una variedad de incidencias, todas del tipo **Code Smell**, con distinto grado de severidad, que fueron solucionadas: - En todas las clases se indicó: * Cambiar el nombre del "_package_" para adecuarlo a un "_regex_" usado convencionalmente para dicho fin (_Minor Code Smell_). * La remoción del "_import:java.lang_", dado que todas las clases lo importan implícitamente (_Minor Code Smell_). - En la clase Adoptante: * Reemplazar una sentencia "_if-then-else_" por una única sentencia "_return_" (_Minor Code Smell_). - En las clases Sistema e Interfaz: * Cambiar la implementación de "_ArrayList_" a "_List_" (_Minor Code Smell_). * Quitar la especificación de tipo en los constructores de los elementos de tipo _List_ usando, en lugar de, por ejemplo, "_<Adoptante>_", simplemente "_<>_" (_Minor Code Smell_). - En la clase interfaz: * Usar el método "_isEmpty()_" para chequear si una colección está vacía o no, en lugar de, por ejemplo, "_if(listaPerros.size() != 0)_" (_Minor Code Smell_). * Remover el parámetro _Sistema_ en los métodos en los que no era utilizado (_Mayor Code Smell_). * Modificar 2 métodos ("_filtrarListaAdoptantes_" y "_filtrarListaPerros_") para reducir su complejidad cognitiva de 17 a un número aceptable de 15 (_Mayor Code Smell_). Además se detectaron otras incidencias que decidieron ser ignoradas: * Remplazar el uso de "_System.out_" por "_logger_" (_Mayor Code Smell_). Se decidió ignorar esta recomendación ya que es sólo válida cuando no se busca mostrar un mensaje al usuario, sino sólo registrar resultados en un _log_. * Definir una constante de _String_ en lugar de repetir el mismo mensaje en varias ocasiones (_Mayor Code Smell_). En este caso, resultaba más claro para nosotros la repetición de ciertos textos en cada menú, que el uso de una variable. * La inclusión de demasiados parámetros en los constructores de las clases "_Adoptante_" y "_Perro_" (11 y 12, respectivamente, frente a los 7 considerados como aceptables) (_Mayor Code Smell_). En este caso, concluímos que era necesario que las clases contaran con los atributos incluídos, y por lo tanto no era posible reducir la cantidad de parámetros en los constructores. [**Volver al Índice**](#índice) ---------- Prueba unitaria =============== Esta es una de las formas de probar el sistema que se está desarrollando, busca probar si su funcionamiento es correcto; este debería realizarse en módulos y antes de que ese modulo sea agregado al resto del sistema, debe pasar por dicha prueba. En nuestro caso esto no fue posible dado que la herramienta _Junit_ fue introducida luego de haber hecho un avance significativo sobre el desarrollo del proyecto. Por esta razón, no fue posible aplicar la técnica de _test-driven development_, la gran parte de las pruebas se realizaron luego de haber desarrollado el código, a contraposición de la metodología planteada, donde se prueba el método previa a su implementación. A pesar de llevarse a cabo de tal forma, nos fue útil para encontrar ciertos errores en el código; estos no eran de suma importancia pero igual influyen en la calidad y mantenibilidad del sistema. Algunos de estos errores hallados fueron especificados en los issues, junto a una captura de pantalla del resultado erróneo obtenido. Metodología: ------------ Por cada clase de nuestro sistema se creó una clase nombrada con su clase referente y la palabra Test; dentro de cada una de estas clases se realizaron distintos métodos, cada uno correspondiente a una prueba unitaria diferente de un método de la clase, es decir, por cada método, hay más de una prueba. Se prueban las posibles entradas y se verifica que el resultado sea el esperado en cualquier caso, probando así ciertos casos limite y de excepción. Una medida utilizada fue que cada vez que incorporamos una prueba nueva, antes de pasar a la siguiente, se corroboró que no existan errores; esto nos fue útil dado que en ciertos casos el error no surgía del código del sistema sino que del código de la prueba, lo que hubiese sido más complejo de corregir en caso de crear todas y luego probarlas. Las pruebas realizadas fueron simples y cortas, siguiendo el procedimiento recomendado de inicialización, manipulación y verificación, y probando una cosa a la vez. Esto lo encontramos muy importante ya que al ser tan especificas, en caso de detectar un error, hallar el origen del mismo se tornó una tarea sencilla. Se utilizó _JaCoCo_, un analizador de cobertura de código integrado que tiene _Intellij_ que permite generar reportes de porcentaje de cobertura de código, dando una idea de las posibles zonas de alta y baja vulnerabilidad del proyecto sobre los _Tests_ generados, lo cual indicó: * Clase Perro: Se realizaron un total de 105 _Tests_ con un 92% de cobertura en los métodos y 84% de cobertura de las líneas de código. * Clase Adoptante: Esta clase tiene un total de 104 _Tests_, con 97% de cobertura de los métodos y un 87% de cobertura de las líneas de código. * Clase Procesos: Tiene un 100% de cobertura de los métodos, 100% de cobertura de las líneas de código. * Clase Sistema: Tiene el 52% de cobertura de los métodos y sólo 20% de cobertura de las líneas de código. En estos resultados tienen sentido ya que en las clases Perro y Adoptante se encuentran todos los métodos que involucran su registro, _set_, _get_ y validaciones; en la clase Procesos están los métodos de filtrado y de adopción, que se probaron en su totalidad; todos ellos tienen métodos concretos directamente vinculados al uso del programa, lo que permitió la implementación de una mayor cantidad de _Tests_ con un mejor rango. En cambio, en la clase Sistema se hallan métodos de interacción con el usuario, que validan el ingreso de datos y va más allá del rango de pruebas por _jUnit_ de este proyecto. [**Volver al Índice**](#índice) ---------- Interfaz de usuario =================== Para realizar la interfaz de usuario de este trabajo fue utilizado el recurso _Material Design_, es una normativa de diseño creada por Google que se enfoca en la visualización en las diversas plataformas digitales. Una correcta implementación de ella nos ayuda a generar una buena interfaz, ya que todos los elementos que lo componen siguen estándares rigurosos de accesibilidad y usabilidad. Adicionalmente, se trabajó teniendo en cuenta los estándares planteados por la _Web Content Accessibility Guidelines_, ya que el uso de _Material Design_ ayuda pero no asegura la perceptibilidad, robustez, la manejabilidad y la facilidad de entendimiento del uso de la página. Herramientas de verificación de estándares de accesibilidad ----------------------------------------------------------- * **_Extensión WAVE:_** Es una herramienta para la evaluación de estándares de accesibilidad planteados por la _WCAG_; cuenta con una extensión del navegador _Chrome_, que lo hace muy útil para su uso en nuestra página, que actualmente se ejecuta sobre un servidor local, lo que imposibilita su evaluación online. En ella encontramos los siguientes problemas: * Falta de declaración del lenguaje de la página, es importante destacar en qué idioma se encuentra la página para que esta no aparezca en la búsqueda de usuarios que usan otro lenguaje. Se corrigió agregando un _tag_ de lenguaje en la declaración del tipo de documento. * El texto alternativo de la imagen del logo tenía solo la descripción "logo", lo cual es demasiado genérico y brinda poca información, se corrigió cambiando el texto a "logo amiwi". * Varios elementos tienen la propiedad "aria-labelledby", que es importante en el uso de los elementos de _Material Design_, ya que indican al navegador la presencia de estructuras complejas y sus vínculos. En nuestro caso las estructuras no estaban referenciando correctamente a los elementos de la página. Se solucionó sustituyendo el _id_ al cual se referencia cada _input_(campo de ingreso de datos) con su _label_(indicador o referencia). * La página carecía de secciones estructurales, que fue sustituyendo la estructura que contenía el logo y la descripción de la página de un _div_ a un _header_, que si bien cumple la misma función, da una mejor guía al navegador. * El color de los botones no presentaban contraste suficiente con el fondo para que sea notorio para todo tipo de usuarios, incluyendo aquellos con dificultades visuales o pantallas de inferior calidad. Dado que el naranja no genera un nivel de contraste aceptable hasta bajar la luminosidad a un color tendiendo al marrón, decidimos cambiar el esquema de color a uno que sea más fácil de visualizar, y optamos dos variantes de verde, lo cual solucionó la alerta de accesibilidad. * **_Validador W3C_** La _W3C_ (o World Wide Web Consortium), es una organización que genera estándares para el material en la Web. Cuenta de validadores online donde puedes subir una página _HTML_ o _CSS_ para su inspección, en este caso, dado que trabajamos con archivos de estilo _SCSS_, pudimos validar únicamente el archivo _HTML_, de los cuales ha alertado los siguientes ítems: * Se vieron tags de múltiples ids duplicados, donde varias estructuras, dado que fueron tomados de los ejemplos de _Material Design_ y posteriormente clonados, compartían un mismo _id_ (que debe ser único en cada página web). Se corrigieron cambiando cada _id_ a una ocurrencia única. * El analizador considera error una práctica de _Material Design_, donde las estructuras _label_ o _button_ no deben contener _divs_. Dado que tales _divs_ son esenciales para la funcionalidad y estética de la estructura planteada por Material Design, decidimos ignorar este error. * Se emitió un _warning_ con respecto al uso del tipo _date_ en el ingreso de datos, ya que sugiere que no todos los navegadores soportan el selector de fechas. Para comprobarlo, se probó en 4 navegadores diferentes: en _Google Chrome_, _Microsoft Edge_ y _Brave_ funcionan correctamente, mientras que en _Safari_ se muestra únicamente un campo de texto, el cual deja como posible vulnerabilidad dado que puede provocar discrepancias en el formato de ingreso. Decidimos omitirlo ya que preferimos brindar la funcionalidad en la mayor cantidad de plataformas posibles, con el riesgo de tener inconsistencias de formato. Análisis heurístico: -------------------- Para este análisis de los principios de usabilidad se siguieron las reglas de Heurísticas de Nielsen, evaluando así: 1. Visibilidad del estatus del sistema: el formulario cuenta de una ayuda visual resaltando con un contorno más grueso y texto móvil sobre el elemento con el cual el usuario se encuentra interactuando. Adicionalmente, el botón de enviar formulario se encuentra deshabilitado hasta que el usuario haya completado los campos requeridos. 2. Vínculo entre el sistema y el mundo real: aparecen elementos en la página donde ayudan al usuario a comprender la funcionalidad de campos o botones, por ejemplo el sujetapapeles en el botón de adjuntar una imagen, aludiendo al adjunto de un documento, o el pequeño calendario que aparece en el costado del campo de selección de fechas. 3. Libertad y control del usuario: el usuario tiene la libertad de control de irse de la página con el botón de volver si quiere borrar el contenido ingresado sin tener que pasar por ninguna dificultad. 4. Consistencia y estándares: fueron analizados por las herramientas _WAVE_ y validador _HTML_ de _W3C_. 5. Prevención de errores: se evitan errores por parte del usuario a través del uso de etiquetas correctas en el código, siendo estas: campos requeridos, valor mínimo en campos numéricos y longitud máxima y mínima en campos de texto. 6. Reconocimiento en vez de memorización: cada uno de los campos es independiente al otro, se presenta una única instrucción de dos líneas cortas. 7. Flexibilidad y eficiencia de uso: para los usuarios altamente familiarizados con la interfaz, es posible navegar con la tecla "Tab" para avanzar de un campo a otro rápidamente y seleccionar números y campos de selección con la flecha hacia arriba o hacia abajo con una mayor eficiencia. 8. Diseño minimalista: se evita la información innecesaria que abrume al usuario, todo elemento que figura en la página es esencial a su uso. 9. Ayudar a los usuarios a reconocer, diagnosticar, y recuperarse de los errores: se utiliza un enmarcado rojo móvil cuando un usuario no ingresa un dato o ingresa uno no válido, y vuelve al color original una vez que el usuario ha adicionado o modificado el dato por uno correcto. 10. Ayuda y documentación: se provee al administrador de la página y del sistema las documentaciones pertinentes. Pruebas con usuarios: --------------------- Para poder visualizar y obtener datos empíricos del uso del sistema, se hizo la prueba de usabilidad con 3 usuarios diferentes (según Nielsen, cada usuario descubre 1/3 de los problemas, con 3 usuarios encontraríamos un aproximado del 70% de los problemas), indicando que rellenen el formulario de ingreso de perro para adoptar, evaluando la eficacia, eficiencia y satisfacción de estos: * **Primer usuario** Eficacia. Dado que es un usuario joven y usa su celular constantemente, se pidió que rellenara el formulario una interfaz de celular simulado con _Google Chrome_. Utilizó la página de sin problemas, rellenando todos los campos en su orden natural, pero detectó que la página cargaba el texto indicativo de una manera incorrecta, donde el cambio de renglón no se realizaba de manera dinámica. Eficiencia. Le ha tomado un tiempo relativamente largo dado la herramienta utilizada, pero pudo terminar en un aproximado de 4 minutos, lo cual nos pareció un flujo de trabajo aceptable. Satisfacción. Satisfactorio, le pareció que faltó pulir un poco la visual, el funcionamiento de los elementos de la página fueron correctas. * **Segundo usuario** Eficacia. El usuario utilizó la interfaz web abierta desde una computadora, y al ver el formulario con apuro, rellenó el nombre propio primero, detectando un problema de claridad en la declaración de la etiqueta. Luego rellenó los campos sin problemas hasta que llegó al peso, del cual quiso rellenar 0 asumiendo que no se sabía el peso del perro, pero el sistema le marcaba error. Planteó la posibilidad de quitar el requerimiento, pero consideramos que es un dato básico dentro de la ficha. Eficiencia. A este usuario le tomó únicamente 3 min, una velocidad relativamente alta y un buen indicador del tiempo a pesar de los problemas encontrados. Satisfacción. Aceptable, le gustaría ver cambios en los problemas de usabilidad encontrados. * **Tercer usuario** Eficacia. Este último usuario detecto un problema en el primer intento, ya que quiso ingresar un perro llamado "Al", lo cual el sistema no permite ya que el nombre requiere de 3 caracteres como mínimo. El usuario no supo cómo arreglar esto hasta que probó otros nombres, y cuando terminó, tampoco supo cuál fue el error en la primera instancia, lo cual sugiere que debería haber algún indicativo de qué se debe rellenar en cada campo. Eficiencia. El tiempo que le llevó fue mayor aún, dado por los errores encontrados, el total fue de un poco más de 4 minutos, que fue aceptable. Satisfacción. Le pareció inaceptable que no se pueda saber cuál fue el error en el ingreso, que causa un confusión y molestia. De las pruebas de estos tres usuarios pudimos obtener la información para realizar las siguientes modificaciones a la usabilidad: 1. Cambiar la etiqueta del primer campo de ingreso a "Nombre del perro" para que sea más intuitivo. 2. Cambiar el formato del texto indicativo en el cabezal de la página para que se ajuste dinámicamente al tamaño de pantalla. 3. Agregar el texto de ayuda en cada una de las secciones de ingreso de datos, para que el usuario pueda saber cuál es el criterio de aceptación del mismo. [**Volver al Índice**](#índice) ---------- Construcción ============ Funcionalidades --------------- 1. Registro: El sistema puede registrar Adoptantes (con nombre, apellido, edad, sexo, e-mail, teléfono, tipo de vivienda, tamaño de vivienda, cantidad de mascotas previas y el estado actual del adoptante que puede ser sin responder, ya adoptó, rechazado, archivado en espera o ya no está interesado) con las respectivas validaciones en cada atributo. El registro de los perros ocurre de la misma manera, pero con diferentes atributos (nombre, edad, sexo, raza, tamaño, peso, estado de castración, fecha de ingreso, estado de adopción, descripción). 2. Edición: Todos los parámetros de tanto de adoptante o perro son editables, de modo que si cambia algún atributo o cambian de estado pueda reflejarse correctamente en el sistema. 3. Listado: Muestran todos los adoptantes o perros de acuerdo a la aplicación de filtros predeterminados (o no), en el caso de los adoptantes se pueden filtrar por tipo de vivienda, tamaño de vivienda y estado; en el caso del perro los filtros son sexo, tamaño y estado. Se pueden aplicar varios filtros combinados para lograr una mejor búsqueda. 4. Adopción: Dado que nuestro sistema no se basa en el uso de cualquier usuario, sino que un administrador o varios administradores capacitados que hacen todos los registros, estos tienen el control del flujo de esta funcionalidad. Una vez aprobada la adopción, el administrador entra a la función donde se va a mostrar los listados de adoptantes que tienen estado "Archivado en espera" y perros "Disponibles" en el sistema, puede entonces seleccionar el adoptante y el perro de las listas correspondientes y asignar la adopción. Una vez terminado, el estado del perro cambia automáticamente a "Adoptado", y al adoptante se le cambia a "Ya adoptó - Perro adoptado: " y el número de id interno que le corresponde al perro adoptado. Proceso de Build ---------------- Se genera un archivo JAR que contiene todas las clases del dominio. Para ello se deben seguir los siguientes pasos: 1. Abrir el menú "File" 2. Seleccionar opción "Project structure" 3. Dentro de las opciones de "Project settings", se selecciona la sección "Artifacts" 4. Seleccionamos el símbolo “+” y seleccionamos el formato ".jar from modules with dependencies" 5. Elegir "Main class", la clase que contenga el main que deseas correr cuando se ejecute el archivo. 6. En la sección "JAR files from libraries" seleccionamos la opción "extract to the target JAR" 7. Luego hacemos click en "Ok", dos veces 8. Abrir el menú Build, seleccionar la opción "Build artifacts" y luego "Build" para crear el archivo 9. Por último encontraremos nuestro archivo .jar en la ruta java/out/artifacts/java_jar Para este trabajo no se utilizaron librerías externas dado que no fue necesario su uso. El proyecto en su totalidad se encuentra en una carpeta que a su vez esta dividida en dos partes, por un lado todas las clases del dominio, incluyendo la clase de prueba que contiene la interfaz por consola. Por el otro lado se encuentra otra carpeta que incluye todas las clases de prueba realizadas con _jUnit_, correspondientes a las clases del dominio. En el archivo .jar no se incluyen las clases de testing. Creamos a su vez un archivo .bat para que se pueda ver correctamente la ejecución del archivo "java.jar", ambos archivos fueron copiados en el siguiente directorio: * [**Archivo .jar**](jar/java.jar) * [**Archivo .bat**](jar/consola.bat) [**Volver al Índice**](#índice) ---------- Testing funcional ================= El testing es una actividad explícita y profesional que no se trató solo de ejecutar pruebas, sino que también existió una planificación, división en etapas, reserva de tiempo, diseño de casos de prueba, evaluación de la salida, informes del testing. En esta etapa se trata de evitar la inmediatez de querer corregir todo en el momento y se controló la autoconfianza excesiva personal ya que cada decisión pasó por todos los integrantes; esto nos dio una mirada más independiente y objetiva sobre el trabajo en general. Casos de prueba --------------- Para el testing existen técnicas de caja blanca y de caja negra; la primera mencionada hace referencia a la estructura lógica interna, pero esta no se llevo a cabo en este trabajo. La segunda tiene un punto de vista más funcional, que se enfoca en las entradas y salidas esperadas, de estas técnicas se usaron la partición de equivalencia en conjunto con el análisis de valores límite, donde se fueron dividiendo clases de equivalencia, probando cada uno de ellos con la mayor cantidad de valores límites posibles. Se realizó el testing de caja negra de las siguientes funcionalidades, donde se plantea una tabla de casos de uso con su curso normal y alternativo (una secuencia de acciones que se pueden tomar cuando se utiliza el _software_), tabla de escenarios (se le da un nombre a los cursos normales y alternativos), tabla de nomenclatura de casos de prueba (se les asigna un nombre de referencia y los datos que acepta), clases de equivalencia (dividir las entradas utilizadas por similitud de comportamiento entre ellas), y tabla de casos de prueba (entradas y salidas reales y el resultado del comportamiento del sistema). * En _JAVA_: * [**Registrar adoptante**](pruebas/registrar_adoptante.xlsx) * [**Registrar perro**](pruebas/registrar_perro.xlsx) * [**Editar adoptante**](pruebas/editar_adoptante.xlsx) * [**Editar perro**](pruebas/editar_perro.xlsx) * [**Filtrar adoptantes**](pruebas/filtrar_adoptantes.xlsx) * [**Filtrar perros**](pruebas/filtrar_perros.xlsx) * [**Adopción**](pruebas/adopcion.xlsx) * En _HTML_: * [**Registrar perro en Web**](pruebas/registrar_perro_web.xlsx) Testing exploratorio -------------------- Dado la carencia de experiencia de realización de testing en el equipo, se eligió la metodología basado en sesiones, para explorar las posibles vulnerabilidades a partir del conocimiento sobre el código que tienen los integrantes por encima del conocimiento de los complejos procesos de adaptación dinámica que son necesarios para otros procesos de testing. Para ello se determinan ciertos parámetros: aplicación a probar, unidad de tiempo para la prueba, objetivo de la sesión, el integrante responsable y notas donde se indican el conjunto de pruebas realizadas junto a los resultados y las posibles vulnerabilidades encontradas, que posteriormente pueden llegar a ser traducidas a _issues_. Este testing fue realizado teniendo en cuenta del hecho que en general, el tester no es el desarrollador, y por ende no puede corregir los issues que se planteen. Por lo tanto, para quitarse el perfil del desarrollador y adentrar realmente en el perfil del tester, los issues encontrados en estas pruebas **no van a ser cerrados**. * **Sesión de testing exploratorio #1** * Aplicación a probar: Aplicación _JAVA_. * Unidad de tiempo: 60 min. * Objetivo: Validar el ingreso de datos duplicados y combinación de varias funcionalidades dado que esto no se prueba en los casos de prueba por la segmentación. * Tester: Chia Hung Hsieh * Notas: Al ingresar adoptante y luego ingresar otro con exactamente los mismos atributos, quedan registrado dos personas que en el sistema no es posible visualizar la diferencia, quedan registrado un duplicado dado la falta de manejo de un identificador que valide la unicidad (comúnmente conocido como _primary key_). Otro tema a destacar a raíz de la misma prueba es la ausencia de validación de teléfonos y/o e-mails duplicados. Cuando se ingresa a la funcionalidad de adopción, se puede emparejar un adoptante con un perro sin problemas, pero luego si se edita el estado del adoptante a "Archivado en espera", y se empareja la adopción con un perro nuevo, se borra el historial de adopción del perro anterior. Cuando se muestran los datos del adoptante indica un único perro que es el último que ha adoptado, esto o bien debería indicar "último perro adoptado" o bien debería presentar una lista con los perros que fueron adoptados por el adoptante para un óptimo seguimiento de estos. Cuando se edita el estado de un perro cambiándolo de adoptado a disponible, en el adoptante sigue figurando que tiene el estado de "Ya adoptó" y sigue siendo asignado el perro, lo cual puede generar conflictos de datos posteriormente. La falta de una funcionalidad de búsqueda general hace que sea más difícil su uso, ya que uno debería poder encontrar en el sistema rápidamente el adoptante en caso de ya tener el dato del nombre el e-mail o teléfono del primero, o la fecha de ingreso en el caso del perro. Cuando se ingresa el perro, se consulta el atributo de tamaño, cuando debería describirse con "tamaño esperado" para ajustarse con la funcionalidad deseada. * **Sesión de testing exploratorio #2** * Aplicación a probar: Aplicación _JAVA_. * Unidad de tiempo: 30 min. * Objetivo: Validar la consistencia en las diferentes funcionalidades. * Tester: Guillermo Poladura * Notas: La fecha de ingreso del perro tiene validación inconsistente. Algunos casos deja ingresar como fecha válida años en formato tanto "aa" como "aaaa", esto podría generar ambigüedades en los registros, ya que, por ejemplo, la fecha 9/11/89, podría referirse a 9/11/1989 o a 9/11/2089. Cuando se ingresa a la opción de edición de datos del perro, se pueden seleccionar 11 opciones diferentes. Si se selecciona "Edad", el sistema pide la edad nueva a ingresar", en cambio, si se selecciona "Descripción", el sistema consulta nuevamente "Desea agregar una breve descripción ?", en lugar de poner el campo directamente. En los campos de texto carecen de un validador de longitud, lo que puede causar problemas ya que si se ingresa una cantidad desmedida de caracteres puede causar problemas de uso posteriores ya sea en la visualización del dato en la interfaz o el almacenamiento del dato. * Sesión de testing exploratorio #3 * Aplicación a probar: Interfaz Web. * Unidad de tiempo: 45 min. * Objetivo: Validar el uso, funcionamiento y apariencia correcta de todos los elementos en los navegadores: _Chrome_, _Firefox_, _Edge_, _Brave_, y navegación por tablet y celular simulado en la herramienta de desarrollo de _Chrome_. * Tester: Jimena Sanguinetti * Notas: Todos tienen la correcta funcionalidad de reajuste de tamaño de pantalla, aunque en _Edge_ no se pudo evaluar todas las anchuras posibles ya que no permite reducir su anchura a un tamaño menor que aproximadamente el 50% del ancho de la pantalla. En selector de fechas funciona correctamente en todos los navegadores, pero _Firefox_ se diferencia del resto ya que no presenta un ícono de calendario sino simplemente un campo que cuando se selecciona, aparece el calendario, esto no constituye un problema grave pero es un punto en contra desde el punto de vista heurístico. En _Firefox_ es posible ingresar caracteres no numéricos en los campos numéricos como años o meses (si bien no es aceptado y marca en color rojo el borde del _input_), en el resto no es posible ingresarlos directamente del teclado, sólo si se copia de otra fuente y se pega dentro del campo. Cuando uno ingresa texto a copiado y pegado en un campo numérico, si se presiona el botón de incremento o decremento, en la mayoría de los navegadores se borra automáticamente el texto previo, en _Firefox_ el botón deja de funcionar hasta que el usuario borre el contenido del campo. Los botones de incremento o decremento desaparecen en las plataformas de celular, ya que con una pantalla chica generan más impedimento que ayuda real. Se probó brevemente en la plataforma _Internet Explorer 11_ sólo para ver como responde un navegador desactualizado a elementos nuevos como lo es _Material Design_, el cual renderizó la página con una anchura de casi triple del tamaño de la pantalla, a su vez, fuera de los campos de ingreso de texto, el resto de las funcionalidades se encuentran totalmente corruptas. [**Volver al Índice**](#índice) ----------------- Reporte de defectos =================== Una vez que fue desarrollado el código y la documentación base, fue posible empezar a reportar los defectos de este. Para lograrlo eficientemente y con el un registro apropiado, implementamos el uso de la herramienta de _issues_ en el repositorio de _GitHub_. Cada defecto encontrado se plantea con una etiqueta que lo clasifica, un título corto y una descripción detallando lo encontrado, y en caso de ser posible, también se adiciona una captura de pantalla del defecto en su entorno. Una vez resuelto un _issue_, realizamos un commit que correspondiente al mismo y lo cerramos, de forma que quede un registro claro del mismo y de su solución. Fue de gran utilidad ya que previamente no poseíamos una herramienta de seguimiento de los _bugs_, y muchas veces causaba confusión si un _issue_ había sido resuelto, o en algunos casos, cómo volver a reproducir un _issue_ no resuelto. Estrucutra del _issue_ ---------------------- Documentamos los issues con los siguientes atributos que nos parecieron relevantes: * Resumen: Se plantea una breve reseña del _issue_, dando una idea general para que un desarrollador pueda orientarse. * Plataforma: Dado que el desarrollo de código y documentación se produce sobre múltiples plataformas, ayuda tener una mejor organización saber dónde está el _issue_. * Severidad: Aquí se determina la relevancia del _issue_, si genera un defecto de uso serio o hace caer el sistema (Alta), si hace que el sistema se comporte de manera anormal pero no llega a caer (Media), o simplemente es un problema visual, sintáctico o que no influye en el uso normal (Baja). * Pasos a reproducir: Se indica una serie de acciones para poder recrear el _issue_, ya que ayuda ampliamente en la visualización del causante y el contexto del _issue_ para poder mitigarlo lo más rápido posible. * Resultado actual: Se da una descripción corta del _isssue_ encontrado. * Resultado esperado: Se plantea una indicación de lo que debe suceder o mostrarse en un curso correcto del evento. * Imagen: En caso de ser posible, se adiciona una imagen del _issue_ en su contexto (y comprobando su existencia). Informe de _issues_ ------------------- Se registraron una mejora y un total de 42 _issues_, de los cuales: * Plataforma: 14 fueron en la plataforma Web, 2 en la documentación, y 26 en la plataforma PC, esto es dado al mayor nivel de complejidad y cantidad de código que presenta este último. * Severidad: Se registraron 30 casos de severidad baja, 9 casos medios y 3 casos altos. Esto tiene sentido, ya que durante el desarrollo es mucho más fácil de ver los errores que rompen el sistema, por lo cual es más raro que llegue a etapas posteriores de pruebas. En cambio los errores simples o de accesibilidad, son difíciles de notar a menos que se estén buscando. * Por _label_: Para mejorar la búsqueda y visualización de los _issues_, se les asignaron las siguientes etiquetas (puede tener más de una por _issue_): * Accesibilidad: 9 casos. * Código: 30 casos. * Calidad de código: 4 casos. * Documentación: 2 casos. * Mejoras: 3 casos. * Imagen: De los 42 casos, 29 presentan una imagen descriptiva del defecto. Esto fue incorporándose cada vez más a medida que avanzamos sobre el proyecto ya que la imagen muchas veces describe mejor el defecto que las palabras y lo hace más fácil de contextualizar. * Cierre: Durante las etapas de desarrollo y las pruebas de casos de uso, se crearon _issues_ de acuerdo a lo encontrado y fueron solucionados rápidamente, formando un total de 31 _issues_ cerrados. Para simular un entorno de desarrollo real con diversas áreas, durante la etapa de testing exploratorio se propuso que los integrantes no tengan la capacidad de resolver los _issues_ encontrados, por lo tanto estos 11 quedaron en estado abierto. Estado general de la calidad de código -------------------------------------- Gracias a las diversas herramientas aplicadas para la validación del proyecto (_SonarLint_, _WAVE_, _HTML Validator_, Pruebas con usuarios, Casos de prueba y Testing exploratorio), se pudieron identificar una gran cantidad de errores que previamente eran desconocidos para los integrantes del proyecto, ya que los desarrolladores en general tienden a generar una visión túnel, y muchas veces ignoran fallas que están fuera del entorno de desarrollo, ya sea estándares nuevos de calidad, cualidad de accesibilidad, o simplemente la dificultad de entendimiento para un usuario común. Creemos que luego de aplicar las diversas técnicas, el proyecto generado tiene una robustez relativamente alta, pero como figura en los datos previos, podemos visualizar que la calidad de código nunca se termina de perfeccionar, ya que siempre hay mejoras posibles; algunas inclusive puede que no sean posibles de lograr dado los recursos, la cantidad de integrantes involucrados, el tiempo invertido, el conocimiento del área. [**Volver al Índice**](#índice) ---------- Conclusiones ============ El objetivo de la presente entrega es generar software de calidad; esto involucra varios niveles de estudio, ya que la calidad no es un concepto unidimensional, sino que cuenta con una gran diversidad de enfoques, los cuales fueron evaluados durante el desarrollo. La base de esto es un estándar de codificación, ya que sin ello se puede generar código confuso y abstracto, que al acumularse puede generar un _software_ imposible de mantener dado lo críptico que es, esto lo vivimos día a día cuando tratamos de revisar un código viejo escrito hace un tiempo, muchas veces perdemos la noción de la referencia de los elementos por falta de claridad cuando fue instanciado. Esperamos que al aplicar las diversas prácticas de estándares de codificación, estas ocurrencias sean cada vez menos comunes. La funcionalidad del _software_ es uno de los puntos que históricamente fueron los más enfocados por los desarrolladores, pero la abundancia de ella se traduce a un buen programa. Es necesario poder descubrir lo posibles defectos de ello y una de las herramientas más adecuados es la prueba por _jUnit_, que nos ayudó a evaluar de manera clara, consistente y estructurada que el programa haga lo que tenga que hacer y no haga lo que no tiene que hacer. En esta etapa no pudimos poner en práctica una de las utilidades de _jUnit_ que es el _test-driven-development_, pero esperamos aplicarlos y ver su impacto en proyectos futuros. Un aspecto muy importante que nunca hemos trabajado previo a este proyecto es el concepto de usabilidad y accesibilidad, el primero indica que tan fácil de usar es un sistema y el segundo apunta a la variedad de gente que pueda utilizarla. Al no ser un tema estrictamente funcional, es muy fácil que un desarrollador los omita, pero la realidad es que sin accesibilidad no se puede llegar a una buena usabilidad, y sin usabilidad los usuarios no van a querer seguir usando el programa. Fue una experiencia reveladora trabajar sobre la variedad de consideraciones que se deben tener a la hora de asegurar la buena usabilidad y accesibilidad, ya sea el manejo de elementos que vinculen al usuario con el mundo real, el manejo de los contrastes de color para la visibilidad, la posibilidad de acceso multi-modal para aquellos usuarios con dificultades o la visibilidad del status del sistema para los menos experienciados, todo ello formó parte de un aprendizaje muy enriquecedor. Las técnicas de testing (ya sea exploratorio o de casos de uso) también aportaron una experiencia diferente, ya que es difícil dejar el perfil del desarrollador donde cada _issue_ que encontramos lo queremos arreglar en el instante, y enfocarse realmente al testing. En un proyecto chico es posible ir arreglando "en la marcha", pero no es realista, ya que en los _software_ más grandes cada funcionalidad tiene un sin fin de dependencias, por lo cual no es realista querer corregir todo en el momento que se encuentra, cada ciclo tiene sus instancias determinadas y cada integrante tiene que cumplir las tareas fieles a su rol. Al igual que en el testing, el registro de _issues_ generó estructura y disciplina que si bien beneficia el seguimiento de los procesos de desarrollo, no genera un cambio muy radical en un equipo chico de desarrollo, pero podemos ponderar su impacto en ambientes de trabajo de equipos más grandes en los que trabajemos en el futuro. En el proceso de desarrollo de este proyecto no nos encontramos con muchas dificultades puntuales, sino que vimos una dificultad general asociado al código que va mucho más allá que el código en sí; todo lo que uno desarrolla tiene un alto grado de influencia en su alrrededor, ya sea en el compañero que va a mantenerlo o el adoptante que quiere usar el programa. Tiene muchas dependencias que cuidar para asegurar que lo que se genera no va a ser un carga para el resto, eso no quiere decir que el código tiene que ser perfecto, ya que nunca lo es; sino que tiene que seguir una serie de reglas, con la ayuda de un abanico de herramientas que ya están a nuestra disposición para acercarnos lo más posible a una buena calidad de _software_. [**Volver al Índice**](#índice) ----------