Mostrando las entradas con la etiqueta Code Review. Mostrar todas las entradas
Mostrando las entradas con la etiqueta Code Review. Mostrar todas las entradas

viernes, agosto 14, 2009

Introducción al TDD I

Pruebas unitarias

Introducción:


El diseño de un software es un factor muy importante pues afecta a todo el ciclo de vida del desarrollo y la calidad del software creado. Un buen diseño permite al sistema satisfacer principalmente los requisitos funcionales pero también los no funcionales como mantenibilidad, seguridad, performance, usabilidad etc. Existen varias técnicas de diseño cada una con sus características particulares. En este artículo vamos a describir los aspectos fundamentales del desarrollo de software basado en pruebas (TDD; por sus siglas en inglés).
Por lo tanto TDD no es una metodología de pruebas sino de diseño donde se comienza con el diseño y desarrollo de los casos de pruebas y luego con la implementación del código funcional hasta que las pruebas se puedan ejecutar sin errores.
Los casos de prueba además sirven para especificar los casos de uso en formato ejecutable y esta técnica permite diseñar el software en niveles de abstracción desde una granularidad chica hasta la más grande.

Beneficios de realizar las pruebas unitarias:

En cuanto al código
  • Es fácil de mantener.
  • Se torna más comprensible.
  • Tiende a estar mejor diseñado.
  • Antes de escribir código, fuerzan a detallar los requisitos de una manera útil.
  • Mientras escribe el código, evitan un exceso de funcionalidad. Cuando se pasan todos los casos de prueba, la función está completa.
  • Cuando se hace refactorización de código, aseguran que la nueva versión se comporta de la misma manera que la antigua.
  • Cuando se mantiene código, ayudan a asegurar que los cambios no alterarán código ajeno.
  • Cuando se escribe código en equipo, aumenta la confianza en que el código que se está a punto de enviar no va a romper el de otras personas, porque se pueden ejecutar las pruebas unitarias de ellos antes.
  • Los test unitarios actúan como documentación.
  • El conjunto de test unitarios proporciona constante retroalimentación de cada uno de los componentes.
  • La detección de errores se ve facilitada.
  • El tiempo de depuración se reduce.
  • El conjunto de tests actúa como una red de seguridad contra regresiones en los bugs.

Características de un buen Test:

  • Un test debe probar el qué y no el cómo, debe asegurarse que la funcionalidad del código a probar se cumpla en forma correcta y no prestar atención a como lo logra.
  • Es muy limitado en su alcance.
  • Se ejecuta y sucede de manera independiente.
  • Revela claramente su intención.
  • Debe poder ser ejecutado en forma automática cada vez que se modifique el código probado.
  • Usa ha menudo stubs y mock objects.
Desventajas de las pruebas unitarias manuales.

  • Se puede escribir una aplicación de prueba para hacer el testing. Si luego de varias semanas se quiere volver a hacer el testing el código ha sufrido tantas modificaciones que seguramente la aplicaciónd e prueba inicial ya no sirva y tenga que volver a construirse.
  • En proyectos grandes podrá haber decenas de clases y muchas librerias.Es muy dificil escribir pruebas separadas por cada una de las clases en el proyecto y mantener todas ellas para futuros pruebas.
  • Probar apliaciones requiere un tester humano.Se puede probar varias posibilidades al principio, pero es dificil recordar todos los casos para repetir en el futuro, se deberían documentar aparte teniendo que mantener los casos de pruebas y la documentación.
  • Cuando la prueba es manual, el tester debe verificar el resultado de la misma y por lo tanto deber tener todo el conjunto de resultados posibles para cada prueba
  • Es muy poco practico repetir todo el tiempo todos los casos manualmente antes de que salga un release. Esto llevaria muchas horas o días para completar las pruebas unitarias de todas las piezas de código.
  • La ejecución de pruebas unitaria en forma manual es muy tedioso y tendiente a errores.
  • Utilizando Test Driven Development TDD las pruebas son automáticas y autodocumentadas.

Herramientas

Existen en el mercado muchas herramientas que permiten realizar pruebas unitarias, la mas utilizadas son

Herramienta
Plataforma
Comentarios
NUnit
http://www.nunit.org/
.Net Framework 1.0,1.1,2.0
Free, modo consola o interface gráfica
TestDriven

http://www.testdriven.net/


.Net Framework1.0,1.1,2.0,3.0
Misma funcionalidad del NUnit como adin del VS.net.Los resultados se visulizan en modo texto en el VS.Net
JUnit

http://www.junit.org/


Java
Stand alone o integrado a varios IDEs (Eclipse, java Builder etc)
vbUnit

http://www.vbunit.com/


Visual Basic 6.0
Comercial, integrada con el VS VB 6.0
ASPUnit

http://aspunit.sourceforge.net/


ASP.Net
Permite realizar casos de prueba para el front end de ASP.Net (proyecto open source suspendido)
TFS
http://msdn.microsoft.com/en-us/teamsystem/default.aspx


.Net framework 2.0,3.0 y 3.5
Integrado con algunas versiones del Visual Studio Team System 2005/2008.
SoapUI
http://www.soapui.org

Java
Permite ejecutar pruebas unitarias de consultas SOAP y REST.

SUNit
http:\\sunit.sourceforge.net

Smaltak
El padre de todas las herramientas xUnit.

Conclusión

Las pruebas unitarias son un tema muy importante para garantizar la calidad del código que estamos creando. Usando una metodología de diseño y herramientas adecuadas este proceso se podría integrar para que en forma automática se ejecuten las pruebas unitarias ante cada subida al repositorio de código centralizado.Para ello se debería integrar con sistemas de control de versiones. Agregando un sistema de revisión de código automática junto se puede garantizar la alineación del código a estándares de codificación que mitigan problemas comunes de la aplicación de malas prácticas. Este tema está fuera del alcance del TDD pero si de las metodologías de desarrollo.

Referencias


  1. Testing object-oriented systems: models, patterns, and tools, Addison-Wesley

  1. Continuous integration, Martin Fowler, http://martinfowler.com/articles/continuousIntegration.html

  1. Extreme Programming XP , http://xprogramming.com/index.php

  1. Introducción a Scrum, http://www.mountaingoatsoftware.com/scrum

  1. Agile Manifiesto, http://agilemanifesto.org/



viernes, junio 19, 2009

Diseño de arquitecturas I

Joseph Hofstader en el Architecure Journal N° 15 indica que el diseño de la arquitectura de un software tienen 4 aspectos: Conocimiento del dominio, conceptualización, habilidades técnicas y habiidades para aplicar patrones. Los dos primero sería la etapa de definicion del problema y las dos ultimas formaria la etapa de desarrollo dela solución.

Indica que el conocimiento de la tecnología no los unico a manejar para diseñar aplcaciones robustas, pero si es una habilidad muy importante que tiene que tener el arquitecto de software. Dentro de la empresa se recomienda trabajar con la menor cantidad de tecnologias posibles, esto permite administrar el esfuerzo del desarrollo en forma más eficiente, reduciendo la cantidad de herramientas de administración, desarrollo monitoreo etc, teniendo grupos con menos perfiles técnicos etc .
Algunos de los los aspectos de calidad a tener en cuanta al momento de diseñar la arquitectura base de un sistema son altamente influenciado por la forma en que se implementa el diseño a nivel código. Por ejemplos aspectos de seguridad, performance y mantenimiento son altamente degradados sin se desarrolla sin seguir buenas practicas y aplicar patrones.
Para ello se debe tener adecuados controles de calidad, testear el codigo en forma periodica, dependiendo de la metodología de desarrollo adoptada, la integración continúa mediante el uso de herramientas permiten controlar al final del día que el código subido al repositorio notiene errores de compilación y además se pueden ejecutar revisione de código y pruebas unitarias automáticas. Si con esto se generar reportes se puede controlar día a día la calidad del código que se está generado.

Si no hacemos esto, cuando el codigo pasa a testing funcional, nos encotramos con cosas como SQL Harcodeados, store procedures gigantescos que no tienen ningun tipo de control en la cantidad de registros a enviar al cliente, armado de documentos (xml u otros tipo) concatenados strings (System.String) y en el peor de los casos codigo "chorizo" practimente imposible de mantener, datos de conexión harcodeados (aunque no lo crean) etc etc.

No se imaginan los problema de reworking y troubleshuting que surgen cuando se produce un incidencia con alguna de esas aplicaciones.