UNIVERSIDAD CENTRAL DEL ECUADOR CARRERA DE INGENIERÍA ... · palabras claves: desarrollo guiado por pruebas / metodologÍas de desarrollo de software / pruebas unitarias / refactorizar
Post on 25-Jun-2020
2 Views
Preview:
Transcript
UNIVERSIDAD CENTRAL DEL ECUADOR
FACULTAD DE INGENIERÍA, CIENCIAS FÍSICAS Y MATEMÁTICA
CARRERA DE INGENIERÍA INFORMÁTICA
SISTEMA DE CAPACITACIÓN VIRTUAL PARA LA IMPLEMENTACIÓN DE LA
METODOLOGÍA DE DESARROLLO DE SOFTWARE TEST DRIVEN DEVELOPMENT
TRABAJO DE GRADUACIÓN PREVIO A LA OBTENCIÓN DEL TITULO DE
INGENIERO INFORMÁTICO
AUTOR: DAVID VLADIMIR CASTRO CRUZ
TUTOR: ING. ALDRIN ISMAEL FLORES SUAREZ
QUITO – 17 DE OCTUBRE
2016
ii
AUTORIZACIÓN DE LA AUTORÍA INTELECTUAL
Yo, David Vladimir Castro Cruz en calidad de autor del trabajo integrador Sistema de
capacitación virtual para la implementación de la metodología de desarrollo de software
Test Driven Development, autorizo a la Universidad Central del Ecuador hacer uso de
todos los contenidos que me pertenecen o parte de los que contiene esta obra, con fines
estrictamente académicos o de investigación.
Los derechos que como autores me corresponden con excepción de la presente
autorización, seguirán vigentes a mi favor, de conformidad con lo establecido en los
artículos 5, 6, 8; 19 y demás pertinentes de la Ley de Propiedad Intelectual y su
Reglamento.
Asimismo, autorizo a la Universidad Central del Ecuador para que realice la
digitalización y publicación de este trabajo integrador en el repositorio virtual, de
conformidad a los dispuesto en el Art. 144 de la Ley Orgánica Educación Superior.
En la ciudad de Quito, a los 17 días del mes de octubre del 2016
David Vladimir Castro Cruz
CC: 1721885521
Teléfono: 023260417 – 0992789386
Email:ktheosmart@hotmail.com
iii
APROBACIÓN DEL TUTOR DEL TRABAJO DE TITULACIÓN
Yo, Aldrin Ismael Flores Suarez, en calidad de tutor del trabajo de titulación Sistema de
capacitación virtual para la implementación de la metodología de desarrollo de software
Test Driven Development, elaborado por el estudiante David Vladimir Castro Cruz de la
Carrera de Ingeniería Informática, Facultad de Ingeniería, Ciencias Físicas y Matemática
de la Universidad Central del Ecuador, considero que el mismo reúne los requisitos y
méritos necesarios en el campo metodológico y en el campo epistemológico, para ser
sometido a la evaluación por parte del jurado examinador que se designe, por lo que
APRUEBO, a fin de que el trabajo integrador sea habilitado para continuar con el
proceso de titulación determinado por la Universidad Central del Ecuador.
En la ciudad de Quito, a los 2 días del mes de septiembre del 2016
Ing. Aldrin Ismael Flores Suarez
CC: 1001662186
Teléfono: 0984050315
Email: aldrinflores.uce@gmail.com
iv
DESIGNACIÓN DEL TRIBUNAL
v
CALIFICACIÓN DEL TRIBUNAL
vi
AGRADECIMIENTO
Primeramente, a mi madre, por su apoyo incondicional, por su paciencia a través de
todos estos años, por creer en mí y porque todo ha sido posible gracias a ella.
A mis hermanos, por su respaldo a lo largo de mi vida educacional y estar siempre
dispuestos a compartir sus conocimientos conmigo.
A todos los amigos que han estado ahí para motivarme, ayudarme y aconsejarme en
momentos tanto tranquilos como difíciles.
A mi tutor, por su asesoramiento en la realización de este proyecto y toda la ayuda
brindada para agilizar la culminación del mismo.
Y quiero expresar un agradecimiento muy especial a Paola Tapia, una de las mejores
personas que he conocido en toda mi vida, los motivos sobran.
Muchas gracias a todos por ayudarme a cumplir esta meta.
vii
CONTENIDO
pag.
AUTORIZACIÓN DE LA AUTORÍA INTELECTUAL ...................................................... ii
APROBACIÓN DEL TUTOR DEL TRABAJO DE TITULACIÓN .................................... iii
DESIGNACIÓN DEL TRIBUNAL ................................................................................. iv
CALIFICACIÓN DEL TRIBUNAL .................................................................................. v
AGRADECIMIENTO .................................................................................................... vi
CONTENIDO ............................................................................................................... vii
LISTA DE TABLAS ..................................................................................................... xix
LISTA DE FIGURAS ..................................................................................................... x
LISTA DE GRÁFICOS ................................................................................................. xi
RESUMEN ................................................................................................................... xii
ABSTRACT ................................................................................................................ xiii
INTRODUCCIÓN .......................................................................................................... 1
1. MARCO TEÓRICO ................................................................................................ 3
1.1. Antecedentes .................................................................................................. 3
1.2. Fundamentación Teórica ................................................................................ 4
1.2.1. Sistema Web ........................................................................................... 4
1.2.2. HyperText Markup Language (HTML)...................................................... 5
1.2.3. Javascript (JS) ......................................................................................... 5
1.2.4. Cascading Style Sheets (CSS) ................................................................ 6
1.2.5. Capacitación ............................................................................................ 7
1.2.6. e-Learning (Educación virtual) ................................................................. 7
1.2.7. Test-Driven Development ........................................................................ 7
1.2.8. Pruebas unitarias ................................................................................... 10
2. METODOLOGÍA .................................................................................................. 11
2.1. Marco Metodológico ..................................................................................... 11
2.2. Evaluación de la situación ............................................................................ 11
2.2.1. Análisis FODA del proyecto ................................................................... 12
viii
2.2.2. Análisis de Riesgos ............................................................................... 13
2.3. Desarrollo del proyecto ................................................................................. 19
2.3.1. Especificación de requerimientos .......................................................... 19
2.3.2. Plan de clase ......................................................................................... 20
2.3.3. Estrategia pedagógica ........................................................................... 21
2.3.4. Contenido del curso de capacitación ..................................................... 22
2.3.5. Diagrama del flujo (DFD) ....................................................................... 40
2.3.6. Herramientas a utilizar ........................................................................... 42
2.3.7. Arquitectura ........................................................................................... 48
2.3.8. Diagrama entidad relación ..................................................................... 50
2.3.9. Diseño de Interfaces (prototipo) ............................................................. 51
3. RESULTADOS .................................................................................................... 56
3.1. Interfaces de usuario .................................................................................... 56
3.2. Métricas del sistema ..................................................................................... 57
3.3. Retroalimentación por parte de usuarios ...................................................... 58
4. DISCUSIÓN ......................................................................................................... 63
5. CONCLUSIONES ................................................................................................ 65
6. RECOMENDACIONES ........................................................................................ 66
BIBLIOGRAFÍA ........................................................................................................... 67
ANEXOS ..................................................................................................................... 69
ANEXO A ................................................................................................................ 70
ANEXO B ................................................................................................................ 85
ANEXO C ................................................................................................................ 87
ix
LISTA DE TABLAS
pag.
Tabla 1. Análisis FODA .............................................................................................. 13
Tabla 2. Tabla de riesgos .......................................................................................... 14
Tabla 3. Tabla de determinación de probabilidades .................................................... 14
Tabla 4. Tabla de determinación de impacto .............................................................. 14
Tabla 5. Matriz de calificación y evaluación de riesgos ............................................... 14
Tabla 6. Riesgo inicial ................................................................................................ 15
Tabla 7. Riesgo final o inherente ................................................................................ 19
Tabla 8. Plan de clase ............................................................................................... 21
Tabla 9. Afirmaciones más usadas de PHPUnit ......................................................... 27
Tabla 10. Detalle de flujos del dfd flujo principal del sistema TDD School .................. 41
Tabla 11. Cuadro comparativo de bases de datos ..................................................... 46
Tabla 12. Cuadro comparativo de lenguajes de programación .................................. 46
Tabla 13. Detalle del diagrama entidad relación del sistema TDD School .................. 51
Tabla 14. Recopilación de métricas del sistema TDD School .................................... 57
Tabla 16. Detalle de pruebas end-to-end del sistema TDD School ............................ 90
x
LISTA DE FIGURAS
pag.
Figura 1. Distribución de factores del análisis FODA ................................................. 12
Figura 2. Diagrama del contenido del curso de capacitación ..................................... 23
Figura 3. Algoritmo de TDD ....................................................................................... 31
Figura 4. Diagrama ciclo RGR ................................................................................... 33
Figura 5. Dfd flujo principal del sistema TDD School .................................................. 40
Figura 6. Arquitectura de hardware del sistema TDD School ..................................... 48
Figura 7. Arquitectura de software del sistema TDD School ...................................... 49
Figura 8. Diagrama entidad relación de base de datos del sistema TDD School ....... 50
Figura 9. Prototipo de pantalla de bienvenida del sistema TDD School ..................... 52
Figura 10. Prototipo de pantalla de ingreso y registro del sistema TDD School ......... 52
Figura 11. Prototipo de pantalla de inicio del sistema TDD School ............................ 53
Figura 12. Prototipo de pantalla de lección del sistema TDD School ......................... 53
Figura 13. Prototipo de pantalla de pregunta del sistema TDD School ...................... 54
Figura 14. Prototipo de pantalla de ejercicio del sistema TDD School ....................... 54
Figura 15. Prototipo de pantalla de finalización del sistema TDD School ................... 55
Figura 16. Diseño final del sistema TDD School ........................................................ 56
xi
LISTA DE GRÁFICOS
pag.
Gráfico 1. Opinión de usuarios acerca del diseño visual del sistema ......................... 58
Gráfico 2. Opinión de usuarios acerca de la facilidad de uso del sistema .................. 58
Gráfico 3. Opinión de usuarios acerca del rendimiento del sistema ........................... 59
Gráfico 4. Opinión de usuarios acerca de los videos del curso .................................. 59
Gráfico 5. Opinión de usuarios acerca de las evaluaciones del curso ........................ 59
Gráfico 6. Opinión de usuarios acerca de la comprensión del curso ......................... 60
Gráfico 7. Opinión de usuarios acerca de la dificultad del curso ................................ 60
Gráfico 8. Opinión de usuarios sobre su conocimiento de TDD antes del curso ........ 60
Gráfico 9. Opinión de usuarios sobre su conocimiento de TDD después del curso .... 61
Gráfico 10. Opinión de usuarios acerca de su interés en TDD ................................... 61
Gráfico 11. Opinión de usuarios sobre usar TDD en el futuro .................................... 61
Gráfico 12. Opinión de usuarios sobre un curso avanzado de TDD ........................... 62
Gráfico 13. Calificación de usuarios a TDD School .................................................... 62
xii
RESUMEN
SISTEMA DE CAPACITACIÓN VIRTUAL PARA LA IMPLEMENTACIÓN DE LA
METODOLOGÍA DE DESARROLLO DE SOFTWARE TEST DRIVEN
DEVELOPMENT
Autor: David Vladimir Castro Cruz
Tutor: Aldrin Ismael Flores Suarez
Test-Driven Development (TDD) es una metodología de desarrollo de software que ha
sido utilizada alrededor del mundo por varios años. Consiste básicamente en escribir
pruebas unitarias antes que escribir código fuente y refactorizar el código.
Se elaboró un sistema web de uso gratuito, con el propósito de enseñar esta
metodología a través de un curso virtual en línea interactivo para facilitar el aprendizaje
de la misma. En este curso de capacitación, se muestran lecciones en video, y después
de ellas, se presentan preguntas y ejercicios relacionadas con el contenido de la lección.
Después de la publicación en línea del sistema titulado TDD School, se recopilaron
datos del mismo y también la opinión usuarios que completaron una encuesta, esa
información se usó para determinar el correcto desempeño del sistema y verificar que
el curso de capacitación en verdad logra sembrar un interés por la metodología TDD, y
además enseñar satisfactoriamente los conceptos y modo de utilización de la misma.
PALABRAS CLAVES: DESARROLLO GUIADO POR PRUEBAS / METODOLOGÍAS
DE DESARROLLO DE SOFTWARE / PRUEBAS UNITARIAS / REFACTORIZAR
CÓDIGO / SISTEMA DE CAPACITACIÓN / EDUCACIÓN VIRTUAL
xiii
ABSTRACT
VIRTUAL TRAINING SYSTEM FOR THE IMPLEMENTATION OF TEST DRIVEN
DEVELOPMENT METHODOLOGY
Author: David Vladimir Castro Cruz
Tutor: Aldrin Ismael Flores Suarez
Test-Driven Development (TDD) is a software development methodology that has been
used around the world for several years. It basically consists in writing unit tests prior to
code implementation, and code refactoring.
A free web application was developed, with the purpose of teaching this methodology
through an interactive virtual course to ease the learning of it. In this training course,
video lessons are shown and after that, questions and excercies related to the lesson
are presented.
After the application named TDD School was published online, data was gathered and
also feedback from users who filled out a survey, that information was used to determine
proper application performance and to verify that the training course is capable of
planting an interest in TDD methodology, and teaching the concepts and usage of it.
KEYWORDS: TEST DRIVEN DEVELOPMENT / SOFTWARE DEVELOPMENT
METHODOLOGIES / UNIT TESTS / CODE REFACTORING / TRAINING COURSE /
E-LEARNING
I certify that the above and foregoing is a true and correct translation of the original
document in spanish.
Valeria Coral Torres
IELTS Certified: 15CO009598CORV001A
IC: 1723207237
1
INTRODUCCIÓN
Los modelos de desarrollo de software comúnmente utilizados en la actualidad, si bien
son más simples y fáciles de implementar, presentan deficiencias que aumentan la
probabilidad de fracaso de un proyecto o le restan valor al mismo. Si se toma por ejemplo
el clásico modelo en cascada, que consiste en las fases secuenciales de: análisis de
requerimientos, diseño del sistema, codificación, pruebas y mantenimiento, se pueden
mencionar algunos problemas como: es difícil cumplir un modelo secuencial sin tener
que realizar una iteración que cree un inconveniente, no se puede iniciar una fase hasta
terminar la anterior, para un cliente es difícil establecer todos los requerimientos
claramente al inicio, no se puede generar una versión previa de un sistema sino hasta
la etapa final del desarrollo, un error puede pasar sin ser detectado hasta cuando el
sistema ya se encuentre en funcionamiento, etc… (Blé, C, 2010)
La etapa de pruebas del desarrollo, también conocida como aseguramiento de la calidad
(QA), es una de las más afectadas negativamente cuando se utiliza una metodología
tradicional como el modelo en cascada en donde generalmente se designa a un equipo
de personas para que ejecuten manualmente el sistema un sin número de veces en
busca de errores.
Debido a las frustraciones y fracasos causados por las metodologías tradicionales se
han diseñado otros modelos a seguir, estos modelos llamados Metodologías Agiles de
Desarrollo de Software adquieren cada vez más presencia en el mundo y sus propósitos
son considerablemente amplios, existiendo metodologías para la organización de
equipos de trabajo, gestión de proyectos, técnicas para codificación y mantenimiento de
software, etc… (Blé, C, 2010)
Este trabajo presenta la metodología de desarrollo de software Test-Driven
Development, en forma de un curso virtual en línea interactivo con el propósito de
hacerla más fácil de asimilar por desarrolladores no familiarizados con el agilismo. TDD
se encuentra incluida dentro de la metodología ágil XP (Xtreme Programming) y
básicamente consiste en dos practicas: escribir las pruebas antes que escribir el código
fuente y refactorizar el código.
El objetivo general de este proyecto es diseñar y elaborar un curso de capacitación
virtual acerca de la metodología Test-Driven Development.
Los objetivos específicos son:
2
analizar y entender el funcionamiento de la metodología TDD
diseñar un curso de capacitación con el propósito de enseñar TDD de una manera
interactiva y fácil de entender
elaborar un sistema informático que presente el curso diseñado anteriormente y que
guarde el progreso de los usuarios en el mismo
publicar el sistema en línea y probar su funcionamiento con usuarios que estén
involucrados en el mundo del desarrollo de software.
El curso de capacitación está principalmente compuesto por lecciones en video,
preguntas de opción múltiple y ejercicios que requieren escribir fragmentos de código.
Está pensado de tal manera que cualquier persona que esté involucrada en el mundo
del desarrollo de software y que tenga conocimientos básicos de programación pueda
tomarlo sin dificultades, ya que abarca solamente la introducción a la metodología Test
Driven Development, es decir lo suficiente para comenzar a utilizarla apropiadamente.
El sistema propuesto permite que los usuarios se registren en el mismo y sigan el curso
virtual en línea en las sesiones que ellos deseen, ya que el progreso se guardará y no
hay ninguna restricción de tiempo para terminar el curso. Sin embargo, el sistema no
cuenta con ningún control para hacer que un usuario deba completar el 100% del curso
de capacitación, es decir que un usuario que empieza el curso, no está obligado a
finalizarlo si así lo desea.
3
1. MARCO TEÓRICO
1.1. Antecedentes
La metodología Test-Driven Development ha sido utilizada esporádicamente por
décadas y son muchos los beneficios que se le atribuyen, incluyendo: reducir el tiempo
de pruebas, escribir código altamente reutilizable, evitar funciones repetidas, entre otros.
Sin embargo, no existe mucha evidencia empírica que soporte o refute la utilidad de esta
metodología en el mundo empresarial.
En el año 2008, un grupo conformado por: Nachiappan Nagappan, E. Michael
Maximilien, Thirumalesh Bhat y Laurie Williams realizó un estudio con tres equipos de
desarrollo en Microsoft y uno en IBM, los cuatro equipos adoptaron TDD como su
metodología de trabajo. Los resultados del estudio indicaron que la cantidad de defectos
pre-lanzamiento de los cuatro proyectos realizados se redujo entre un 40% y 90%, pero
que el tiempo que tomó realizar los proyectos sufrió un incremente de entre 15% y 35%.
En el año 2003, Boby George y Laurie Williams realizaron un experimento estructurado
incluyendo a 24 programadores profesionales para investigar la eficacia de TDD. Los
programadores se dividieron en dos grupos, uno de ellos desarrolló una pequeña
aplicación en Java usando TDD y el otro grupo de control desarrolló la misma aplicación
utilizando el modelo cascada. Los resultados indicaron que los programadores usando
TDD pasaron un 18% más pruebas de caja negra, pero consumieron un 16% más
tiempo, cabe recalcar que el grupo de control no escribió pruebas para todo su código.
Otros estudios sobre TDD han sido realizados por profesionales en el área de la
informática y algunas de sus conclusiones son las siguientes: TDD mejora la
productividad de los programadores pero no la calidad del software, la efectividad de
TDD depende de la dedicación de los programadores en seguirla, TDD aumenta
enormemente la confianza que los desarrolladores tienen en su código, TDD mejora
factores de programación como la descomposición del código y cobertura de pruebas,
de igual manera que factores humanos como la productividad y la confianza.
Una indagación con el motor de búsqueda google.com revela la existencia de una
moderada cantidad de cursos de capacitación de TDD en el mercado, las ofertas en su
mayoría consisten en cursos presenciales pagados que no duran más de 20 horas, y
otras consisten solamente en la venta de videos. Sin embargo, hasta la fecha presente
4
no existe ningún curso en línea que cuente con todas las características propuestas
para TDD School como son: gratuidad, registro de usuarios, contenido disponible en
línea 24/7, lecciones en video, preguntas y ejercicios incluidos dentro del sistema,
facilidad de seguir el curso de capacitación en varias sesiones sin pérdida del progreso.
Además, al investigar los repositorios digitales de varias Universidades del Ecuador,
incluyendo la Universidad Central del Ecuador, Universidad Andina Simón Bolívar,
Universidad Internacional del Ecuador, Universidad de las Américas, Universidad
Técnica de Ambato, Universidad de Cuenca, Universidad Técnica de Cotopaxi,
Universidad Técnica del Norte, Universidad del Pacifico, Pontifica Universidad Católica
del Ecuador, Escuela Politécnica Nacional, Universidad San Francisco de Quito, y
Universidad Politécnica Salesiana, se obtuvo que ninguna cuenta con un trabajo
relacionado con la elaboración de un curso de capacitación de la metodología Test
Driven Development.
1.2. Fundamentación Teórica
1.2.1. Sistema Web
Los sistemas web también conocidos como aplicaciones web reciben este nombre
porque se ejecutan en la internet. Es decir que los datos o los archivos en los que se
trabaja son procesados y almacenados dentro de la web. Estas aplicaciones, por lo
general, no necesitan ser instaladas en tu computador y se accede a ellas mediante un
navegador.
Las aplicaciones web son populares debido a lo práctico del navegador web como
cliente ligero, a la independencia del sistema operativo, así como a la facilidad para
actualizar y mantener aplicaciones web sin distribuir e instalar software a miles de
usuarios potenciales.
Es importante mencionar que una página Web puede contener elementos que permiten
una comunicación activa entre el usuario y la información. Esto permite que el usuario
acceda a los datos de modo interactivo, gracias a que la página responderá a cada una
de sus acciones, como por ejemplo rellenar y enviar formularios, participar en juegos
diversos y acceder a gestores de base de datos de todo tipo.
(Fraktalweb, 2016)
5
1.2.2. HyperText Markup Language (HTML)
HyperText Markup Language o Lenguaje de Marcas de Hipertexto, hace referencia al
lenguaje de marcado para la elaboración de páginas web. Es un estándar que sirve de
referencia del software que conecta con la elaboración de páginas web en sus diferentes
versiones, define una estructura básica y un código (denominado código HTML) para la
definición de contenido de una página web, como texto, imágenes, videos, juegos, entre
otros. Es un estándar a cargo del World Wide Web Consortium (W3C) o Consorcio
WWW, organización dedicada a la estandarización de casi todas las tecnologías ligadas
a la web, sobre todo en lo referente a su escritura e interpretación.
El lenguaje HTML basa su filosofía de desarrollo en la diferenciación. Para añadir un
elemento externo a la página (imagen, vídeo, script, entre otros.), este no se incrusta
directamente en el código de la página, sino que se hace una referencia a la ubicación
de dicho elemento mediante texto. De este modo, la página web contiene solamente
texto mientras que recae en el navegador web (interpretador del código) la tarea de unir
todos los elementos y visualizar la página final. Al ser un estándar, HTML busca ser un
lenguaje que permita que cualquier página web escrita en una determinada versión,
pueda ser interpretada de la misma forma (estándar) por cualquier navegador web
actualizado.
A lo largo de sus diferentes versiones, se han incorporado y suprimido diversas
características, con el fin de hacerlo más eficiente y facilitar el desarrollo de páginas web
compatibles con distintos navegadores y plataformas (PC de escritorio, portátiles,
teléfonos inteligentes, tabletas, etc.). Para interpretar correctamente una nueva versión
de HTML, los desarrolladores de navegadores web deben incorporar estos cambios y el
usuario debe ser capaz de usar la nueva versión del navegador con los cambios
incorporados.
(definicionabc, 2016)
1.2.3. Javascript (JS)
Javascript es un lenguaje de programación interpretado que surgió con el objetivo inicial
de programar ciertos comportamientos sobre las páginas web, respondiendo a la
interacción del usuario y la realización de automatismos sencillos. En ese contexto
podríamos decir que nació como un "lenguaje de scripting" del lado del cliente, sin
embargo, hoy Javascript es mucho más. En los últimos años Javascript se está
6
convirtiendo también en el lenguaje "integrador". Lo encontramos en muchos ámbitos,
ya no solo en Internet y la Web, también es nativo en sistemas operativos para
ordenadores y dispositivos, del lado del servidor y del cliente. Aquella visión de
Javascript "utilizado para crear pequeños programitas encargados de realizar acciones
dentro del ámbito de una página web" se ha quedado muy pequeña.
Todos los navegadores modernos interpretan el código JavaScript integrado en las
páginas web. Para interactuar con una página web se provee al lenguaje JavaScript de
una implementación del Document Object Model (DOM).
(efectosjavascript, 2016)
1.2.4. Cascading Style Sheets (CSS)
Las Hojas de Estilo en Cascada (Cascading Style Sheets), son un mecanismo simple
que describe cómo se va a mostrar un documento en la pantalla, o cómo se va a
imprimir, o incluso cómo va a ser pronunciada la información presente en ese
documento a través de un dispositivo de lectura. Esta forma de descripción de estilos
ofrece a los desarrolladores el control total sobre estilo y formato de sus documentos.
CSS se utiliza para dar estilo a documentos HTML y XML, separando el contenido de la
presentación. Los Estilos definen la forma de mostrar los elementos HTML y XML. CSS
permite a los desarrolladores Web controlar el estilo y el formato de múltiples páginas
Web al mismo tiempo. Cualquier cambio en el estilo marcado para un elemento en la
CSS afectará a todas las páginas vinculadas a esa CSS en las que aparezca ese
elemento.
CSS funciona a base de reglas, es decir, declaraciones sobre el estilo de uno o más
elementos. Las hojas de estilo están compuestas por una o más de esas reglas
aplicadas a un documento HTML o XML. La información de estilo puede ser definida en
un documento separado o en el mismo documento HTML.
Junto con HTML y Javascript, CSS es una piedra angular utilizada por la mayoría de
sitios web para crear paginas e interfaces de usuarios visualmente atractivas e
interesantes para los usuarios.
(librosweb, 2016)
7
1.2.5. Capacitación
La capacitación es el conjunto de medios que se organizan de acuerdo a un plan, para
lograr que un individuo adquiera destrezas, valores o conocimientos teóricos, que le
permitan realizar ciertas tareas o desempeñarse en algún ámbito específico, con mayor
eficacia. Se requiere la existencia de un potencial que se trata de transformar en acto.
(deconceptos, 2016)
1.2.6. e-Learning (Educación virtual)
El e-learning consiste en la educación y capacitación a través de Internet. Este tipo de
enseñanza online permite la interacción del usuario con el material mediante la
utilización de diversas herramientas informáticas. El término "e-learning" es la
simplificación de Electronic Learning. El mismo reúne a las diferentes tecnologías, y a
los aspectos pedagógicos de la enseñanza y el aprendizaje.
Los beneficios del e-learning son:
Reducción de costos: permite reducir y hasta eliminar gastos de traslado,
alojamiento, material didáctico, etc
Rapidez y agilidad: Las comunicaciones a través de sistemas en la red confiere
rapidez y agilidad a las comunicaciones
Acceso just-in-time: los usuarios pueden acceder al contenido desde cualquier
conexión a Internet, cuando les surge la necesidad
Flexibilidad de la agenda: no se requiere que un grupo de personas coincidan en
tiempo y espacio
(abclearning, 2016)
1.2.7. Test-Driven Development
A pesar de su nombre, TDD (Test-Driven Development) no es una técnica de testing,
sino una metodología de diseño e implementación de software que se encuentra incluida
dentro de la metodología XP (Xtreme Programming). Involucra dos prácticas: Escribir
las pruebas antes que escribir el código fuente, y Refactorizar el código. Uno de sus
resultados es un conjunto de pruebas unitarias, pero esas pruebas son un efecto
secundario, no el objetivo principal. Practicar TDD se trata más acerca de establecer un
patrón de comportamiento para diseñar y programar más que realizar pruebas.
8
TDD también es conocido como: Test-First Design, Test-First Programming y Test
Driven-Design. En español TDD se traduce a Desarrollo Guiado por Pruebas.
En otras metodologías de desarrollo de software, generalmente primero se piensa en
definir la arquitectura, clases, objetos, interfaces, eventos, etc... En TDD se deja que la
implementación de pequeños ejemplos, en constantes iteraciones, haga surgir la
arquitectura que se requiere usar. Esto no significa que se debe dejar a un lado por
completo las características técnicas de la aplicación como la plataforma donde se la va
a utilizar, la concurrencia de usuarios o requerimientos específicos.
Los pilares fundamentales en los que se centra TDD son:
Implementación de las funciones justas que se necesitan y no más.
Minimización del número de defectos que llegan al software en fase de producción.
La producción de software modular, altamente reutilizable y preparado para el
cambio.
En el libro Test Driven Development: By Example de Kent Beck (uno de los padres de
la metodología) se mencionan varias ventajas sobre TDD y porque resulta beneficioso
convertirla en una herramienta habitual para desarrollar software. Estas son algunas de
las ventajas que se encuentran en el libro además de algunas que se derivan
directamente de los pilares de TDD:
Código altamente reutilizable.
El trabajo en equipo se hace más comprensible.
Multiplica la comunicación entre los miembros del equipo.
Las personas encargadas de la garantía de calidad adquieren un rol más inteligente
e interesante.
Escribir el ejemplo (test) antes que el código nos obliga a escribir el mínimo de
funcionalidad necesaria, evitando sobrediseñar.
Incrementa la productividad.
Nos hace descubrir y afrontar más casos de uso en tiempo de diseño.
Las pruebas hechas para cada método del sistema pueden utilizarse como
documentación para su entendimiento.
Uno se marcha a casa con la reconfortante sensación de que el trabajo está bien
hecho.
(Gałęzowski, G., 2015)
9
En contraste se pueden describir algunas de las desventajas de la metodología Test
Driven Development:
Los ciclos extremadamente cortos y el cambio entre pruebas y codificación de
producción hacen que muchos programadores lo sientan como contrario a su
intuición y desgastante. Exige además disciplina, responsabilidad y coraje.
La imposibilidad de adopción cuando se utilizan lenguajes de programación que no
cuentan con el marco de pruebas unitarias, o cuando se utilizan herramientas de
alto nivel para la generación de código y asistencia al desarrollo que no lo integran.
Si bien esto puede resolverse en muchos casos con desarrollo propio, no siempre
es posible por problemas de costo y tiempo.
Las dificultades o imposibilidad para su adopción cuando se utilizan herramientas
de alto nivel para la asistencia al desarrollo o lenguajes de programación que no
adhieren al paradigma de la orientación a objetos.
En las pruebas de aceptación, donde es más dificultosa la automatización, pues la
prueba puede ser asimilada a un ciclo funcional, lo que acrecienta la complejidad de
los casos, con alta probabilidad de intervención de interfaces gráficas (GUI), desde
las cuales la aplicación interactúa con el usuario.
(Araújo, A, 2007)
La metodología TDD se basa en la repetición de un ciclo de desarrollo muy corto.
Primero el desarrollador escribe una prueba diseñada para resultar fallida, después se
escribe el código mínimo que hace que la prueba pase satisfactoriamente y
posteriormente se refactoriza el código. La secuencia usual del ciclo es:
1. Escribir una prueba unitaria: se escribe una prueba específica para un requisito o
funcionalidad del sistema, el programador debe conocer a la perfección las
especificaciones de la funcionalidad que esta por implementar para hacer esto
2. Ejecutar la prueba y verificar si falla: se valida que la prueba no pase por error sin
haber escrito nuevo código, si la prueba pasa es porque esta incorrecta o porque el
requisito ya existe
3. Escribir código fuente: se escribe el código mínimo para que la prueba unitaria pase,
en este punto no es necesario que el código escrito este perfectamente optimizado
y no se deben considerar otros requisitos
4. Ejecutar todas las pruebas: se verifica que todas las pruebas pasen, si no lo hacen
se debe corregir el código hasta que todo sea satisfactorio, las pruebas en este paso
deberían ser automatizadas
5. Refactorizar el código: el código que se escribió anteriormente debe ser limpiado y
ubicado correctamente donde pertenezca según el sistema que se está
10
desarrollando y su arquitectura, el código duplicado debe ser eliminado, para
mejorar este paso se recomienda utilizar patrones de diseño
6. Repetir: se empieza nuevamente con otra prueba unitaria y el proceso se repite, en
el paso 4 se deben ejecutar todas las pruebas que se hayan creado para verificar
que el nuevo código no perjudique el ya escrito anteriormente
(Gałęzowski, G., 2015)
1.2.8. Pruebas unitarias
Una prueba unitaria o “unit test” es un procedimiento que prueba una unidad estructural
de código, generalmente una función o un método. Buscan aislar cada parte del sistema
y mostrar que las partes individuales son correctas.
Una prueba unitaria diseñada correctamente debería tener las siguientes
características:
Unitaria: Prueba solamente pequeñas cantidades de código
Independiente: No debe depender ni afectar a otras pruebas unitarias
Automatizable: La prueba debería poder correr sin intervención manual
Repetible y predecible: Sin importar el orden y las veces que se ejecute la prueba,
el resultado siempre debe ser el mismo
Simple: El desarrollo de una prueba unitaria no debería tardar más de cinco minutos
Rápida: Si una prueba no se ejecuta rápido, no se la ejecuta
Informativa: Una prueba unitaria debería poder utilizarse para comprender mejor el
código que se está probando
Se debe considerar que, por estar orientadas a pruebas de fragmentos de código
aislados, las pruebas unitarias por si solas no descubrirán errores de integración,
problemas de rendimiento y otros problemas que afectan a todo el sistema en su
conjunto. Si la utilización de pruebas unitarias no se incorpora como parte de la
metodología de trabajo, probablemente el código quedará fuera de sincronismo con los
casos de prueba.
(Hartjes, C., 2014)
11
2. METODOLOGÍA
2.1. Marco Metodológico
Para elaborar este trabajo se eligió la Metodología Investigación-Acción. La
investigación-acción es un enfoque, un proceso que busca la interpretación de un
aspecto social a través del uso de la investigación activa, con la intención de provocar
un cambio positivo de orden social, en donde se involucra la toma de decisiones. Esta
definición implica que la investigación-acción obliga a combinar la teoría con la práctica,
así como también se hace necesario el uso de la observación, participación,
planificación y la reflexión. Esta metodología consta de cinco pasos:
1. Diagnóstico: Investigación del Estado del arte, análisis de las buenas prácticas,
técnicas, herramientas y formalismos existentes. Además, el diseño de la propuesta.
2. Planificación de la acción: Determinación de los ajustes y pasos necesarios para
implementar la propuesta metodológica con el caso de estudio.
3. Tomar la acción: Se debe aplicar la propuesta en el proyecto.
4. Evaluación: Se debe evaluar la propuesta con los entregables alcanzados y se
refinará la misma para obtener la primera versión.
5. Especificación del aprendizaje: Se establecerán las conclusiones de acuerdo a los
resultados.
(Hernández, R., Fernández, C. & Baptista, p., 1997)
2.2. Evaluación de la situación
La metodología TDD es una práctica bien conocida en el mundo del desarrollo de
software, sin embargo, la mayoría de personas no saben de su existencia o solo han
escuchado acerca de ella y no saben cómo aplicarla correctamente. A pesar de las
deficiencias con las que cuentan las metodologías tradicionales de desarrollo y las
ventajas que proporcionan las metodologías ágiles, el uso de técnicas tradicionales es
superior a la de técnicas agiles.
Las razones para que suceda esto pueden incluir: la facilidad de implementación de
métodos comunes, falta de conocimiento de otras técnicas, escasa participación de los
12
usuarios, falta de capacitación y soporte, falta de recursos, incompetencia tecnológica,
etc.
Es necesario contribuir al crecimiento de la utilización de metodologías agiles en el
mundo del desarrollo de software y una manera de hacerlo es a través del e-learning.
El e-learning brinda una educación en línea, virtual, dando facilidad de horarios y
accesibilidad a cualquier persona que tenga un computador y una conexión a internet.
La capacitación a través de e-learning además posee ventajas como constante
actualización, reducción del tiempo de aprendizaje, utilización de material multimedia,
reducción de costos, etc.
(Blé, C, 2010)
2.2.1. Análisis FODA del proyecto
Figura 1. Distribución de factores del análisis FODA Fuente: Autoría propia
FORTALEZAS
Acceso a recursos informativos de la metodología TDD
Habilidad y capacidad total para desarrollar el sistema
Costo de elaboración extremadamente bajo
Flexibilidad de requerimientos
FACTORES POSITIVOS
FACTORES INTERNOS
FACTORES EXTERNOS
FACTORES NEGATIVOS
FORTALEZAS
OP
OR
TUN
IDA
DES
D
EBIL
IDA
DES
AMENAZAS
13
Posibilidad de actualizaciones futuras
DEBILIDADES
Proyecto no rentable
Personal y recursos insuficientes en caso de crecimiento del proyecto
No hay una gestión estratégica clara
OPORTUNIDADES
Baja oferta en cursos virtuales de metodología TDD
Crecimiento rápido de las metodologías agiles de desarrollo de software
Enfocado a grupos que nunca tendrán dificultad para utilizar el sistema
AMENAZAS
Poca evidencia que soporte los beneficios de la metodología TDD
Existencia de varios sistemas de e-learning con otros propósitos
Cambios en las preferencias de metodologías de desarrollo de software
Aumento de costos para mantener el sistema
No se sabe si el sistema será aceptado favorablemente
Tabla 1. Análisis FODA Fuente: Autoría propia
2.2.2. Análisis de Riesgos
a) Identificación de riesgos
La tabla a continuación muestra los riesgos que amenazan a la aplicación. Por
probabilidad se entiende la posibilidad de ocurrencia del riesgo. Por impacto se
entiende el resultado de un evento que afecta los objetivos. (serviciocivil, 2014)
Tipo Nombre del Riesgo Probabilidad Impacto
Rie
sgo
s d
e p
lanific
ació
n Conceptos incorrectos sobre la
metodología TDD Baja Alto
El sistema no cumple su objetivo de enseñar TDD
Baja Alto
Tiempo de desarrollo sobre excedido Media Medio
Incompatibilidad de herramientas de desarrollo
Baja Medio
Incompatibilidad del sistema con el servidor
Media Bajo
Rie
sgo
s
técnic
os
Error en el diseño de base de datos Baja Alto
Error en el código de la aplicación Media Medio
Error en el diseño de interfaces Baja Bajo
Exceder la capacidad del servidor Alta Medio
Hackeo del sistema Media Alto
14
El sistema deja de funcionar inesperadamente
Baja Medio
Rie
sgo
s d
e
neg
ocio
Usuarios no entienden cómo utilizar el sistema
Alta Bajo
El sistema no es del agrado de los usuarios
Baja Alto
Mala difusión del sistema Media Medio
Tabla 2. Tabla de riesgos
Fuente: Autoría propia
Para establecer los valores de probabilidad e impacto se utilizan las siguientes tablas
informativas:
Valor Nivel Descriptor Descripción
1 Baja Muy improbable El evento puede ocurrir solo en circunstancias excepcionales
2 Media Posible El evento podría ocurrir en algún momento
3 Alta Casi seguro Se espera que el evento ocurra en la mayoría de las circunstancias
Tabla 3. Tabla de determinación de probabilidades
Fuente: serviciocivil.gov.co
Valor Nivel Descriptor Descripción
1 Bajo Insignificante Si el hecho llegara a presentarse, tendría consecuencias o efectos mínimos
2 Medio Moderado Si el hecho llegara a presentarse, tendría medianas consecuencias o efectos
3 Alto Catastrófico Si el hecho llegara a presentarse, tendría desastrosas consecuencias o efectos
Tabla 4. Tabla de determinación de impacto
Fuente: serviciocivil.gov.co
b) Riesgo inicial
Para establecer la valoración de riesgo inicial se utiliza la siguiente matriz:
Impacto
Probabilidad Bajo (1) Medio (2) Alto (3)
Baja (1) 1 2 3
Media (2) 2 4 6
Alta (3) 3 6 9
Tabla 5. Matriz de calificación y evaluación de riesgos
Fuente: serviciocivil.gov.co
15
Bajo riesgo: 1 – 2 (verde)
Medio riesgo: 3 – 6 (amarillo)
Alto riesgo: 7 – 9 (rojo)
A partir de esto se obtiene el riesgo inicial:
Nombre del Riesgo Probabilidad Impacto Calificación Riesgo
Conceptos incorrectos sobre la metodología TDD
1 3 3 Medio
El sistema no cumple su objetivo de enseñar TDD
1 3 3 Medio
Tiempo de desarrollo sobre excedido
2 2 4 Medio
Incompatibilidad de herramientas de desarrollo
1 2 2 Bajo
Incompatibilidad del sistema con el servidor
2 1 2 Bajo
Error en el diseño de base de datos
1 3 3 Medio
Error en el código de la aplicación
2 2 4 Medio
Error en el diseño de interfaces
1 1 1 Bajo
Exceder la capacidad del servidor
3 2 6 Alto
Hackeo del sistema 2 3 6 Alto
El sistema deja de funcionar inesperadamente
1 2 2 Bajo
Usuarios no entienden cómo utilizar el sistema
3 1 3 Medio
El sistema no es del agrado de los usuarios
1 3 3 Medio
Mala difusión del sistema
2 2 4 Medio
Tabla 6. Riesgo inicial Fuente: Autoría propia
c) Mitigación de riesgos
Conceptos incorrectos sobre la metodología TDD
16
Estudiar cuidadosamente la documentación existente sobre la metodología, revisar
publicaciones oficiales y no de fuentes anónimas de internet. Tomar el tiempo que
sea necesario para entender la metodología a la perfección y ser capaz de aplicarla
en proyectos de distintas escalas.
El sistema no cumple su objetivo de enseñar TDD
Hacer el curso interactivo, más comprensible, tomar en cuenta que no todos los
usuarios son expertos, incluir ejemplos no relacionados con programación, y ofrecer
consejos para facilitar el entendimiento en caso de que un usuario se encuentre
atascado en algún punto del curso.
Tiempo de desarrollo sobre excedido
Estimar la duración del periodo de desarrollo del proyecto tomando en cuenta
inconvenientes que podrían surgir y añadir un tiempo de holgura a ese lapso.
Incompatibilidad de herramientas de desarrollo
Antes de empezar a programar, hacer una prueba con las herramientas y librerías
elegidas para comprobar si son compatibles, en caso de no serlo seleccionar otras
que si lo sean.
Incompatibilidad del sistema con el servidor
A menos que se tenga un servidor propio no hay mucho que se pueda hacer para
mitigar este riesgo, la única solución en este caso es elegir otro servidor, lo cual no
es ningún problema.
Error en el diseño de base de datos
Aplicar estándares de diseño de modelos de bases de datos, tomar en cuenta todas
las entidades que conforman el sistema y como se relacionan, no olvidar la
capacidad que podría alcanzar el sistema en un futuro.
Error en el código de la aplicación
Utilizar metodólogas agiles de desarrollo como la propuesta en este trabajo: Test-
Driven Development. Tener un entorno de desarrollo en el cual se verificará que todo
funcione perfectamente antes de publicar el sistema en producción.
Error en el diseño de interfaces
17
Comprobar cómo se ven las interfaces en distintos dispositivos con varios tamaños
de pantallas y diferentes navegadores para verificar que todo se muestra
correctamente.
Exceder la capacidad del servidor
En la mayoría de los casos la capacidad del servidor está definida previamente
según el paquete contratado, pero en caso de no contar con esta información se
debe realizar pruebas de estrés y pruebas de carga para determinar la capacidad
máxima que soporta el servidor y decidir si el servicio ofrecido es lo más indicado
para el funcionamiento del sistema.
Hackeo del sistema
Desarrollar el sistema con algún framework que incluya seguridades contra ataques.
Verificar si alguna de las herramientas a utilizar tiene alguna vulnerabilidad y si existe
como solucionarla. Verificar si el entorno donde va a funcionar el sistema tiene
protecciones contra hackeos. Existen herramientas que sirven para comprobar el
estado de protección que tiene un sistema ante un ataque informático, en caso de
no poder utilizar estas herramientas, hacer pruebas personalmente. Realizar
backups cada cierto tiempo para no perder mucha información en caso de no poder
evitar un hackeo.
El sistema deja de funcionar inesperadamente
Crear tareas programadas para realizar backups del sistema y de la base de datos
automáticamente, estos backups deberían almacenarse en una ubicación distinta y
no en el mismo servidor donde se encuentra el sistema en producción. Utilizar un
sistema de revisión de control del código del sistema para poder volver a una versión
anterior en caso de que un cambio reciente hay sido el responsable de la caída del
sistema. Programar las operaciones de base de datos con transacciones para no
dejar procesos de cambios a medias. De ser posible utilizar un servidor auxiliar para
que entre en funcionamiento cuando el otro falle.
Usuarios no entienden cómo utilizar el sistema
Agregar textos de ayuda en los elementos de control del sistema para que los
usuarios sepan que hacer. Agregar una sección de ayuda para preguntas frecuentes
acerca del uso del sistema. Diseñar las interfaces de la aplicación de una manera
simple, con pocos elementos de control, pero bien diferenciados. Utilizar elementos
multimedia siempre que sea posible. Agregar una opción para que los usuarios
puedan dar su opinión acerca del sistema y como podría mejorar.
18
El sistema no es del agrado de los usuarios
Analizar detalladamente cada uno de los aspectos de negocio del sistema, es decir:
propósito, población objetivo, oferta y demanda de la propuesta, competencia,
costos, etc. Y también otros aspectos relevantes como: diseño, disponibilidad,
seguridad, etc. Determinar entre todos estos aspectos cual puede provocar que la
aplicación no sea aceptada entre los usuarios y por tanto resulte en un fracaso. De
ser necesario buscar ayuda profesional para atacar los aspectos preocupantes del
sistema.
Mala difusión del sistema
Este riesgo está relacionado con el anterior, si el sistema es del agrado de los
usuarios, ellos lo compartirán con sus conocidos ayudando a su difusión. Además,
se puede utilizar publicidad a través de redes sociales y si el presupuesto lo permite
otros medios pagados.
d) Riesgo final o inherente
La siguiente tabla muestra el riesgo final o inherente después de tomar en cuenta los
mitigadores descritos anteriormente:
Nombre del Riesgo Riesgo inicial Mitigador Riesgo final
Conceptos incorrectos sobre la metodología TDD
Medio Estudiar mejor la
metodología Bajo
El sistema no cumple su objetivo de enseñar TDD
Medio Curso más
comprensible Bajo
Tiempo de desarrollo sobre excedido
Medio Considerar
inconvenientes Bajo
Incompatibilidad de herramientas de desarrollo
Bajo Verificar compatibilidad Bajo
Incompatibilidad del sistema con el servidor
Bajo Elegir otro servidor Bajo
Error en el diseño de base de datos
Medio Diseñar con estándares Bajo
Error en el código de la aplicación
Medio Verificar antes de
publicar Bajo
Error en el diseño de interfaces
Bajo Probar distintos
dispositivos Bajo
Exceder la capacidad del servidor
Alto Pruebas de estrés y
carga Medio
Hackeo del sistema Alto Herramientas para
protección Medio
19
El sistema deja de funcionar inesperadamente
Bajo Backups de datos y
código Bajo
Usuarios no entienden cómo utilizar el sistema
Medio Interfaces sencillas Bajo
El sistema no es del agrado de los usuarios
Medio Análisis integral del
sistema Medio
Mala difusión del sistema Medio Conseguir publicidad Bajo
Tabla 7. Riesgo final o inherente
Fuente: Autoría propia
2.3. Desarrollo del proyecto
La aplicación a desarrollarse lleva el nombre de “TDD School” debido a su propósito de
enseñar Test-Driven Development a usuarios involucrados en el mundo del desarrollo
de software.
2.3.1. Especificación de requerimientos
Diseñar un curso interactivo para enseñar la metodología Test-Driven Development
Dividir el curso en partes y sub-partes
Elaborar un sistema informático que contenga el curso de capacitación de TDD
Permitir el registro de usuarios en el sistema
Los usuarios pueden guardar su progreso en el curso para no tener que completarlo
en una sola sesión
Utilizar audio y video para facilitar la enseñanza
El sistema debe ser fácil de acceder y usar para que cualquier usuario con un
computador, celular o tablet y acceso a internet pueda ingresar al mismo
Evaluar al usuario mientras avanza en cada capítulo del curso
Verificar si las respuestas dadas del usuario son correctas
A un usuario solo se le permite avanzar de sección al aprobar las preguntas y
ejercicios de la misma
Al final del curso recomendar a los usuarios como aprender más sobre TDD
Realizar una encuesta a los usuarios sobre su experiencia en la aplicación
20
2.3.2. Plan de clase
Tema Introducción a Test Driven Development.
Meta instruccional
Enseñar a los usuarios a elaborar pruebas unitarias, y que a partir de ellas puedan escribir código fuente, siguiendo el principio de la metodología TDD.
Contenido
Capítulo 1. Introducción a Test Driven Development
o Subcapítulo 1.1. ¿Qué es TDD?
Video de duración: 3 minutos y 26 segundos
4 preguntas
Capítulo 2. Pruebas Unitarias
o Subcapítulo 2.1. ¿Qué son las pruebas unitarias?
Video de duración: 2 minutos y 40 segundos
3 preguntas
1 ejercicio
o Subcapítulo 2.2. Herramientas xUnit y PHPUnit
Video de duración: 8 minutos y 54 segundos
3 preguntas
3 ejercicios
Capítulo 3. ¿Cómo desarrollar con Test Driven Development?
o Subcapítulo 3.1. El algoritmo de TDD
Video de duración: 7 minutos y 13 segundos
4 preguntas
5 ejercicios
o Subcapítulo 3.2. El ciclo Red Green Refactor (RGR)
Video de duración: 4 minutos y 5 segundos
2 preguntas
o Subcapítulo 3.3. La estructura Given-When-Then
Video de duración: 3 minutos y 8 segundos
3 preguntas
Capítulo 4. Practicas con Test Driven Development
o Subcapítulo 4.1. Órdenes y productos
Video de duración: 13 minutos y 40 segundos
1 ejercicio
Alcance del curso
El curso de capacitación muestra una introducción a la metodología TDD con ejemplos y ejercicios simples que solamente requieren el uso y manipulación de datos primitivos (no objetos).
Requisitos Es altamente recomendable que para tomar este curso los usuarios tengan conocimientos de programación en el lenguaje PHP, como: variables, bucles, funciones, clases, herencia y encapsulamiento.
Estrategia didáctica
Presentación de videos con el contenido de la clase, los videos son narrados y pueden tener instrucción teórica o desarrollo de ejemplos prácticos. La ampliación de este punto se encuentra en la sección Estrategia Pedagógica.
Recursos El portal web TDD School, el cual estará ubicado bajo el dominio tddschool.net
21
Estimación del tiempo
El curso tiene una duración aproximada de 120 minutos, tomando en cuenta la reproducción de los video-tutoriales, que en total suman 43 minutos y 10 segundos, y el tiempo que el usuario tarde resolviendo las 19 preguntas y 10 ejercicios.
Evaluación
Preguntas de opción múltiple, y ejercicios que requieren escribir fragmentos de código. Estas evaluaciones no tienen una calificación cuantitativa, sin embargo, deben ser contestadas correctamente para seguir avanzando en el curso de capacitación.
Tabla 8. Plan de clase Fuente: Autoría propia
2.3.3. Estrategia pedagógica
Entendemos por estrategias pedagógicas aquellas acciones que realiza el maestro con
el propósito de facilitar la formación y el aprendizaje de las disciplinas en los estudiantes
(UDEA, 2016). En este caso el maestro es el sistema informático TDD School, las
disciplinas son el contenido del curso de capacitación de TDD y los estudiantes son
todos los usuarios registrados que utilizan el sistema.
La estrategia de TDD School está inspirada en CodeSchool 1 y consiste en presentar un
curso de capacitación virtual de carácter informativo, sin calificaciones, sin
penalizaciones y la única recompensa es el conocimiento que puede adquirirse.
El 100% de las lecciones, las preguntas y los ejercicios del curso de capacitación de
TDD se encontrarán disponibles en el sistema TDD School, esto tiene el propósito de
que los usuarios permanezcan dentro del sistema sin tener la necesidad de buscar
recursos externos y así evitar distracciones o demoras.
En cuanto a las lecciones del curso de capacitación, se utilizarán videos con una
duración máxima de 15 minutos con el fin de no aburrir a los usuarios, acompañados de
narración para comunicar el contenido de las mismas. Cuando las lecciones sean
teóricas, los videos mostrarán un resumen de esa teoría a manera de diapositivas, y
cuando las lecciones sean ejemplos prácticos, los videos mostrarán el desarrollo del
ejemplo en alguna herramienta informática escribiendo y ejecutando el código paso a
paso. Los usuarios no están obligados a ver todos los videos de principio a fin y pueden
adelantarlos o saltarlos por completo si así lo desean, esto tiene el propósito de que los
usuarios pueden visualizar nuevamente un video o solamente una parte de este.
1 Plataforma de aprendizaje en línea (codeschool.com)
22
En cuanto a las evaluaciones, estas se presentarán después de cada lección, estarán
relacionadas directamente con el contenido de la lección previa y pueden ser de dos
tipos: preguntas de opción múltiple y ejercicios que requieres escribir fragmentos de
código, estos ejercicios además de su descripción contarán con pasos a seguir y
consejos para facilitar su resolución. Las evaluaciones no tendrán un puntaje
cuantitativo, es decir sus respuestas solamente tendrán dos estados: correcto o
incorrecto. Una pregunta o ejercicio podrá intentar resolverse ilimitadas veces, y se
guardará un registro del número de intentos que cada usuario realiza en cada una de
ellas. Si una pregunta o ejercicios no está resuelta correctamente, el sistema no
permitirá avanzar al usuario de ese punto en el curso de capacitación.
Una vez que los usuarios lleguen al final del curso, después de haber contestado todas
las preguntas y ejercicios correctamente, se les mostrará la suma total de veces que
intentaron resolverlas todas, este es el único indicador de desempeño que verán los
usuarios ya que el propósito del curso de capacitación no es otorgar una calificación
sino brindar conocimiento. Para revisar todas las preguntas y ejercicios con sus
respectivas respuestas ver el Anexo A.
2.3.4. Contenido del curso de capacitación
El curso de capacitación está divido en cuatro capítulos secuenciales y cada uno
consiste en tres partes: las tutorías que se darán a los usuarios a través de videos, las
preguntas de opción múltiple donde se evaluará la comprensión de la teoría impartida y
los ejercicios en los que los usuarios deben demostrar que son capaces de resolver
problemas relacionados con el tema. Además, al final de la capacitación se incluye una
última sección que no tiene el propósito de instruir o evaluar sino solamente dar una
última reflexión sobre la metodología TDD.
23
Figura 2. Diagrama del contenido del curso de capacitación Fuente: Autoría Propia
A continuación, se detalla el contenido que será impartido a los usuarios.
“Más que el acto de hacer tests, el acto de diseñar tests es uno de los mecanismos
conocidos más efectivos para prevenir errores… El proceso mental que debe
desarrollarse para crear tests útiles puede descubrir y eliminar problemas en todas las
etapas del desarrollo”
Boris Beizer
a) Capítulo 1. Introducción a Test Driven Development
Subcapítulo 1.1. ¿Qué es TDD?
A pesar de su nombre, TDD (Test-Driven Development) no es una técnica de testing,
sino una metodología de diseño e implementación de software que se encuentra incluida
dentro de la metodología XP (Xtreme Programming). Involucra dos prácticas: Escribir
las pruebas antes que escribir el código fuente, y Refactorizar el código. Uno de sus
resultados es un conjunto de pruebas unitarias, pero esas pruebas son un efecto
secundario, no el objetivo principal. Practicar TDD se trata más acerca de establecer un
patrón de comportamiento para diseñar y programar que realizar pruebas.
Los pilares fundamentales en los que se centra TDD son:
Implementación de las funciones justas que se necesitan y no más.
Introducción a Test Driven
Development¿Qué es TDD?
Pruebas Unitarias
¿Qué son Pruebas Unitarias?
xUnit (PHPUnit)
¿Cómo desarrollar con
Test Driven Development?
El algoritmo de TDD
El ciclo Red-Green-Refactor
¿Cómo empezar? La estructura Given-When-
Then
Prácticas con Test Driven
Development
Órdenes y Productos
24
Minimización del número de defectos que llegan al software en fase de producción.
La producción de software modular, altamente reutilizable y preparado para el
cambio.
(Blé, C, 2010)
En otras metodologías de desarrollo de software, generalmente primero se piensa en
definir la arquitectura, objetos, interfaces, eventos, etc... En TDD se deja que la
implementación de pequeños ejemplos, en constantes iteraciones, haga surgir la
arquitectura que se requiere usar. Esto no significa que se debe dejar a un lado por
completo las características técnicas de la aplicación como la plataforma donde se la va
a utilizar, la concurrencia de usuarios u otros requerimientos específicos.
Test-Driven Development también es conocido como: Test-First Design, Test-First
Programming y Test-Driven Design. En español TDD se traduce a Desarrollo Guiado
por Pruebas, pero por su familiaridad con su nombre original en la totalidad de este
curso se lo seguirá refiriendo como TDD (Test-Driven Development).
El redescubrimiento de TDD se le atribuye a Kent Beck, quien también es el creador de
Extreme Programming y JUnit. Se dice que es un redescubrimiento ya que existen
evidencias del uso de un prototipo de TDD en la década de los 60. En esa época el
mecanismo de programación consistía en insertar tarjetas perforadas en los
mainframes, los programadores tenían que estar muy seguros de que su código
funcionaba correctamente ya que solo tenían unas pocas oportunidades de correr el
código en los computadores. De esta manera ellos primero escribían el resultado
esperado y a partir de esto escribían el código fuente.
En el año 2002, Kent Beck publica su libro Test Driven Development: By Example, y en
ese momento la metodología empieza a ser popular a través de la comunidad de
desarrolladores. El libro presenta dos ejemplos utilizando TDD y una gran porción del
mismo es dedicado a presentar soluciones a problemas de testeo que pueden
presentarse con el uso de TDD. A partir de esto, empieza la jornada de TDD en el mundo
del desarrollo de software y se realizan varias investigaciones y artículos referentes al
tema.
(c2, 2014)
Son varias las ventajas que se le atribuyen a la metodología TDD y son muchas las
razones por las que resulta beneficioso convertirla en una herramienta habitual para el
desarrollo de software. Estas son algunas de esas ventajas:
25
Ventajas para el software
Código altamente reutilizable.
Escribir el ejemplo (test) antes que el código nos obliga a escribir el mínimo de
funcionalidad necesaria, evitando sobrediseñar.
Nos hace descubrir y afrontar más casos de uso en tiempo de diseño.
Las pruebas hechas para cada método del sistema pueden utilizarse como
documentación para su entendimiento.
La calidad del software aumenta.
Ventajas para el equipo de trabajo
Multiplica la comunicación entre los miembros del equipo.
El trabajo en equipo se hace más comprensible.
Las personas encargadas de la garantía de calidad adquieren un rol más inteligente
e interesante.
Incrementa la productividad.
Uno se marcha a casa con la reconfortante sensación de que el trabajo está bien
hecho.
b) Capítulo 2. Pruebas Unitarias
Subcapítulo 2.1. ¿Qué son las Pruebas Unitarias?
Una prueba unitaria o “unit test” es un procedimiento que prueba una unidad estructural
de código, generalmente una función o un método. Buscan aislar cada parte del sistema
y mostrar que las partes individuales son correctas. (Hartjes, C., 2014)
Para entender mejor este concepto tomemos un ejemplo apartado del mundo del
software, una impresora a tinta, para verificar el correcto funcionamiento de la misma,
se la podría construir por completo y después probar si todas sus funciones cumplen su
objetivo. Al realizar pruebas con este método se obtendrían resultados, pero en caso de
un fallo sería muy difícil detectar cual componente exactamente es el responsable.
Imaginemos que, durante una prueba, la impresora devuelve un papel manchado, para
detectar dónde está la falla habría que desarmar el artefacto, analizar todos los pasos
realizados y todos los componentes involucrados en la impresión.
El método anterior, claramente no es la mejor manera para realizar pruebas. Entonces
ahora, al mismo ejemplo de la impresora lo abordaremos de una manera distinta, con
pruebas unitarias. En lugar de construir toda la impresora y luego probarla, la trataremos
26
en partes. Tomaremos todas esas partes, una por una, y probaremos cada una de sus
funciones, empecemos por ejemplo con la bandeja del papel, tendremos una prueba
para comprobar el funcionamiento del ingreso de papel, otra prueba para verificar que
se admiten varios tamaños de papel, otra prueba para verificar que se permiten solo
ciertos grosores de papel, otra prueba para abrir o cerrar la bandeja, etc. De esta manera
se tendrán muchas pruebas, una para cada función de la bandeja del papel, y una para
cada función de cada componente de la impresora.
Una prueba unitaria diseñada correctamente debería tener las siguientes
características:
Unitaria: Prueba solamente pequeñas cantidades de código
Independiente: No debe depender ni afectar a otras pruebas unitarias
Automatizable: La prueba debería poder correr sin intervención manual
Repetible y predecible: Sin importar el orden y las veces que se ejecute la prueba,
el resultado siempre debe ser el mismo
Simple: El desarrollo de una prueba unitaria no debería tardar más de cinco minutos
Rápida: Si una prueba no se ejecuta en corto tiempo, no se la ejecuta
Informativa: Una prueba unitaria debería poder utilizarse para comprender mejor el
código que se está probando
(Hartjes, C., 2014)
Se debe considerar que, por estar orientadas a pruebas de fragmentos de código
aislados, las pruebas unitarias por si solas no descubrirán errores de integración,
problemas de rendimiento y otros problemas que afectan a todo el sistema en su
conjunto.
Si la utilización de pruebas unitarias no se incorpora como parte de la metodología de
trabajo, probablemente el código quedará fuera de sincronismo con los casos de prueba.
Subcapítulo 2.2. xUnit (PHPUnit)
xUnit es el nombre común que se le da a un conjunto de frameworks de pruebas
unitarias que tienen la misma estructura y funcionalidad, pero distinto lenguaje de
programación, generalmente se reemplaza la “x” con una letra que identifique el
lenguaje de programación objetivo del framework, por ejemplo: JUnit para Java,
PHPUnit para PHP, RUnit para R, NUnit para .NET, etc.
27
Todos estos frameworks utilizan afirmaciones (assertions) para verificar que el
comportamiento de una porción de código es el esperado. Una prueba completa pasa
cuando no ejecuta afirmaciones o cuando todas las afirmaciones se verifican exitosas.
Las afirmaciones básicamente son declaraciones que deben retornar un valor true para
considerarse exitosas. Las afirmaciones son el objetivo final de una prueba unitaria, en
ellas se compara el valor esperado con el valor calculado que retorna la función que
está bajo probación (Hartjes, C., 2014). Entre las afirmaciones más utilizadas en
PHPUnit se encuentran las siguientes:
assertTrue($x) Es exitosa si $x es true
assertFalse($x) Es exitosa si $x es false
assertNull($x) Es exitosa si $x es null
assertNotNull($x) Es exitosa si $x es distinta de null
assertEquals($x, $y) Es exitosa si $x es igual a $y
assertNotEquals($x, $y) Es exitosa si $x es distinta a $y
Tabla 9. Afirmaciones más usadas de PHPUnit
Fuente: Autoría propia
La lista completa de afirmaciones de PHPUnit puede encontrarse en la documentación
https://phpunit.de/manual/current/en/appendixes.assertions.html. Las afirmaciones
pueden variar dependiendo el lenguaje de programación y el framework que se utilice.
Nota: En este curso se utilizará las siguientes herramientas:
ambiente de desarrollo: xampp https://www.apachefriends.org
editor de texto: Sublime Text https://www.sublimetext.com
el usuario puede utilizar cualquier herramienta con la que se sienta cómodo.
En PHPUnit una prueba unitaria es una función que empieza con la palabra clave “test”
y que pertenece a una clase que extiende de PHPUnit_Framework_TestCase, la cual
es una clase abstracta perteneciente al framework de PHPUnit. Por convención la
prueba unitaria debe tener un nombre que explique la función que está probando de la
manera más explícita posible.
Nota: La última versión de PHPUnit ha cambiado un poco su sintaxis, por ejemplo, no
se extiende de PHPUnit_Framework_TestCase sino de TestCase, la lista completa de
cambios puede encontrarse en la documentación https://phpunit.de/manual/current.
Ejemplo 2.2.1:
28
En este ejemplo el archivo MiPrimeraPrueba.php contiene una clase MiPrimeraPrueba
que extiende de PHPUnit_Framework_TestCase, esta clase contiene un método público
llamado testCompararNumeros que lo único que hace es afirmar que 1 es igual a 1, al
ejecutar esta prueba se nota claramente que el resultado será verdadero.
MiPrimeraPrueba.php
<?php
class MiPrimeraPrueba extends PHPUnit_Framework_TestCase {
public function testCompararNumeros() {
$this->assertTrue(1 == 1);
}
}
?>
Para ejecutar las pruebas unitarias solo basta con utilizar el comando phpunit en la
consola del sistema operativo.
La respuesta de PHPUnit es fácil de interpretar: un punto ( . ) por cada prueba aprobada
y una F por cada prueba fallida, también pueden aparecer otras letras como la E que
indica que la prueba no se ejecutó correctamente y se produjo en error.
Ejemplo 2.2.2:
Ahora vamos a cambiar la prueba unitaria y afirmar que 1 es igual a 0.
MiPrimeraPrueba.php
<?php
class MiPrimeraPrueba extends PHPUnit_Framework_TestCase {
public function testCompararNumeros() {
$this->assertTrue(1 == 0);
}
}
?>
En este caso la prueba falla y cuando eso sucede la respuesta de phpunit incluye una
descripción con detalles de la función y la línea donde se encuentra el fallo. Esto es muy
útil en situaciones en las que se ejecutan múltiples pruebas a la vez o casos de prueba
a la vez, un caso de prueba es el conjunto de todas las pruebas de una misma clase.
A medida que se escriben más y más pruebas unitarias, resultara claro que se sigue un
patrón común, inicializar los componentes que serán probados, llamar a algún método
de un componente y ejecutar las afirmaciones, algunas veces al final es necesario
realizar más pasos como por ejemplo liberar los recursos utilizados en la prueba. En un
escenario con muchas pruebas es posible que varias de ellas compartan la misma fase
29
de inicialización o fase final, si por ejemplo se estuvieran probando todos los métodos
de una clase, sería necesario inicializar esa clase en cada prueba unitaria, en estos
casos es conveniente utilizar las funciones que provee PHPUnit.
La funciones setUp() y tearDown() se ejecutan respectivamente antes y después de
cada prueba unitaria sin necesidad de llamarlas, esto ayuda a evitar la repetición de
código y a tener una mejor organización de las pruebas.
Ejemplo 2.2.3:
En el ejemplo ArrayTest se pretende probar el comportamiento de un array, para eso se
han creado tres pruebas unitarias: testEmpty() comprueba que el arreglo este vacío,
testPush() comprueba la inserción de un elemento en el array y testPop() comprueba la
eliminación de un elemento del array. La función setUp() se encarga de la tarea de crear
el array vacío necesario para ejecutar las pruebas unitarias, además al hacer esto se
evita que una prueba interfiera con la otra.
ArrayTest.php
<?php
class ArrayTest extends PHPUnit_Framewok_TestCase {
public function testEmpty() {
$stack = array();
$this->assertTrue(empty($stack));
}
public function testPush() {
$stack = array();
array_push($stack, 'foo');
$this->assertEquals('foo', $stack[count($stack) -1]);
$this->assertFalse(empty($stack));
}
public function testPop() {
$stack = array();
array_push($stack, 'foo');
$this->assertEquals('foo', array_pop($stack));
$this->assertTrue(empty($stack));
}
}
ArrayTest.php
<?php
class ArrayTest extends PHPUnit_Framework_TestCase {
protected $stack;
protected function setUp() {
$this->stack = array();
30
}
public function testEmpty() {
$this->assertTrue(empty($this->stack));
}
public function testPush() {
array_push($this->stack, 'foo');
$this->assertEqualss('foo', $this->stack[count($this->stack)-1]);
$this->assertFalse(empty($this->stack));
}
public function testPop() {
array_push($this->stack, 'foo');
$this->assertEqualss('foo', array_pop($this->stack));
$this->assertTrue(empty($this->stack));
}
}
?>
En caso de ser necesario también se cuenta con los métodos públicos estáticos
setUpBeforeClass() y tearDownAfterClass() los cuales se ejecutan respectivamente
antes de la primera prueba de una clase y al final de la última prueba de una clase.
c) Capítulo 3. ¿Cómo desarrollar con Test Driven Development?
Subcapítulo 3.1. El algoritmo de TDD
La metodología TDD se basa en la repetición de un ciclo de desarrollo muy corto.
Primero el desarrollador escribe una prueba diseñada para resultar fallida, después se
escribe el código mínimo que hace que la prueba pase satisfactoriamente y
posteriormente se refactoriza el código.
La secuencia usual del ciclo es:
1. Escribir una prueba unitaria: se escribe una prueba específica para un requisito o
funcionalidad del sistema, el programador debe conocer a la perfección las
especificaciones de la funcionalidad que está por implementar para hacer esto
2. Ejecutar la prueba y verificar si falla: se valida que la prueba no pase por error sin
haber escrito nuevo código, si la prueba pasa es porque esta incorrecta o porque el
requisito ya existe
31
3. Escribir código fuente: se escribe el código mínimo para que la prueba unitaria pase,
en este punto no es necesario que el código escrito este perfectamente optimizado
y no se deben considerar otros requisitos
4. Ejecutar todas las pruebas: se verifica que todas las pruebas pasen, si no lo hacen
se debe corregir el código hasta que todo sea satisfactorio
5. Refactorizar el código: el código que se escribió anteriormente debe ser limpiado y
ubicado correctamente donde pertenezca, el código duplicado debe ser eliminado,
para mejorar este paso se recomienda utilizar patrones de diseño
6. Repetir: se empieza nuevamente con otra prueba unitaria y el proceso se repite, en
el paso 4 se deben ejecutar todas las pruebas que se hayan creado para verificar
que el nuevo código no perjudique al ya escrito anteriormente
Figura 3. Algoritmo de TDD Fuente: Autoría propia
Ejemplo 3.1.1:
En este ejemplo primero se crea una prueba unitaria para verificar el funcionamiento de
un método de suma de una clase Calculadora, luego a partir de esta prueba se crea la
función que estaba bajo probación.
CalculadoraTest.php
<?php
require 'Calculadora.php';
32
class CalculadoraTest extends PHPUnit_Framework_TestCase {
public function testSuma() {
$calculadora = new Calculadora();
$resultado = $calculadora->suma(2, 2);
$this->assertEqualss(4, $resultado);
}
}
?>
Calculadora.php
<?php
class Calculadora {
public function suma($a, $b) {
return $a + $b;
}
}
?>
Ejemplo 3.1.2:
En este ejemplo se crea una prueba unitaria adicional para verificar el funcionamiento
de un método de multiplicación de la clase Calculadora, luego se organiza el código con
las funciones auxiliares de PHPUnit. A partir de las pruebas unitarias se procede a crear
las funciones en la clase Calculadora.
CalculadoraTest.php
<?php
require 'Calculadora.php';
class CalculadoraTest extends PHPUnit_Framework_TestCase {
protected $calculadora;
protected function setUp() {
$this->calculadora = new Calculadora();
}
protected function tearDown() {
$this->calculadora = NULL;
}
public function testSuma() {
$resultado = $this->calculadora->suma(2, 2);
$this->assertEquals(4, $resultado);
}
public function testMultiplicacion() {
$resultado = $this->calculadora->multiplicacion(3, 3);
$this->assertEquals(9, $resultado);
}
}
?>
33
Calculadora.php
<?php
class Calculadora {
public function suma($a, $b) {
return $a + $b;
}
public function multiplicacion($a, $b) {
return $a * $b;
}
}
?>
Subcapítulo 3.2. El ciclo Red-Green-Refactor (RGR)
Este ciclo se deriva del algoritmo de TDD y es típicamente pero no estrictamente
ejecutado una vez para cada prueba unitaria que se complete. Las reglas de este ciclo
son simples:
Red (Rojo): Crear una prueba unitaria que falle
Green (Verde): Escribir suficiente código fuente para que la prueba pase
Refactor (Refactorizar): Limpiar y optimizar el código fuente
Figura 4. Diagrama ciclo RGR Fuente: Autoría propia
Este ciclo nos dice que primero debemos enfocarnos en probar y hacer que el sistema
funcione correctamente, y después, únicamente después de eso, enfocarnos en darle
al sistema ya funcional una estructura.
Es muy importante mencionar que refactorizar el código no es algo que se hace al final
del proyecto, es una actividad que se realiza constantemente. No hay una tarea
establecida en el cronograma del proyecto que indique: refactorizar el código. No hay
RED
GREEN
REFACTOR
34
tiempo reservado al final del proyecto, al final de una etapa o al final de un día para
refactorizar el código. El acto de refactorizar el código es un proceso continuo en el
desarrollo de un sistema, no es algo que se deja para el final y por tanto no debería ser
opcional.
La meta final de las reglas mencionadas es que el desarrollo esté intentando dirigir el
sistema hacia una Arquitectura Limpia, es decir independiente de organismos externos.
(Gałęzowski, G., 2015)
Ejemplo 3.2.1:
En este ejemplo se tiene una porción de código elaborada con la metodología TDD,
primero se elaboró la prueba unitaria testPersonaPuedeTenerMascota y a partir de ella
se creó la clase Persona. Una vez que se comprobó que el código funciona
correctamente se procedió a refactorizarlo para optimizarlo, creando los métodos get y
set del atributo mascota.
Código sin refactorizar:
PersonaTest.php
class PersonaTest extends PHPUnit_Framework_TestCase {
require Persona.php;
public function testPersonaPuedeTenerMascota() {
$persona = new Persona()
$persona->mascota = 'gato';
$this->assertEquals($persona->mascota, 'gato');
}
}
Persona.php
class Persona {
protected $mascota;
}
Código después de refactorizar:
PersonaTest.php
class PersonaTest extends PHPUnit_Framework_TestCase {
require Persona.php;
public function testPersonaPuedeTenerMascota() {
$persona = new Persona()
$persona->setMascota('gato');
$this->assertEquals($persona->getMascota(), 'gato');
}
}
35
Persona.php
class Persona {
private $mascota;
public function setMascota($mascota) {
$this->mascota = $mascota;
}
public function getMascota() {
return $this->mascota;
}
}
Subcapítulo 3.3. ¿Cómo empezar? La estructura Given-When-Then
Muchas personas saben programar y hacer pruebas unitarias, TDD se trata de hacer
eso, pero al revés, esto talvez no resulte tan fácil de hacer para algunas personas,
especialmente principiantes. La estructura Given-When-Then es una técnica para
ayudar a saber cómo empezar a escribir pruebas unitarias antes que el código fuente.
Para una mejor compresión de esta técnica es altamente recomendable que los
nombres de las pruebas unitarias no sean genéricos, sino que sigan un estándar e
indiquen detalladamente lo que hacen.
La técnica se trata de tomar las partes Given, When y Then, es decir: Dado, Cuando y
Entonces de un requerimiento y traducirlas a código de una manera casi literal, y
después de completar esto, añadir el resto de código necesario para que la prueba sea
ejecutable. (Gałęzowski, G., 2015)
Given: dado un contexto
When: cuando una causa
Then: entonces un efecto
Ejemplo 3.3.1:
Hacer la comparación entre dos usuarios para saber si son los mismos, suponiendo que
son iguales si tienen el mismo nombre.
Given: dado un usuario con un nombre
When: cuando se lo compare con otro usuario que tenga el mismo nombre
Then: entonces ambos usuarios son iguales
UsuarioTest.php
// GIVEN
$usuario1 = new Usuario('Pedro');
// WHEN
36
if ($usuario1 == $usuario2) {}
// THEN
$this->assertTrue($iguales);
Completando el código para que la prueba sea ejecutable:
UsuarioTest.php
// GIVEN
$usuario1 = new Usuario('Pedro');
$usuario2 = new Usuario('Pedro');
// WHEN
$iguales = false;
if ($usuario1 == $usuario2) {
$iguales = true;
}
// THEN
$this->assertTrue($iguales);
Agregando los detalles del framework de pruebas
UsuarioTest.php
class UsuarioTest extends PHPUnit_Framework_TestCase {
public function testDosUsuariosSonIguales() {
// GIVEN
$usuario1 = new Usuario('Pedro');
$usuario2 = new Usuario('Pedro');
// WHEN
$iguales = false;
if ($usuario1 == $usuario2) {
$iguales = true;
}
// THEN
$this->assertTrue($iguales);
}
}
d) Capítulo 4. Practicas con Test Driven Development
Subcapítulo 4.1. Ordenes con Productos
Este ejemplo consiste en un catálogo de productos, los productos tienen un nombre y
un precio, usuarios pueden comprar los productos, los productos pasan a ser parte de
37
una orden, y las ordenes tienes un precio total igual a la suma del precio de todos los
productos que la conforman.
Ejemplo 4.1.1:
ProductoTest.php
require 'Producto.php';
class ProductoTest extends PHPUnit_Framework_TestCase {
protected $producto;
protected function setUp() {
$this->producto = new Producto();
}
protected function tearDown() {
$this->producto = null;
}
public function testProductotienenombre() {
$this->producto->setNombre('pelota');
$this->assertEquals($this->producto->getNombre(), 'pelota');
}
public function testProductotieneprecio() {
$this->producto->setPrecio(10);
$this->assertEquals($this->producto->getPrecio(), 10);
}
public function testPrecioespositivo() {
$precio = $this->producto->setPrecio(-10);
$this->assertEquals($precio, 'error');
}
}
?>
Producto.php
<?php
class Producto {
protected $nombre;
protected $precio;
public function setNombre($nombre) {
$this->nombre = $nombre;
}
public function getNombre() {
return $this->nombre;
}
public function setPrecio($precio) {
if ($precio >= 0) {
$this->precio = $precio;
return $this->precio;
}
return 'error';
38
}
public function getPrecio() {
return $this->precio;
}
}
?>
UsuarioTest.php
<?php
require_once 'Usuario.php';
require_once 'Producto.php';
class UsuarioTest extends PHPUnit_Framework_TestCase {
public function crearProducto($nombre, $precio) {
$producto = new Producto();
$producto->setNombre($nombre);
$producto->setPrecio($precio);
return $producto;
}
public function testUsuariotienenombre() {
$usuario = new Usuario();
$usuario->setNombre('beto');
$this->assertEquals($usuario->getNombre(), 'beto');
}
public function testUsuariotieneordenes() {
$usuario = new usuario();
$producto = new Producto();
$producto->setNombre('silla');
$producto->setPrecio(20);
$orden = array($producto);
$usuario->agregarOrden($orden);
$this->assertCount(1, $usuario->getOrdenes());
$this->assertEquals($usuario->getOrden(0), $orden);
}
public function testPreciototaldeorden() {
$usuario = new Usuario();
$producto1 = $this->crearProducto('mesa', 25);
$producto2 = $this->crearProducto('silla', 15);
$orden = array($producto1, $producto2);
$usuario->agregarOrden($orden);
$this->assertEquals($usuario->getTotalOrden(0), 40);
}
}
?>
Usuario.php
39
<?php
class Usuario {
protected $nombre;
protected $ordenes;
function __construc() {
$this->ordenes = array();
}
public function setNombre($nombre) {
$this->nombre = $nombre;
}
public function getNombre() {
return $this->nombre;
}
public function agregarOrden($orden) {
$this->ordenes[] = $orden;
}
public function getOrdenes() {
return $this->ordenes;
}
public function getOrden($numero) {
return $this->ordenes[$numero];
}
public function getTotalOrden($numero) {
$total = 0;
foreach ($this->ordenes[$numero] as $orden) {
$total += $orden->getPrecio();
}
return $total;
}
}
?>
e) Conclusiones y Recomendaciones
Al utilizar la metodología TDD se llega a la conclusión de que no se puede escribir mucho
código sin tener que compilar o ejecutar algo. Pero este es precisamente el punto, en
todo lo que se hace, ya sea escribir código fuente, escribir pruebas unitarias, o
refactorizar código, el ciclo se mantiene ejecutándose todo el tiempo. El promedio entre
la ejecución de pruebas debería ser de minutos o incluso segundos, 10 minutos es un
tiempo inaceptablemente largo.
Aproximadamente cada hora deberíamos detenernos un momento y analizar el sistema
que estemos desarrollando, fijarnos si las actividades están cumpliendo los ciclos que
nos llevan a que el sistema este alineado con la metodología TDD.
40
2.3.5. Diagrama del flujo (DFD)
Este diagrama se enfoca en el proceso principal, cuando el usuario ya está dentro del
sistema y pretende empezar o continuar el curso virtual en línea, sin entrar en detalle de
los procesos de registro de usuarios o iniciar sesión.
Figura 5. DFD flujo principal del sistema TDD School Fuente: Autoría propia
41
Nombre Flujo Descripción
F1
Se hace la verificación de usuario y contraseña para permitir o denegar el ingreso al sistema.
F2
Se obtiene cual fue la última pregunta/ejercicio que el usuario visitó y no aprobó.
F3
A partir del estado del usuario en el curso, se verifica si aún hay más contenido por delante.
F4
Mostrar los videos y/o textos de la lección correspondiente.
F5
Se verifica si el usuario ha contestado correctamente las preguntas de la lección.
F6
El usuario ingresa su respuesta a una pregunta.
F7
Se verifica si la respuesta que dio el usuario a la pregunta fue correcta.
F8
Se verifica si el usuario ha completado correctamente los ejercicios de la lección.
F9
El usuario ingresa su respuesta a un ejercicio.
F10
Se verifica si la respuesta que dio el usuario al ejercicio fue correcta.
F11
Mostrar una estadística de las veces que un usuario falló/acertó las preguntas o ejercicios, y además recomendaciones para seguir aprendiendo.
Tabla 10. Detalle de flujos del DFD flujo principal del sistema TDD School
Fuente: Autoría propia
42
2.3.6. Herramientas a utilizar
a) Comparación de herramientas
Para seleccionar las herramientas que será utilizadas para la elaboración de este
sistema se realizó una comparación de bases de datos y lenguajes de programación,
describiendo las características, ventajas y desventajas de ellos. Cabe recalcar que
solamente se consideraron herramientas de uso libre, útiles para el desarrollo de
sistemas web y presentes en el mercado desde hace varios años. La decisión de excluir
herramientas de uso propietario se debe a que el sistema TDD School es 100% de uso
gratuito y no rentable.
i. Bases de Datos
MySQL
MySQL es un sistema de gestión de bases de datos relacional, multihilo y multiusuario
dsitribuido bajo licencia dual, comercial y GPL. Es principalmente utilizado en
aplicaciones web en conjunto con PHP.
Ventajas:
Aprovecha la potencia de sistemas multiprocesador, gracias a su
implementación multihilo
Soporta gran cantidad de tipos de datos para las columnas
Dispone de API's en gran cantidad de lenguajes (C, C++, Java, PHP, etc)
Gran portabilidad entre sistemas
Soporta hasta 32 índices por tabla
Gestión de usuarios y passwords
Es una de las herramientas más utilizadas por programadores orientados a
entorno web. Grandes organizaciones incluyendo Facebook, Google, Adobe y
Alcatel utilizan MySQL
Infinidad de librerías y otras herramientas que permiten su uso a través de gran
cantidad de lenguajes de programación
Fácil utilización, instalación y configuración
Desventajas:
Un gran porcentaje de las utilidades de MySQL no están documentadas.
No es intuitivo, como otros programas (ejemplo: Microsoft Access).
43
El uso de triggers es básico comparado con otros motores de bases de datos
comerciales
La función de conversión CAST() no soporta la conversión a REAL o BIGINT
Los privilegios para una tabla no se eliminan automáticamente cuando se borra
una tabla
(Cambi & Zúñiga, 2006)
PostgreSQL
PostgreSQL es un sistema de gestión de bases de datos objeto-relacional, distribuido
bajo licencia BSD y con su código fuente disponible libremente. El desarrollo de
PostgreSQL no es manejado por una empresa y/o persona, sino que es dirigido por una
comunidad de desarrolladores que trabajan de forma desinteresada, altruista, libre y/o
apoyados por organizaciones comerciales. Dicha comunidad es denominada el PGDG
(PostgreSQL Global Development Group).
Ventajas:
Por su arquitectura de diseño, escala muy bien al aumentar el número de CPUs
y la cantidad de RAM. PostgreSQL usa una estrategia de almacenamiento de
filas llamada MVCC para conseguir una mucho mejor respuesta en ambientes
de grandes volúmenes
Soporta datos de tipo fecha, monetarios, elementos gráficos, datos sobre redes
(MAC, IP ...), cadenas de bits, etc. También permite la creación de tipos propios
Incluye herencia entre tablas (aunque no entre objetos, ya que no existen), por
lo que a este gestor de bases de datos se le incluye entre los gestores objeto-
relacionales
Permite la gestión de diferentes usuarios, como también los permisos asignados
a cada uno de ellos
PostgreSQL posee excelentes funciones con las que se puede indexar
elementos y hacer búsquedas avanzadas en formato JSON, a diferencia de otras
bases de datos
Desventajas:
En comparación con MySQL es más lento en inserciones y actualizaciones, ya
que cuenta con cabeceras de intersección que no tiene MySQL
Soporte en línea: Hay foros oficiales, pero no hay una ayuda obligatoria
Consume más recursos que MySQL
La sintaxis de algunos de sus comandos o sentencias no es nada intuitiva
Menos funciones integradas para PHP
44
PostgreSQL no está diseñada para ser una base de datos que trabaja al 100%
en tiempo real. Aunque ofrece las funciones LISTEN, UNLISTEN y NOTIFY que
facilitan el envío de notificaciones asíncronas a todos los procesos conectados
a la base de datos
(Cambi & Zúñiga, 2006)
ii. Lenguajes de Programación
Java
Java es un lenguaje de programación de propósito general, concurrente, orientado a
objetos que fue diseñado específicamente para tener tan pocas dependencias de
implementación como fuera posible. Su intención es permitir que los desarrolladores de
aplicaciones escriban el programa una vez y lo ejecuten en cualquier dispositivo, lo que
quiere decir que el código que es ejecutado en una plataforma no tiene que ser
recompilado para correr en otra.
Ventajas:
El manejo de la memoria se hace automáticamente utilizando el garbage
collector
Lenguaje Multi-plataforma, el código que escrito en java es leído por un
intérprete, por lo que su programa se ejecutará en cualquier plataforma.
Java fue diseñado como un lenguaje orientado a objetos desde el principio. Los
objetos se agrupan en estructuras encapsuladas tanto sus datos como los
métodos (o funciones) que manipulan esos datos.
Java proporciona una colección de clases para su uso en aplicaciones de red,
que permiten abrir sockets y establecer y aceptar conexiones con servidores o
clientes remotos facilitando así la creación de aplicaciones distribuidas
Desventajas:
Para poder ejecutar un programa de Java en múltiples dispositivos, cada uno
requiere un intérprete de Java
El código necesario para un desarrollo es más extenso (engorroso) que en otros
lenguajes de programación
No existen servidores gratuitos en internet que permitan alojar sistemas en java
El tiempo entre actualizaciones se ha visto reducido desde que Oracle, la
compañía dueña de Java, anunció que Java ya no sería su producto principal
(adictosaltrabajo, 2014)
45
PHP
PHP es un lenguaje de uso general de script incrustado dentro del HTML. La mayor
parte de su sintaxis ha sido tomada de C, Java y Perl con algunas características
específicas de sí mismo. La meta del lenguaje es permitir rápidamente a los
desarrolladores la generación dinámica de páginas. El código es interpretado por un
servidor web con un módulo de procesador de PHP que genera la página Web
resultante.
Ventajas:
Es un lenguaje multiplataforma
Completamente orientado al desarrollo de aplicaciones web dinámicas
El código fuente escrito en PHP es invisible al navegador y al cliente ya que es
el servidor el que se encarga de ejecutar el código y enviar su resultado HTML
al navegador
Permite aplicar técnicas de programación orientada a objetos
No requiere definición de tipos de variables, aunque sus variables se pueden
evaluar también por el tipo que estén manejando en tiempo de ejecución
Desventajas:
El código fuente dentro de un servidor es visible para cualquiera que tenga
acceso al mismo, en caso de querer ocultarlo se necesita una aplicación para
encriptar
Nativamente, sin implementar un framework, resultar muy difícil desarrollar
modularmente o por capas
(adictosaltrabajo, 2014)
iii. Cuadros comparativos
Los cuadros comparativos son una manera de dar una calificación cuantitativa a las
características de cada herramienta. La escala de calificación utilizada es la siguiente:
malo regular promedio bueno excelente
1 2 3 4 5
Bases de datos
Característica PostgreSQL MySQL
Orientada a objetos 2 4
46
Multiproceso 4 5
Multiplataforma 4 5
Soporte para procedimientos almacenados 5 5
Soporte para vistas 5 5
Rendimiento 5 4
Seguridad 4 4
Facilidad de uso 3 5
Total 32 37
Tabla 11. Cuadro comparativo de bases de datos
Fuente: Autoría propia
Lenguajes de programación
Característica Java PHP
Orientado a objetos 5 4
Distribuido 5 5
Robusto 5 3
Seguridad 4 3
Portabilidad 5 3
Simplicidad 2 5
Modularización 4 4
Mantenibilidad 4 4
Escalabilidad 4 4
Rendimiento 4 5
Facilidad de uso 2 5
Total 44 45
Tabla 12. Cuadro comparativo de lenguajes de programación
Fuente: Autoría propia
b) Selección de herramientas
Basándose en las comparaciones anteriores, tendencias actuales, compatibilidad,
funcionalidad y capacidad se ha decidido utilizar las siguientes herramientas para el
desarrollo del sistema:
i. Lenguaje de programación
PHP 5.6: PHP es un lenguaje 100% orientado a entorno web, es más simple y el
desarrollo es más rápido, además los servidores para alojar sistemas en PHP son
47
mucho más accesibles que los servidores para alojar otros lenguajes, estas
características lo hacen ideal para este proyecto.
ii. Motor de base de datos
MySQL 5.6: MySQL posee mejor integración con PHP que con otros lenguajes, ya que
PHP incluye funciones para realizar operaciones de base de datos dedicadas para
MySQL. Además, es un motor de base de datos más liviano sin sacrificar capacidad o
rendimiento.
iii. Servidor Web
Apache 2.4: El servidor HTTP Apache es el servidor web más usado en todo el mundo,
es de código abierto y está disponible para plataformas Unix, Windows, Macintosh y
otras. El servidor apache es actualmente desarrollado y mantenido por una comunidad
de usuarios bajo la supervisión de la Apache Software Foundation. Entre sus
características se encuentran: modular, extensible, altamente escalable, balanceo de
carga, soporte para TLS/SSL, reescritura de URLs, etc. Además, Apache posee PHP
incrustado, lo cual permite ejecutar líneas de comandos en ese lenguaje.
iv. Framework
Laravel 5.2: Laravel es un framewok para PHP de código abierto y gratuito, su propósito
es el desarrollo de aplicaciones web siguiendo el modelo arquitectónico MVC (modelo
– vista – controlador). Laravel tiene como objetivo ser un framework que permita el uso
de una sintaxis elegante y expresiva para crear código de forma sencilla y permitiendo
varias funcionalidades, intenta aprovechar lo mejor de otros frameworks y las
características de las últimas versiones de PHP. Gran parte de Laravel está formado por
dependencias, especialmente Symfony.
v. Utilitarios
JQuery 2.2: JQuery es una librería de Javascript diseñada para simplificar la interacción
con el código del lado del cliente o HTML. JQuery es la librería de Javascript más popular
a nivel mundial, es gratuita y de código abierto. La sintaxis de JQuery está diseñada
48
para facilitar la navegación de un documento HTML, selección de elementos del DOM
(Document Object Model), creación de animaciones, manejo de eventos, uso de ajax.
Bootstrap 3.3: Bootstrap es una librería de front-end gratuita y de código abierto que
tiene el propósito de facilitar el desarrollo de sitios y aplicaciones web. Contiene plantillas
basadas en HTML y CSS para tipografías, formas, botones, y otros elementos de
interfaz de usuario, así como también extensiones opcionales de Javascript. Bootstrap
facilita la implementación de diseño web adaptable, lo cual significa que la disposición
de los elementos de las páginas web se ajusta dinámicamente tomando en cuenta las
características del dispositivo que está siendo utilizado (pc, tablet, teléfono móvil, etc.)
2.3.7. Arquitectura
a) Arquitectura de Hardware
Figura 6. Arquitectura de hardware del sistema TDD School Fuente: Autoría propia
Cliente – Servidor. La arquitectura cliente – servidor es un modelo de aplicación
distribuida en el que las tareas se reparten entre los proveedores de recursos o servicios
49
llamados servidores, y los demandantes, llamados clientes. Los equipos clientes (pc,
tablets, teléfonos, etc) ingresan al sistema mediante su navegador (Chrome, Firefox,
etc), realizan peticiones al servidor web donde está alojado el sistema y este retorna
una respuesta, el servidor web se conecta con el servidor de base de datos para guardar
y recuperar información. Una maquina puede ser cliente, servidor o ambos dependiendo
de la naturaleza de sus aplicaciones o servicios.
b) Arquitectura de Software
Figura 7. Arquitectura de software del sistema TDD School Fuente: Autoría propia
Modelo – Vista – Controlador (MVC). El sistema lleva la arquitectura de software del
framework que utiliza, Laravel. La arquitectura MVC separa los datos y la lógica de
negocio de la lógica asociada con la interfaz de usuario (GUI). Los componentes de
MVC se podrían definir de la siguiente manera:
Modelo: Son la representación de entidades del mundo real en forma de datos. Los
modelos gestionan el acceso a esos datos y también las reglas de negocio aplicables
para las entidades.
Vista: Se refiere al contenido que se presenta a los usuarios (páginas HTML).
Aunque la vista puede presentar varias maneras para que un usuario ingrese o
revise información, la vista por si misma nunca se hace cargo del manejo de
información.
50
Controlador: Es el puente entre el modelo y la vista, maneja las peticiones de los
usuarios y las respuestas que reciben, interactúa con la base de datos e indica que
acción debe seguirse, por ejemplo: mostrar una vista, re direccionar a otra página,
registrar información, etc. En el caso de Laravel todas las operaciones de un
controlador están definidas a través de rutas.
2.3.8. Diagrama entidad relación
Figura 8. Diagrama entidad relación de base de datos del sistema TDD School Fuente: Autoría propia
51
Tabla Descripción
users Almacena la información de los usuarios, incluyendo la fecha de su creación y la última vez que ingresaron al sistema.
trainings Almacena la información de los cursos de capacitación existentes, en este caso solamente Test Driven Development.
trainings_users_map
Almacena la información de la relación entre usuarios y cursos de capacitación.
labels Almacena las etiquetas que pueden tener un contenido, por ejemplo: capitulo, subcapítulo, etc.
content Almacena la información del contenido de una sección del curso de capacitación. Aquí es donde se establecen las partes que conforman el curso.
lessons Almacena la información de una lección, puede ser un video, diapositivas o texto.
evaluations Almacena la información de una pregunta/ejercicio, incluyendo su tipo, en este caso solamente se admiten preguntas y ejercicios.
questions Almacena la información de las preguntas. Estas preguntas son de opción múltiple.
answers Almacena la información de las opciones de respuesta que pueden tener las preguntas.
questions_answers_map
Almacena la relación entre las preguntas y las respuestas. Aquí se indica cual respuesta es correcta y cual es incorrecta.
excercises Almacena la información de los ejercicios. Se pretende que estos ejercicios se resuelvan con fragmentos de código.
hints Almacena la información de los consejos que se le pueden aplicar a un ejercicio, con el propósito de facilitar la resolución de los mismos.
excercises_hints_map
Almacena la relación entre los ejercicios y los consejos.
scores
Almacena la información que relaciona a un usuario con las preguntas y ejercicios que ha tomado, incluyendo el número de veces que ha intentado la pregunta o ejercicio, la fecha que la intento por primera vez y la fecha en que la aprobó.
Tabla 13. Detalle del diagrama entidad relación del sistema TDD School
Fuente: Autoría propia
2.3.9. Diseño de Interfaces (prototipo)
a) Pantalla de bienvenida
52
Figura 9. Prototipo de pantalla de bienvenida del sistema TDD School Fuente: Autoría propia
Esta es la pantalla de presentación del sistema, a esta interfaz llegan todos los usuarios
que visitan la página. Aquí solamente se pueden realizar dos acciones: ver un video
informativo o pulsar el botón para empezar el curso, ese botón despliega la pantalla de
iniciar sesión y/o registrar usuarios.
b) Pantalla de ingreso de sesión y registro de usuarios
Figura 10. Prototipo de pantalla de ingreso y registro del sistema TDD School Fuente: Autoría propia
Esta pantalla se muestra a manera de popup, en ella un usuario puede ingresar sus
credenciales para acceder al sistema, o si es un usuario nuevo puede pulsar el botón
Registrarse para mostrar el formulario de registro y crear una cuenta nueva. Si
cualquiera de los procesos se completan exitosamente esta pantalla redirige al usuario
a la pantalla de inicio.
53
c) Pantalla de inicio (index)
Figura 11. Prototipo de pantalla de inicio del sistema TDD School Fuente: Autoría propia
Esta interfaz muestra todo el contenido disponible, aquí se listan enlaces a todas las
secciones del curso de capacitación incluyendo sus lecciones, preguntas y ejercicios. El
usuario puede elegir pulsar un contenido específico al cual desee acceder, o puede
pulsar el botón Continuar para que el sistema lo redirija automáticamente al punto hasta
donde avanzó la última vez. Cuando el usuario pulse un botón de una sección del curso
de capacitación, el sistema verificará si el usuario ha aprobado todas las actividades
previas y según eso le permitirá o denegará el acceso.
d) Pantalla de lección
Figura 12. Prototipo de pantalla de lección del sistema TDD School Fuente: Autoría propia
54
Esta pantalla únicamente se encarga de mostrar el contenido de la lección
correspondiente, puede ser un video, diapositivas o texto.
e) Pantalla de pregunta
Figura 13. Prototipo de pantalla de pregunta del sistema TDD School Fuente: Autoría propia
En esta pantalla se despliega una pregunta de opción múltiple y las posibles respuestas
a ella. El usuario debe pulsar el botón Enviar para verificar su respuesta y solamente
cuando esta se ha verificado correcta se le permite avanzar.
f) Pantalla de ejercicio
Figura 14. Prototipo de pantalla de ejercicio del sistema TDD School Fuente: Autoría propia
55
Esta pantalla despliega un ejercicio que el usuario debe resolver, generalmente
involucra escribir fragmentos de código. En el lado izquierdo se muestra la descripción
del ejercicio con la tarea que hay que realizar, también existe la opción de mostrar
consejos que facilitan la resolución del mismo. En el lado derecho está el área para que
el usuario escriba su respuesta y un área para mostrar el resultado de la misma. El
usuario debe pulsar el botón Enviar para verificar su respuesta y solamente cuando esta
se ha verificado correcta se le permite avanzar.
g) Pantalla de finalización
Figura 15. Prototipo de pantalla de finalización del sistema TDD School Fuente: Autoría propia
Cuando un usuario ha terminado todo el curso, es decir que ha visto todas las lecciones
y ha contestado todas las preguntas y ejercicios correctamente, se despliega esta
pantalla, la cual solamente contiene recomendaciones finales y recursos externos para
que el usuario pueda seguir aprendiendo más de Test Driven Development, en caso de
así desearlo.
56
3. RESULTADOS
El sistema TDD School fue exitosamente publicado en línea el día 11 de julio del 2016
bajo el dominio tddschool.net.
3.1. Interfaces de usuario
El diseño final del sistema se puede apreciar en la siguiente imagen:
Figura 16. Diseño final del sistema TDD School Fuente: Autoría propia
57
3.2. Métricas del sistema
En los primeros 30 días de actividad en línea del sistema TDD School se obtuvieron
las siguientes métricas:
Número de usuarios registrados 84 usuarios
Número de usuarios que completaron la totalidad del curso
34 usuarios
Tiempo más corto en que un usuario completó del curso
98 minutos
Tiempo más largo en que un usuario completó del curso
Indefinido (hay muchos usuarios que no lo han terminado aún)
Número total de reproducciones de las lecciones
288 reproducciones
Lección con mayor número de reproducciones
Subcapítulo 1.1. ¿Qué es Test Driven Development?
Lección con menor número de reproducciones
Subcapítulo 3.2. El ciclo Red Green Refactor
Número total de intentos para contestar las preguntas y ejercicios
5172 intentos
Número de intentos fallidos para contestar las preguntas y ejercicios
3520 intentos
Número de intentos exitosos para contestar las preguntas y ejercicios
1652 intentos
Pregunta/ejercicio con mayor número de intentos
Ejercicio 1 del subcapítulo 2.2
Pregunta/ejercicio con menor número de intentos
Pregunta 1 del subcapítulo 1.1
Pregunta/ejercicio en la que más usuarios se han quedado y no han avanzado
Ejercicio 1 del subcapítulo 2.2
Menor número de intentos de preguntas y ejercicios en que un usuario completó el curso
66 intentos
Institución con más usuarios Universidad Central del Ecuador
Número de veces que el sistema reportó errores en producción
0 veces
Tabla 14. Recopilación de métricas del sistema TDD School
Fuente: Autoría propia
Además de estas métricas, también se tiene información sobre las pruebas end-to-end
realizadas al sistema, el detalle de las pruebas puede encontrarse en el Anexo C.
Para las siguientes estadísticas solamente se consideran los 34 usuarios que
completaron la totalidad del curso de capacitación:
58
Solamente el 40.47% de los usuarios registrados completo el curso en su totalidad
Cada usuario empleó en promedio 103 intentos en todas las 29 preguntas y
ejercicios
Cada usuario empleó en promedio 4 intentos en cada pregunta/ejercicio
3.3. Retroalimentación por parte de usuarios
Cuando un usuario contesta correctamente la última pregunta o ejercicio del curso,
antes de proceder a la pantalla de finalización, se le presenta una encuesta para que
pueda dejar su opinión acerca del sistema TDD School. La encuesta completa puede
encontrarse en el anexo B. Estos son los resultados recogidos por la encuesta en los
primeros 30 días de actividad del sistema:
1. ¿Qué calificación le pondrías a TDD School en Diseño visual (interfaces)?
Gráfico 1. Opinión de usuarios acerca del diseño visual del sistema Fuente: Autoría propia
2. ¿Qué calificación le pondrías a TDD School en Facilidad de uso (navegación)?
Gráfico 2. Opinión de usuarios acerca de la facilidad de uso del sistema Fuente: Autoría propia
59
3. ¿Qué calificación le pondrías a TDD School en Rendimiento (velocidad de
respuesta)?
Gráfico 3. Opinión de usuarios acerca del rendimiento del sistema Fuente: Autoría propia
4. ¿Qué calificación le pondrías a TDD School en Contenido (videos)?
Gráfico 4. Opinión de usuarios acerca de los videos del curso Fuente: Autoría propia
5. ¿Qué calificación le pondrías a TDD School en Evaluaciones (preguntas y
ejercicios)?
Gráfico 5. Opinión de usuarios acerca de las evaluaciones del curso Fuente: Autoría propia
60
6. ¿Qué tal te pareció la compresión de este curso?
Gráfico 6. Opinión de usuarios acerca de la comprensión del curso Fuente: Autoría propia
7. ¿Qué tal te pareció la dificultad del curso?
Gráfico 7. Opinión de usuarios acerca de la dificultad del curso Fuente: Autoría propia
8. ¿Conocías acerca de Test Driven Development antes de empezar el curso de TDD
School?
Gráfico 8. Opinión de usuarios sobre su conocimiento de TDD antes del curso Fuente: Autoría propia
61
9. ¿Cómo sientes tus conocimientos de Test Driven Development después de
completar el curso de TDD School?
Gráfico 9. Opinión de usuarios sobre su conocimiento de TDD después del curso Fuente: Autoría propia
10. ¿Cuál es tu interés ahora en Test Driven Development como metodología de
desarrollo de software?
Gráfico 10. Opinión de usuarios acerca de su interés en TDD Fuente: Autoría propia
11. ¿Piensas utilizar Test Driven Development en tus proyectos futuros?
Gráfico 11. Opinión de usuarios sobre usar TDD en el futuro Fuente: Autoría propia
62
12. ¿Te gustaría que TDD School cuente con un curso avanzado de Test Driven
Development?
Gráfico 12. Opinión de usuarios sobre un curso avanzado de TDD Fuente: Autoría propia
13. ¿Qué puntuación le pondrías en total a TDD School?
Gráfico 13. Calificación de usuarios a TDD School Fuente: Autoría propia
El modelo de encuesta que se utilizó para obtener estos resultados puede encontrarse
en el Anexo B.
63
4. DISCUSIÓN
El sistema TDD School fue elaborado con el propósito de enseñar a usuarios
involucrados en el mundo del desarrollo de software la metodología Test Driven
Development. A pesar de su poca difusión, se lograron conseguir ciertos resultados con
los cuales se puede analizar si se cumplió o no este objetivo.
El hecho de que menos de la mitad de los usuarios registrados hayan terminado el curso,
indica que podría existir un punto dentro del sistema en el cual los usuarios pierden el
interés por continuar. Este punto bien podría ser el ejercicio 2.2.1 del subcapítulo 2.2,
ya que este ejercicio reporta el mayor número de intentos de respuesta fallidos y es
hasta donde la mayoría de usuarios que no completaron el curso han avanzado. El
subcapítulo 2.2 enseña sobre PHPUnit y muestra por primera vez en el curso
fragmentos de código a modo de ejemplos, de igual manera el ejercicio 1 pretende que
el usuario resuelva un problema que involucra escribir una pequeña porción de código
basándose en lo aprendido en la lección. Al parecer la manera en la que el sistema
introduce a los usuarios a la parte de programación no está bien expuesta y necesita
ser abordada más lenta y detalladamente, de tal manera que los usuarios tengan más
claros los conceptos de la lección y que las preguntas/ejercicios tengan un grado de
dificultad progresivo empezando en un punto más bajo del actual.
Por otro lado, considerando los resultados de la encuesta de opinión de los usuarios
que si terminaron el curso completo de TDD School, el panorama es muy alentador, más
del 90% de las calificaciones recibidas son positivas en cuanto a los aspectos básicos
del sistema como diseño, rendimiento, etc. Y en la puntuación final que los usuarios le
dieron al sistema en una escala del 1 al 10, las calificaciones varían de 5 a 10 siendo 8
la predominante con el 44%. Esto indica que los usuarios que pudieron ver el sistema
en su totalidad, de principio a fin, están satisfechos con el funcionamiento del mismo, al
menos en lo concerniente al software en sí.
Finalmente analizando los aspectos del contenido del curso, es decir las lecciones y
preguntas/ejercicios de la metodología Test Driven Development, la gran mayoría de
usuarios si muestran interés en la misma después de completar el curso y no descartan
la posibilidad de utilizarla para sus propios proyectos, esto se corrobora aún más
positivamente considerando que las 3/4 partes de los usuarios que utilizaron el sistema
64
empezaron sin conocimiento alguno o muy escaso de la metodología y que la
puntuación en el aspecto de comprensión esta 100% por encima de la media.
Sin embargo, el aspecto que necesita ajustarse del curso de capacitación parece ser la
dificultad, que si bien en su mayoría tiene una calificación intermedia por parte de los
usuarios que completaron la totalidad del curso, también existe un alto porcentaje de
usuarios que la consideran más alta de la media, y eso no debería suceder de acuerdo
al plan de contenido del curso. Además, este aspecto es una preocupación que
seguramente debe tomarse en cuenta para ayudar a disminuir el problema del abandono
prematuro del curso.
Actualmente el contenido del curso de capacitación es secuencial y restrictivo, es decir
que los usuarios no pueden avanzar a la siguiente sección sin aprobar la anterior, se
debe considerar cambiar esta estrategia y eliminar la restricción de tal manera que los
usuarios puedan navegar libremente por el contenido del curso. Este cambio tiene tanto
implicaciones positivas como negativas, por un lado, los usuarios se sentirían más
cómodos con la libertad de navegación y podrían tomar solamente las lecciones y
preguntas/ejercicios que ellos consideren necesarias, y por otro lado esto dificultaría
recolectar información sobre si un usuario completó la totalidad del curso.
El sistema TDD School puede mejorar en muchos aspectos como: diseño, difusión,
accesibilidad, velocidad, etc, pero uno de los aspectos más importantes es su estrategia
pedagógica, a los videos se los puede hacer más explicativos con más teoría, ejemplos
analógicos y un resumen de los mismos para facilitar la compresión de las lecciones
impartidas, a las preguntas se las puede estandarizar dándoles a todas el mismo
número de opciones de respuesta con una lógica bien definida, y a los ejercicios se los
puede presentar con un fragmento de código pre cargado para que el usuario no tenga
que escribir la totalidad de la respuesta sino solamente las partes más relevantes.
No se descarta la posibilidad de implementar estos cambios en un futuro, pero para
hacerlo se necesita realizar un análisis del tiempo y los recursos necesarios para
determinar si son factibles y convenientes.
65
5. CONCLUSIONES
Se lograron cumplir todos los objetivos que se propusieron para este proyecto. El
sistema TDD School fue elaborado correctamente cumpliendo el objetivo general del
trabajo y fue exitosamente publicado en línea bajo el dominio tddschool.net para que
cualquier usuario con acceso a internet pueda utilizarlo libremente desde un
computador o dispositivo móvil.
Se asumieron los riesgos que afectaban al sistema ya que ninguno representaba
una amenaza alta. De todas maneras, se tomaron medidas para mitigar el impacto
y la probabilidad de los mismos, como por ejemplo estudiar la metodología TDD de
fuentes oficiales, elaborar el sistema con seguridades para evitar su hackeo,
comprobar la visualización en distintos dispositivos, etc. Esto ayudó enormemente a
que el sistema reporte cero fallas en producción.
El curso de capacitación de Test Driven Development resultó ser exitoso en sembrar
un interés, en enseñar los conceptos y el uso básico de esta metodología a los
usuarios que completaron la totalidad del curso.
La satisfacción de los usuarios que completaron el curso de capacitación al utilizar
el sistema es positiva en su gran mayoría, superando el 90% de calificaciones
positivas.
El sistema tiene deficiencias en los aspectos de difusión del mismo y retención de
usuarios. Hay una falla grave en la manera en la que el curso de capacitación
introduce la programación de código a los usuarios y provoca la pérdida de interés
en continuar el curso, se deben tomar medidas correctivas que incluyen re-escribir
el contenido de la lección y cambiar el ascenso de la dificultad de las preguntas o
ejercicios.
66
6. RECOMENDACIONES
Para ayudar a mejorar la difusión del sistema TDD School podrían tomarse algunas
medidas como: utilizar herramientas estadísticas que entreguen resultados más
detallados sobre el estado del sistema y su interacción con los usuarios, vincular el
sistema con redes sociales, invertir en campañas de publicidad pagada.
Por ahora el sistema solo se encuentra disponible en español y las lecciones
solamente muestran PHP como lenguaje de programación, deberían incluirse más
idiomas y más lenguajes de programación para atraer a un grupo más grande y
diverso de desarrolladores.
Considerar eliminar la restricción que impide que los usuarios naveguen libremente
por el contenido del curso de capacitación para darles más libertad y comodidad de
visitar las lecciones y preguntas/ejercicios a su gusto.
Mejorar el curso de capacitación tomando medidas como: agregar más teoría,
ejemplos y resúmenes a las lecciones, estandarizar las opciones de respuesta para
las preguntas y pre cargar fragmentos de código para los ejercicios.
El sistema TDD School tiene grandes oportunidades de mejoramiento en varios
aspectos como en diseño de interfaces, accesibilidad, curva de aprendizaje,
estrategia pedagógica y nivel de dificultad del curso de capacitación, etc. Se debe
realizar un análisis para determinar cuáles son los puntos más importantes que
harían que el sistema sea más exitoso en comparación con el esfuerzo y recursos
que requerirían atender esos puntos. Este análisis sería un buen inicio para
implementar un proceso de mejora continua.
67
BIBLIOGRAFÍA
1. Beck, K. (2002). Test Driven Development: By Example: Addison-Wesley
Professional
2. Astels, D. (2003). Test-Driven Development: A Practical Guide: Prentice Hall
3. Hernández, R., Fernández, C. y Baptista, p. (1997). Metodología de la
investigación: Mc Graw Hill
4. Cambi, J., Zúñiga, J. (2006). Comparación entre MySQL vs. Postgress
5. George, B. y Williams L. (2003). A structured experiment of test-driven
development, 46 (2004) 337–342
6. Nagappan, N., Maximilien, E. M. y Williams, L. (2008). Realizing quality
improvement through test driven development: results and experiences of four
industrial teams. (2008) 13:289–302
7. Araújo, A. (2007). Test Driven Development Fortalezas y Debilidades
8. Hartjes, C. (2015). The Grumpy Programmer’s Guide To Building Testable PHP
Applications. Recuperado de https://leanpub.com/grumpy-testing
9. Hartjes, C. (2014). The Grumpy Programmer’s PHPUnit Cookbook. Recuperado de
https://leanpub.com/grumpy-phpunit
10. Popescu, M. (2011). TDD by example Evaluating an expression. Recuperado de
http://renfieldsoftware.com
11. Gałęzowski, G. (2015). Test-Driven Development: Extensive Tutorial. Recuperado
de https://leanpub.com/tdd-ebook
12. Blé, C. (2010). Diseño Ágil con TDD. Recuperado de
http://www.carlosble.com/libro-tdd
13. TDD como metodología de diseño de software (s.f.). En paradigmadigital.
Recuperado en marzo de 2016 de https://www.paradigmadigital.com/dev/tdd-
como-metodologia-de-diseno-de-software/
14. Sistemas Web. ¿Para qué sirven? (2013). En Fraktalweb. Recuperado en marzo
de 2016 de http://fraktalweb.com/blog/sistemas-web-para-que-sirven/
68
15. Definición de e-Learning. (s.f.). En abclearning. Recuperado en marzo de 2016 de
http://www.e-abclearning.com/definicione-learning
16. Definición de HTML. (s.f.). En definicionabc. Recuperado en marzo de 2016 de
http://www.definicionabc.com/tecnologia/html.php
17. ¿Qué es JavaScript? (s.f.). En efectosjavascript. Recuperado en marzo de 2016 de
http://www.efectosjavascript.com/javascript.html
18. Introducción a CSS. (s.f.). En librosweb. Recuperado en marzo de 2016 de
http://librosweb.es/libro/css/
19. Estrategias pedagógicas. (s.f.). En UDEA. Recuperado en septiembre de 2016 de
http://docencia.udea.edu.co/educacion/lectura_escritura/estrategias.html
20. Ten Years Of Test Driven Development. (2014). En c2. Recuperado en marzo del
2016 de http://c2.com/cgi/wiki?TenYearsOfTestDrivenDevelopment
21. PHP vs Java. (2014). En adictosaltrabajo. Recuperado en marzo del 2016 de
https://www.adictosaltrabajo.com/tutoriales/php-vs-java/
22. Concepto de capacitación. (s.f.) En deconceptos. Recuperado en septiembre del
2016 de http://deconceptos.com/ciencias-sociales/capacitacion
23. Instructivo para la elaboración de la matriz de riesgos. (2014). En serviciocivil.
Recuperado en septiembre del 2016 de http://www.serviciocivil.gov.co/
69
ANEXOS
70
ANEXO A
Preguntas y ejercicios del curso de capacitación, con sus respuestas
Preguntas del subcapítulo 1.1
1.1.1. ¿Qué es Test-Driven Development?
Es una metodología para escribir mejor código y realizar mejores pruebas a un
sistema
Es una técnica de programación en la que se escribe por lo menos una prueba
por cada función o método que tiene el sistema
Es una metodología de diseño e implementación de software (Respuesta)
Es una metodología también conocida como Extreme Programming que
consiste en realizar pruebas cada que se escribe un bloque de código
Ninguna de las anteriores
1.1.2. ¿Cuáles son las prácticas principales que conforman Test-Driven
Development?
Escribir pruebas para cada función del código y refactorizar
Escribir pruebas antes que el código y refactorizar (Respuesta)
Escribir solamente el código necesario y elaborar pruebas para cada función
Escribir pruebas antes que el código y realizar iteraciones para generar la
arquitectura
Ninguna de las anteriores
1.1.3. ¿Cuál de las siguientes no es una ventaja de utilizar Test-Driven Development?
Aumenta la seguridad de que el código no tiene errores
La comunicación en un equipo de desarrollo mejora
Código más limpio y reutilizable
El tiempo de programación se reduce drásticamente (Respuesta)
Todas las anteriores
Ninguna de las anteriores
1.1.4. ¿Cuál es el propósito de Test-Driven Development?
Crear una conciencia de la importancia de realizar pruebas a un sistema
71
Establecer un patrón de comportamiento para diseñar y programar en los
desarrolladores (Respuesta)
Ahorrar tiempo de programación que puede ser mejor invertido
Facilitar la organización en un equipo de desarrollo
Eliminar los errores de un sistema en la etapa más temprana posible
Todas las anteriores
Ninguna de las anteriores
Preguntas del subcapítulo 2.1
2.1.1. ¿Qué es lo que pretenden probar las pruebas unitarias?
Un sistema
Una función o método (Respuesta)
Una línea de código
Muchas líneas de código
Todas las funciones de una clase
Todas las anteriores
Ninguna de las anteriores
2.1.2. ¿Qué pruebas unitarias se necesitarían para probar una bombilla eléctrica?
Encendido, apagado
Conducción, durabilidad, resistencia, iluminación
Color, forma, temperatura
Todas las anteriores (Respuesta)
Ninguna de las anteriores
2.1.3. Se tiene una función que evalúa la raíz cuadrada de un número, se crea una
prueba unitaria para verificar el correcto resultado de aquella función, luego al
probar la función con el número 9, se obtiene como resultado el número 3, al
ejecutar la prueba unitaria esta devuelve verdadero que indica que la prueba
pasó con éxito. ¿Cuál de las siguientes afirmaciones es correcta?
La función y la prueba unitaria son correctas
la función es correcta y la prueba unitaria es incorrecta
La función es incorrecta y prueba unitaria es correcta
La función y la prueba unitaria están incorrectas (Respuesta)
72
Ejercicios del subcapítulo 2.1
Ejercicio 2.1.1.
Escribe un ejemplo de prueba unitaria que podría aplicarse a una calculadora básica,
que no sea sumar. Escribe solamente un verbo.
Respuesta:
Encender, apagar, sumar, restar, multiplicar, dividir
Consejos:
Puedes incluir operaciones matemáticas que realizaría una calculadora
Preguntas del subcapítulo 2.2
2.2.1 ¿Cuál de los siguientes es un nombre correcto para una prueba unitaria?
pruebaSumarNúmeros
PruebaSumarNúmerosPositivosEnteros
testSumarNúmerosPositivosEnteros (Respuesta)
TestSumarNúmerosPositivosEnteros
Todas las anteriores
Ninguna de las anteriores
2.2.2 ¿Qué afirmación se debe utilizar para verificar que una variable $x tiene un
valor distinto de cero?
assertTrue($x != 0)
assertFalse($x == 0)
assertNotEmpty($x)
assertNotEquals($x, 0)
Todas las anteriores (Respuesta)
Ninguna de las anteriores
2.2.3. Se tiene una clase CalculadoraTest que extiende de
PHPUnit_Framework_TestCase, ¿Cuál de las siguientes funciones se ejecuta
primero?
setUpBeforeClass() (Respuesta)
setUp()
testSuma()
testMultiplicacion()
73
tearDown()
Ejercicios del subcapítulo 2.2
Ejercicio 2.2.1.
Crear una prueba unitaria llamada testEstado, que asigna el valor true a una variable
$status, y que comprueba si $status es true.
Respuesta:
<?php
public function testEstado() {
$status = true;
$this->assertTrue($status);
}
?>
<?php
public function testEstado() {
$status = true;
$this->assertEquals($status, true);
}
?>
Consejos:
No olvidar abrir y cerrar las etiquetas de php <?php ?>
Una prueba unitaria es una función, así que debe estar precedida por public
function
assertTrue o assertEquals son afirmaciones que pueden verificar si una
variable tiene un valor true
No escribir más código del necesario
Ejercicio 2.2.2.
Crear una clase llamada CambioTest que extienda de
PHPUnit_Framework_TestCase, en ella crear dos métodos, testOn y testOff.
- testOn asignará el valor ‘on’ a una variable $x y verificará que su valor sea ‘on’.
- testOff asignará el valor a ‘off’ a una variable $x y verificará que su valor sea ‘off’.
Respuesta:
<?php
class CambioTest extends PHPUnit_Framework_TestCase {
public function testOn() {
$x = ‘on’;
$this->assertEquals($x, ‘on’);
}
public function testOff() {
74
$x = ‘off’;
$this->assertEquals($x, ‘off’);
}
}
?>
Consejos:
No olvidar abrir y cerrar las etiquetas de php <?php ?>
Una prueba unitaria es una función, así que debe estar precedida por public
function
assertEquals es una afirmación que pueden verificar si una variable es igual a
un valor
No escribir más código del necesario
Ejercicio 2.2.3.
Crear una clase con dos pruebas unitarias, una para cambiar el valor de una variable a
“on” y otra para cambiar el valor de la misma variable a “off”, además inicializar esa
variable en “ready” antes de cada prueba y ponerla en null después de cada prueba.
- Crear una clase llamada CambioTest que extienda PHPUnit_Framework_TestCase
- Declarar una variable protected $x
- Crear una función setUp que inicializará el valor de $x en ‘ready’
- Crear una prueba unitaria llamada testOn que cambie $x a ‘on’ solamente si su valor
era ‘ready’, utilizar la afirmación assertEquals para verificar que el valor de $x es ‘on’
- Crear una prueba unitaria llamada testOff que cambie $x a ‘off’ solamente si su valor
era ‘ready’, utilizar la afirmación assertEquals para verificar que el valor de $x es ‘off’
- Crear una función tearDown que asigne null a la variable $x.
Respuesta:
<?php
class CambioTest extends PHPUnit_Framework_TestCase {
protected $x;
protected function setUp() {
$this->x =’ready’;
}
public function testOn() {
if ($this->x == ‘ready’) {$this->x = ‘on’;}
$this->assertEquals($this->x, ‘on’);
}
public function testOff() {
if ($this->x == ‘ready’) {$ this->x = ‘off’;}
$this->assertEquals($this->x, ‘off’);
}
75
protected function tearDown() {
$this->x = null;
}
}
?>
Consejos:
No olvidar abrir y cerrar las etiquetas de php <?php ?>
Una prueba unitaria es una función, así que debe estar precedida por public
function
Es necesario incluir una sentencia condicional if en estas pruebas unitarias
La visibilidad de las funciones setUp() y tearDown() es protected
No escribir más código del necesario
Es muy importante que sigas los pasos en el orden descrito
Preguntas del subcapítulo 3.1
3.1.1. ¿Cuál es el primer paso para empezar a desarrollar con TDD?
Escoger un requisito del sistema y escribir todas las pruebas unitarias para esa
funcionalidad
Escoger un requisito del sistema y escribir una prueba unitaria para esa
funcionalidad (Respuesta)
Escoger un requisito del sistema y escribir el código fuente para esa
funcionalidad
Escoger un requisito del sistema, escribir una prueba unitaria para esta
funcionalidad y verificar que la prueba pase
Ninguna de las anteriores
3.1.2. ¿Qué se debe hacer cuando se escribe una prueba unitaria nueva y esta pasa
satisfactoriamente en su primera ejecución?
Escribir una prueba unitaria distinta para la misma función que se está
probando
Escribir una prueba unitaria para otra función distinta del sistema
Escribir el código fuente para la función que se está probando
Verificar si la prueba esta incorrecta o la función que se está probando ya
existe (Respuesta)
Ninguna de las anteriores
76
3.1.3. ¿Cuál de los pasos del algoritmo de TDD debería ser automatizado?
Todos
1er paso
2do paso
3er paso
4to paso (Respuesta)
5to paso
6to paso
3.1.4. ¿Es posible que el algoritmo de TDD pueda escribirse en un mayor o menor
número de pasos?, ¿Podrían existir diferentes versiones del mismo?
Si (Respuesta)
No
Talvez
Ejercicios del subcapítulo 3.1
Ejercicio 3.1.1.
Para cumplir un requerimiento de un sistema, hace falta elaborar una función que
reciba dos números enteros y devuelva el mayor ellos. Elaborar la prueba unitaria para
cumplir este requerimiento.
- Crear una clase TestOperaciones que extienda de PHPUnit_Framework_TestCase
- Elaborar una prueba unitaria llamada testMayorDeDosNumeros
- Crear un objeto $operaciones de una clase llamada Operaciones
- Llamar al método mayorDeDosNumeros de la clase Operaciones
- Los parámetros de la función mayorDeDosNumeros en este caso son los números 5
y 10
- Almacenar el resultado de la función mayorDeDosNumeros en una variable
$resultado
- Utilizar $resultado para verificar la afirmación assertEquals(15, $resultado)
Respuesta:
<?php
class TestOperaciones extends PHPUnit_Framework_TestCase {
public function testMayorDeDosNumeros() {
$operaciones = new Operaciones();
77
$resultado = $operaciones->mayorDeDosNumeros(5, 10);
$this->assertEquals(15, $resultado);
}
}
?>
Consejos:
No olvidar abrir y cerrar las etiquetas de php <?php ?>
Una prueba unitaria es una función, así que debe estar precedida por public
function
No escribir más código del necesario
Es muy importante que sigas los pasos en el orden descrito
Ejercicio 3.1.2.
Después de haber elaborado la prueba unitaria, ahora hace falta escribir el código
fuente, como lo dicta la metodología TDD. Crear una función que calcule el mayor de
dos números.
- Crear una clase Operaciones
- Crear una función pública llamada mayorDeDosNumeros que toma dos parámetros
$x y $y
- Declarar una variable $respuesta e inicializarla en una cadena de texto vacía ‘’;
- Hacer la comparación entre $x y $y para ver cuál es mayor, si $x es mayor que $y
asignar $x a $respuesta, caso contrario asignar $y a $respuesta
- Retornar $respuesta para finalizar la función mayorDeDosNumeros
Respuesta:
<?php
class Operaciones {
public function mayorDeDosNumeros($x, $y) {
$respuesta = ‘’;
if ($x > $y) {
$respuesta = $x;
} else {
$respuesta = $y;
}
return $respuesta;
}
}
?>
Consejos:
78
No olvidar abrir y cerrar las etiquetas de php <?php ?>
No escribir más código del necesario
Es muy importante que sigas los pasos en el orden descrito
No utilizar mayor o igual (>=) para hacer la comparación
Ejercicio 3.1.3.
Si se ejecuta el ejemplo anterior, tanto la función como su prueba unitaria deberían
funcionar, sin embargo, esto no significa que la función este 100% correcta y
completa. ¿Qué sucede si se trata de verificar la prueba unitaria con los valores ‘gato’
y ‘perro’?, ni siquiera sabríamos contra que comparar ese resultado, es claro hacen
falta hacer un par de correcciones. Crear otra prueba unitaria que verifique que los
parámetros de la función mayorDeDosNumeros son números.
- Crear una prueba unitaria llamada testMayorDeDosNumerosSinNumeros
- Crear un objeto $operaciones de la clase Operaciones
- Llamar al método mayorDeDosNumeros de la clase Operaciones
- Los parámetros de la función mayorDeDosNumeros en este caso son las palabras
‘gato’ y ‘perro’
- Almacenar el resultado de la función mayorDeDosNumeros en una variable
$resultado
- Utilizar $resultado para verificar la afirmación assertEquals(‘error, los parámetros no
son números’, $resultado)
Respuesta:
<?php
public function testMayorDeDosNumerosSinNumeros() {
$operaciones = new Operaciones();
$resultado = $operaciones->mayorDeDosNumeros(‘gato’, ‘perro’);
$this->assertEquals(‘error, los parámetros no son números’, $resultado);
}
?>
Consejos:
No olvidar abrir y cerrar las etiquetas de php <?php ?>
Una prueba unitaria es una función, así que debe estar precedida por public
function
No escribir más código del necesario
Es muy importante que sigas los pasos en el orden descrito
No hace falta incluir la clase TestOperaciones (solo para el ejercicio)
79
Ejercicio 3.1.4.
Al crear la prueba unitaria anterior, se puede saber que la función
mayorDeDosNumeros está incompleta, es hora de corregir esa función. Verificar que
los parámetros de la función mayorDeDosNumeros son números antes de realizar la
comparación de cual es mayor.
- Elaborar la función pública llamada mayorDeDosNumeros que toma dos parámetros
$x y $y
- Declarar una variable $respuesta e inicializarla en una cadena de texto vacía ‘’;
- Realizar la verificación de que $x y $y son números con la función de PHP
is_numeric()
- Si $x y $y superan la verificación de que son números realizar la comparación de
cual es mayor, si $x es mayor que $y asignar $x a $respuesta, caso contrario asignar
$y a $respuesta
- Si falla de verificación de que $x y $y son números, asignar el mensaje ‘error, los
parámetros no son números’ a $respuesta
- Retornar $respuesta para finalizar la función mayorDeDosNumeros
Respuesta:
<?php
public function mayorDeDosNumeros($x, $y) {
$respuesta = ‘’;
if (is_numeric($x) && is_numeric($y)) {
if ($x > $y) {
$respuesta = $x;
} else {
$respuesta = $y;
}
} else {
$respuesta = ‘error, los parámetros no son números’;
}
return $respuesta;
}
?>
Consejos
No olvidar abrir y cerrar las etiquetas de php <?php ?>
Una prueba unitaria es una función, así que debe estar precedida por public
function
No escribir más código del necesario
Es muy importante que sigas los pasos en el orden descrito
No hace falta incluir la clase Operaciones (solo para el ejercicio)
80
La verificación para saber si $x y $y son números puede escribirse if
(is_numeric($x) && is_numeric($y))
No utilizar mayor o igual (>=) para hacer la comparación
Ejercicio 3.1.5.
La corrección previa es una de las mucha que podrían realizarse, pero para avanzar
con este ejercicio vamos al siguiente paso, refactorizar el código. Refactorizar la
función mayorDeDosNumeros para optimizarla, eliminar la variable $respuesta y
retornar los resultados directamente.
- Elaborar la función pública llamada mayorDeDosNumeros que toma dos parámetros
$x y $y
- Realizar la verificación de que $x y $y son números con la función de PHP
is_numeric()
- Si $x y $y superan la verificación de que son números realizar la comparación de
cual es mayor, si $x es mayor que $y retornar $x, caso contrario retornar $y
- Si falla de verificación de que $x y $y son números, retornar el mensaje ‘error, los
parámetros no son números’
Respuesta:
<?php
public function mayorDeDosNumeros($x, $y) {
if (is_numeric($x) && is_numeric($y)) {
if ($x > $y) {
return $x;
} else {
return $y;
}
} else {
return ‘error, los parámetros no son números’;
}
}
?>
Consejos:
No olvidar abrir y cerrar las etiquetas de php <?php ?>
Una prueba unitaria es una función, así que debe estar precedida por public
function
No escribir más código del necesario
Es muy importante que sigas los pasos en el orden descrito
No hace falta incluir la clase Operaciones (solo para el ejercicio)
81
La verificación para saber si $x y $y son números puede escribirse if
(is_numeric($x) && is_numeric($y))
No utilizar mayor o igual (>=) para hacer la comparación
Preguntas del subcapítulo 3.2
3.2.1. Según el ciclo RGR, ¿Cuándo es un buen momento para refactorizar el
código?
Después de escribir una línea de código
Después de escribir una función
Después de que las pruebas unitarias pasan (Respuesta)
Después de completar la totalidad del sistema
Todas las anteriores
Ninguna de las anteriores
3.2.2. ¿Cuántas veces se debe repetir el ciclo RGR?
Una vez por cada prueba unitaria
Una vez por cada función de código fuente
Una vez por cada cambio que se realiza en el código
Todas las veces que sean necesarias (Respuesta)
Ninguna de las anteriores
Preguntas del subcapítulo 3.3
3.3.1. Para cumplir un requerimiento se necesita transformar un número entero en su
letra equivalente del abecedario (1=A, 2=B, 3=C, etc…), si los números llegan a
la última letra del abecedario se comienza nuevamente en A. ¿Cuál es la forma
correcta de escribir la parte GIVEN de la estructura GIVEN-WHEN-THEN para
realizar una prueba unitaria para cumplir este requerimiento? (Given = Dado un
número entero)
$numero = new Numero();
$numero = 10;
$numero = ‘10’;
$numero = new Numero(10);
Todas las anteriores (Respuesta)
Ninguna de las anteriores
82
3.3.2. Para cumplir un requerimiento se necesita transformar un número entero en su
letra equivalente del abecedario (1=A, 2=B, 3=C, etc…), si los números llegan a
la última letra del abecedario se comienza nuevamente en A. ¿Cuál es la forma
correcta de escribir la parte WHEN de la estructura GIVEN-WHEN-THEN para
realizar una prueba unitaria para cumplir este requerimiento? (When = Cuando
al número se lo transforma en letra)
$letra = transformar($numero);
$letra = $clase->transformar($numero);
$letra = transformar($numero->valor);
$letra = $clase->transformar($numero->getValor());
Todas la anteriores (Respuesta)
Ninguna de las anteriores
3.3.3. Para cumplir un requerimiento se necesita transformar un número entero en su
letra equivalente del abecedario (1=A, 2=B, 3=C, etc…), si los números llegan a
la última letra del abecedario se comienza nuevamente en A. ¿Cuál es la forma
correcta de escribir la parte THEN de la estructura GIVEN-WHEN-THEN para
realizar una prueba unitaria para cumplir este requerimiento? (Then = Entonces
la transformación del número es igual a su letra correspondiente del
abecedario)
$this->assertEquals($letra, ‘J’);
$this->assertTrue($letra == ‘J’);
$this->assertTrue($letra === ‘J’);
$this->assertFalse($letra != ‘J’);
Todas las anteriores (Respuesta)
Ninguna de las anteriores
Ejercicios del subcapítulo 4.1
Ejercicio 4.1.1.
En el último ejemplo la clase UsuarioTest quedo muy desorganizada, en este ejercicio
debes refactorizar el código de esa clase.
- copia y pega el código de la clase UsuarioTest proporcionado
- en el inicio de la clase declara una variable protected $usuario
- a continuación crea una función setUp() para inicializar esa variable global $usuario
con un new Usuario();
83
- después de la función setUp(), crea una función tearDown() para asignar null a la
variable global $usuario
- borra todas las inicializaciones locales de $usuario en cada prueba unitaria y
reemplaza las referencias locales a $usuario con la variable global $this->usuario
- en la prueba unitaria testUsuariotieneordenes utiliza la función crearProducto en
lugar de crear el producto localmente, los parámetros no deben cambiar
Respuesta:
<?php
require_once 'Usuario.php';
require_once 'Producto.php';
class UsuarioTest extends PHPUnit_Framework_TestCase {
protected $usuario;
protected function setUp() {
$this->usuario = new Usuario();
}
protected function tearDown() {
$this->usuario = null;
}
public function crearProducto($nombre, $precio) {
$producto = new Producto();
$producto->setNombre($nombre);
$producto->setPrecio($precio);
return $producto;
}
public function testUsuariotienenombre() {
$this->usuario->setNombre('beto');
$this->assertEquals($this->usuario->getNombre(), 'beto');
}
public function testUsuariotieneordenes() {
$producto = $this->crearProducto('silla', 20);
$orden = array($producto);
$this->usuario->agregarOrden($orden);
$this->assertCount(1, $this->usuario->getOrdenes());
$this->assertEquals($this->usuario->getOrden(0), $orden);
}
public function testPreciototaldeorden() {
$producto1 = $this->crearProducto('mesa', 25);
$producto2 = $this->crearProducto('silla', 15);
$orden = array($producto1, $producto2);
$this->usuario->agregarOrden($orden);
$this->assertEquals($this->usuario->getTotalOrden(0), 40);
}
}
?>
84
Consejos
No escribir más código del necesario
Es muy importante que sigas los pasos en el orden descrito
La visibilidad de las funciones setUp() y tearDown() es protected
Debes hacer siete reemplazos locales de $usuario por $this->usuario
85
ANEXO B
Modelo de encuesta para los usuarios que completaron la totalidad del curso de
capacitación de TDD School
¿Qué calificación le pondrías a TDD School en los siguientes aspectos?
Pésimo Malo Intermedio Bueno Excelente
Diseño visual (interfaces)
Facilidad de uso
(navegación)
Rendimiento (velocidad
de respuesta)
Contenido (videos)
Evaluaciones (preguntas
y ejercicios)
¿Qué tal te pareció la compresión de este curso?
1 2 3 4 5
No entendí nada
Entendí todo
¿Qué tal te pareció la dificultad del curso?
1 2 3 4 5
Fácil
Difícil
¿Conocías acerca de Test Driven Development antes de empezar el curso de
TDD School?
1 2 3 4 5
No sabía nada
Sabía mucho
¿Cómo sientes tus conocimientos de Test Driven Development después de
completar el curso de TDD School?
1 2 3 4 5
No aprendí nada
Aprendí mucho
86
¿Cuál es tu interés ahora en Test Driven Development como metodología de
desarrollo de software?
1 2 3 4 5
No me interesa
Me interesa mucho
¿Piensas utilizar Test Driven Development en tus proyectos futuros?
No
Es probable
Si
¿Te gustaría que TDD School cuente con un curso avanzado de Test Driven
Development?
No
Me da igual
Si
¿Tienes algún comentario sobre TDD School?
--------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------
¿Qué puntuación le pondrías en total a TDD School?
1 2 3 4 5 6 7 8 9 10
Malo
Bueno
87
ANEXO C
Escenarios de pruebas end-to-end del sistema TDD School
Nomenclatura:
PC: Computador de escritorio
M: Teléfono móvil Smart
T: Tablet
P: Pasó la prueba
F: Falló la prueba
N/A: No aplica
Prueba PC M T Observaciones
Ingreso al sitio web
Ingresar a la dirección del sistema con un navegador
P P P
Pantalla de bienvenida
Ver contenido de la pantalla P P P
Reproducir video de bienvenida P P P
Abrir ventana de inicio de sesión y registro de usuarios al pulsar el botón "Comenzar"
P P P
Si ya se ha iniciado sesión, dirigirse a la pantalla de inicio al pulsar el botón "Comenzar"
P P P
Pantalla de inicio de sesión y registro de usuarios
Ver contenido de la pantalla P P P
Alternar entre las pantallas de inicio de sesión y registro de usuarios con los botones "Registrarse" y "Cancelar"
P P P
Validar campos de texto del formulario P P P Validación por cliente y servidor
Permitir el acceso al sistema al pulsar el botón "Ingresar" si se ingresaron las credenciales correctas
P P P
Denegar el acceso al sistema al pulsar el botón "Ingresar" si se ingresaron credenciales incorrectas
P P P
Registrar un nuevo usuario al pulsar el botón "Crear Cuenta" si la validación de campos de texto pasa
P P P
No registrar un nuevo usuario al pulsar el botón "Crear Cuenta" si la validación de campos de texto falla
P P P
Dirigirse a la pantalla de inicio después de iniciar sesión o registrarse exitosamente
P P P
88
Pantalla de inicio (index)
Ver contenido de la pantalla P P P
Dirigirse al último contenido visitado pulsando el botón "Continuar"
P P P
Mostrar u ocultar las preguntas y ejercicios de un capitulo o subcapítulo con los botones "+" y "-"
P P P
Dirigirse a una lección, pregunta o ejercicio especifico al pulsar sobre su botón correspondiente
P P P
Permitir el acceso a una lección, pregunta o ejercicio si se han completado todas las actividades previas
P P P
Denegar el acceso a una lección, pregunta o ejercicio si no se han completado todas las actividades previas
P P P
Menú de navegación superior
Ver el menú de navegación y su contenido en todas las pantallas del sistema
P P P El logo cambia dependiendo el dispositivo
Dirigirse a la pantalla de inicio al pulsar sobre el logo del sistema
P P P
Dirigirse a la pantalla de inicio al pulsar sobre el botón "Inicio"
P P P El nombre del botón está en el tooltip
Dirigirse a la pantalla de perfil de usuario al pulsar sobre el botón "Mi Perfil"
P P P El nombre del botón está en el tooltip
Dirigirse a la pantalla de bienvenida y cerrar sesión al pulsar el botón "Salir"
P P P El nombre del botón está en el tooltip
Menú de navegación inferior
Ver el menú de navegación y su contenido en todas las pantallas de lección, pregunta y ejercicio
P P P
Dirigirse a la siguiente lección, pregunta o ejercicio al pulsar el botón "Siguiente"
P P P
Dirigirse a la anterior lección, pregunta o ejercicio al pulsar el botón "Anterior"
P P P
Permitir el acceso al contenido con el botón "Siguiente" si la pregunta o ejercicio fueron contestados correctamente
P P P
Denegar el acceso al contenido con el botón "Siguiente" si la pregunta o ejercicio fueron contestados incorrectamente
P P P
Dirigirse a la pantalla de finalización con el botón "Siguiente" en el último contenido del curso
P P P
Dirigirse a la pantalla de inicio con el botón "Anterior" al encontrarse en el primer contenido del curso
P P P
89
Pantalla de perfil de usuario
Ver contenido de la pantalla P P P
Ver la información actual del usuario P P P
Validar campos de texto de los formularios P P P Validación solo por servidor
Actualizar la información del usuario al pulsar el botón "Actualizar Datos"
P P P
Actualizar la contraseña del usuario al pulsar el botón "Cambiar Contraseña" si la validación de campos de texto pasa
P P P
No actualizar la contraseña del usuario al pulsar el botón "Cambiar Contraseña" si la validación de campos de texto falla
P P P
Dirigirse a la pantalla de inicio después de completar un proceso de actualización
P P P
Pantalla de lección
Ver contenido de la pantalla P P P
Reproducir video de la lección P P P En computador el video se reproduce automáticamente
Pantalla de pregunta
Ver contenido de la pantalla P P P
Ver nombre, descripción y opciones de respuestas de la pregunta
P P P
Seleccionar una opción de respuesta pulsando sobre ella
P P P
Verificar la opción de respuesta seleccionada al pulsar el botón "Verificar Respuesta"
P P P
Mostrar mensaje de éxito al verificar una respuesta correcta
P P P
Mostrar un mensaje de fallo al verificar una respuesta incorrecta
P P P
Pantalla de ejercicio
Ver contenido de la pantalla P P P
Ver nombre y descripción del ejercicio P P P
Mostrar u ocultar consejos al pulsar el botón "Ver Consejos"
P P P
Escribir código en el cuadro de respuesta P P P
El cuadro se expande automáticamente dependiendo el texto
Verificar el código ingresado al pulsar el botón "Verificar Respuesta"
P P P
Mostrar mensaje de éxito al verificar una respuesta correcta
P P P
90
Mostrar un mensaje de fallo al verificar una respuesta incorrecta
P P P
Pantalla de encuesta
Ver contenido de la pantalla P P P
Pre cargar el email del usuario en la encuesta
P P P No se puede evitar que el usuario borre su email si lo desea
Contestar las preguntas de la encuesta P P P La pantalla se desborda en un dispositivo pequeño
Enviar la encuesta P P P
Mostrar el botón "Continuar" al pulsar el botón "No" en la pregunta "¿Olvidaste enviar la encuesta?"
P P P Esto no garantiza que el usuario haya enviado la encuesta
Desplazar la pantalla hacia la parte superior al pulsar el botón "Si" en la pregunta "¿Olvidaste enviar la encuesta?"
P P P Esto no garantiza que el usuario haya enviado la encuesta
Dirigirse a la pantalla de finalización al pulsar el botón "Continuar"
P P P
Pantalla de finalización
Ver contenido de la pantalla
Ver el número de intentos por contestar preguntas y ejercicios del usuario
Ver las recomendaciones finales
Ver los recursos para aprender más de Test Driven Development
Abrir una ventana nueva al pulsar un recurso para prender más de TDD
Tabla 15. Detalle de pruebas end-to-end del sistema TDD School
Fuente: Autoría propia
top related