Eligiendo un escenario de deploy para una nueva instalación de TFS 2010

por Victor Passador  29. noviembre 2010

Recientemente, un cliente nos comenta la decisión de incorporar TFS en la empresa como solución ALM.

El desafío que se planteaba era interesante, tenían un proceso medianamente ordenado pero cada uno de los roles involucrados utilizaba sus propias herramientas (algunas de ellas manuales) para administrar los documentos que se generaban, por lo que además de la diversidad de formatos, no existía sincronización entre esos documentos. Mucho menos pensar en algún tipo de versionamiento o workflow de aprobación.

Por su parte, el equipo de desarrollo recibía quejas constantes originadas en el cliente/usuario que apuntaban a la baja calidad del producto entregado. ¿Cómo era esto posible si el equipo contaba con recursos altamente capacitados?. Claramente el problema venía del lado de la mala administración del código fuente.

Con estas limitaciones en la gestión de los diferentes proyectos quedaba claro que no se podía contar con casi ningún tipo de métrica, gráfico o reporte que mostrara el grado de avance (o retroceso…). Tampoco existía la posibilidad de obtener algún indicador que permitiera la detección temprana de desviaciones.

Si bien la decisión estaba tomada, se reconocía asimismo la existencia de algún temor ante la imposibilidad de adaptarse a esta nueva herramienta que se presentaba como un gigante indomable frente a aquellas otras a las que conocían desde hace mucho tiempo. Iríamos por una cambio gradual.

En resumen, se requería una incorporación gradual de TFS al proceso de la empresa, pero con una visión de mediano/largo plazo que escale correctamente a medida que se vayan obteniendo resultados y que se vayan incorporando otras áreas y recursos de la empresa a esta nueva forma de integración. Por lo tanto, teníamos que lograr resultados rápidamente para convencer a los grupos más escépticos y a la vez estar preparados para cuando éstos decidan subirse al nuevo barco.

Arquitectura de servidores

Estaba claro que tanto las bases de datos (Data Services), como los reportes (Reporting Services, Analysis Services), serían instalados en un servidor dedicado distinto al que se usaría como Application Tier. En caso de detectar problemas de performance originados en el Data Tier, podríamos escalar utilizando SQL Server clusters.

Lo nuevo de todo esto es que con la versión 2010 de TFS también podemos escalar el Application Tier. Aparece aquí el nuevo concepto de TFS Farm.

Con esta nueva posibilidad, podemos agregar un nuevo servidor a nuestra Application Tier si se diera alguna de estas situaciones:

  • Necesidad de redundancia en la instalación de TFS
  • Necesidad de mejora de performance
  • Necesidad de restaurar un servidor que ha fallado
  • Necesidad de mover una instalación a otro servidor

 

Con esta arquitectura obtendríamos estos dos importantes beneficios:

  • Soporte de NLB (Network Load Balancing) en Application Tiers: Además de la mejora en performance, obtendremos alta disponibilidad, ya que podría caerse uno de los servidores sin que el usuario se entere. También podríamos aplicar parches individualmente a cada servidor poniéndolo offline sin desconectar a los usuarios.
  • Escalabilidad en Data Tiers: Teniendo más de un servidor SQL, tendremos más flexibilidad, ya que como cada Team Project Collection está en una base de datos independiente, podremos hostearlo como mejor nos convenga.

 

Un tema resuelto.

Organización de los proyectos

Habiendo relevado poco y nada a nivel global, no estaba del todo claro cómo íbamos a organizar los proyectos, y como el cliente no conocía TFS, no podía colaborar demasiado en determinar si usaríamos un sólo Team Project a nivel global y nos manejaríamos con áreas de proyecto para separar sectores (lo que implicaba un trabajo importante de personalización de templates de proyecto) o un Team Project por sector.

Finalmente nos decidimos por esta última opción, ya que si bien no estaba perfectamente delimitado, cada sector de la empresa se dedicaba casi exclusivamente a un sólo producto de software. Con esto, más algunos toques a las queries de work items, podríamos resolver las cuestiones más urgentes y en caso de necesitar un nivel de agrupamiento más alto, tendríamos la posibilidad de armar otras Project Collections.

Otro tema resuelto.

Final abierto (o no tanto …)

Al ser una instalación limpia, fue bastante sencilla y rápida la instalación de los diferentes componentes y la creación del Team Project que utilizaría, inicialmente, el sector que planteó los requerimientos.

Terminada la instalación, y habiendo logrado que los diferentes roles de ese sector pudieran …

… manejar documentos versionados utilizando el Project Portal como punto de acceso y que además, registren requerimientos en un repositorio común,

… que los desarrolladores puedan asociar el código fuente a cada uno de esos nuevos requerimientos y que además tengan la posibilidad de corregir bugs de versiones en producción al mismo tiempo que se desarrollan features de la nueva versión sin que eso implique un riesgo de regresión (gracias a un plan sencillo de branching),

… que se empiecen a generar los primeros reportes de trabajo pendiente y de estado de bugs,

todo esto con una solución (relativamente) sencilla y a la vez escalable, no es difícil imaginar cuál va a ser la reacción de los otros sectores de la empresa.

Hasta la próxima.

Tags:

Gestión de Proyectos | TFS | ALM

Reportes Agiles en Team Foundation Server – Stories Progress Report

por Viviana Chelini  25. noviembre 2010
Última entrega sobre comentarios de reportes ágiles, debajo está la lista de comentarios que hemos ido realizando:

Bug Status Report

Bug Trend Report

Reactivation Report

Build Quality Indicators Report

Burndown and Burn Rate Report

Remaining Work Report

Status on All Iterations Report

Stories Overview Report

 

Stories Progress Report

 

Información que proporciona el reporte

El reporte de Progreso de los Casos de Uso muestra el estado de realización determinado por las tareas definidas para implementar el mismo.

 

Este informe muestra para cada caso de uso, la siguiente información:

 

  • Progreso (% completado): valor numérico que representa el porcentaje de trabajo completado.
  • Horas completadas: representación visual de las horas completadas, que se muestra como una barra de color verde oscuro.
  • Completado recientemente: representación visual de las horas completadas en el intervalo de tiempo especificado para Días recientes (calendario), que se muestra como una barra de color verde claro.
  • Horas restantes: Horas restantes correspondientes a todas las tareas vinculadas al caso de uso o sus casos secundarios.

 

Para que el reporte sea fiable se deben de alimentar correctamente los siguientes parámetros de los elementos de trabajo:

  • Definir los casos de uso y las tareas, crear un vínculo Secundario de cada tarea al caso que implementa y crear un vínculo Secundario de las subtareas a su tarea primaria.
  • Definir y actualizar los campos Completado y Restante para cada tarea o subtarea durante la iteración o el lanzamiento.
  • Especificar las rutas de acceso de Iteración y Área para cada caso y tarea.

Análisis del reporte

El reporte permite visualizar el volumen de trabajo realizado por el equipo durante la última semana o un período de tiempo reciente. Se puede encontrar respuestas a las siguientes preguntas:

  • ¿En qué casos el equipo progresó y cuáles están a punto de completarse?
  • ¿En qué casos no ha trabajado el equipo?
  • ¿A qué casos de uso les queda el mayor volumen de trabajo para completarse?
  • ¿Hay trabajo bloqueado en algún caso?

    Los casos que no muestran una banda de color verde claro en la barra de progreso pueden indicar un problema de bloqueo.

  • ¿Se puede entregar todo lo que se ha planeado? ¿Qué objetivos se deben suprimir y cuáles deben ser objeto de un cambio de ámbito?

 

Versión positiva del reporte

Un reporte positivo muestra que el equipo ha completado recientemente trabajo (color verde claro) en todos los casos que se espera estén en curso.

Versión negativa del reporte

Un reporte negativo podría mostrar una o más de los siguientes indicadores:

  • No se muestra trabajo en uno o varios casos.

    Los casos con 0% de progreso o 0 horas restantes no tienen definido esfuerzo previsto ni tareas para ellos.

  • Muchos casos de uso no tienen trabajo completado recientemente.

    Cuando varios casos indican ningún volumen o volúmenes muy pequeños de trabajo completado, el progreso del equipo es lento.

 

Charla - Automatización eficaz de Sistemas de Gestión de Calidad

por Daniel Laco  16. noviembre 2010

clip_image001

clip_image003

El Martes 30 de Novimebre realizaremos una charla en la Cámara de Industria y Comercio Argentino-Alemana sobre:

Automatización eficaz de Sistemas de Gestión de Calidad

Orador: Mg Patricia Scalzone
Scrum Master. Magister en Informática. Licenciada en Análisis de Sistemas. Docente Universitaria con amplia experiencia en la organización y conducción de grupos de trabajo. Reconocida impulsora de la adopción de normas de calidad y metodologías. Integrante de la Comisión de Calidad de CESSI (Cámara de Empresas de Software & Servicios Informáticos de la República Argentina). Presidente de VEMN S.A.

Resumen

La administración de un sistema de Gestión de Calidad basada en un modelo como ISO:9001 u otros, tiene sus particularidades en cada empresa que lo implementa.

El cumplimiento de la gestión documental, o el envío de avisos a los usuarios para tomar acción en cumplimento de los requisitos de las normas, son temas complejos a la hora de en la puesta en marcha del sistema.

Las empresas perciben estos procedimientos como un incremento burocrático a sus tareas diarias, produciendo finalmente el deterioro del sistema y un gran esfuerzo por parte de los responsables para mantenerlo en marcha.

En esta charla se presentará el caso real de nuestra empresa, en el cual la automatización del sistema de gestión de la calidad redujo el soporte en papel en más del 90%, se agilizaron los procesos, se registra la evidencia, integrando áreas que estaban como islas, con el uso de una plataforma tecnológica adecuada, en este caso Sharepoint como CMS (Content Management System).

Datos del Evento:

Martes, 30 de Noviembre de 2010

de 09:00 a 11:00 hrs.

en la Sala de Conferencias de la Cámara Argentino-Alemana,

Av. Corrientes 327, Piso 24, Buenos Aires.

La inscripción sin costo podrá efectuarse con:

Lucrecia Borchardt, lborchardt@ahkargentina.com.ar , Tel. 011-5219-4000

Cupos limitados.

Tags:

Eventos | General | Metodologías y Procesos | Sharepoint

Reportes Agiles en Team Foundation Server – Stories Overview Report

por Viviana Chelini  10. noviembre 2010

Siguiendo con los comentarios sobre los reportes ágiles de TFS 2010 iniciados en :

Bug Status Report

Bug Trend Report

Reactivation Report

Build Quality Indicators Report

Burndown and Burn Rate Report

Remaining Work Report

Status on All Iterations Report

 

Hoy comentaremos sobre:

Stories Overview Report (Agile)

El siguiente reporte muestra gráficamente información general sobre los casos de uso definido para una iteración o área determinada.

Información que proporciona el reporte

El reporte presenta una visión del trabajo realizado para el conjunto de casos de uso filtrados hasta la fecha actual.

Este reporte muestra la siguiente información sobre cada caso de uso:

Progreso del trabajo

  • % de horas completadas: un valor numérico y representación visual que muestra el porcentaje de trabajo completado.
  • Horas restantes: un valor numérico de todas las horas restantes para todas las tareas vinculadas al caso de uso o sus casos secundarios.

Estado de la prueba

  • Pruebas: un valor numérico que representa el número de casos de prueba vinculados al caso de uso o sus casos secundarios.
  • Resultados de pruebas: un valor numérico y representación visual que muestra el porcentaje de casos de prueba, agrupados según el estado de su ejecución de pruebas más reciente, donde las opciones son Superadas (verde), Con error (rojo) o Sin ejecutar (negro).
  • Errores: un valor numérico y representación visual que muestra el número de errores vinculados al caso de prueba o caso de uso, donde las opciones son Activa (azul) y Resuelto (oro).

El reporte de Información general enumera y resalta los casos según los siguientes criterios:

  • Los casos aparecen por orden de importancia, que está basado en su clasificación asignada.
  • Los casos aparecen en tipo en negrita cuando están en el estado activo o resuelto.
  • Los casos aparecen en tipo normal cuando están en el estado cerrado.
  • Los casos aparecen en tipo gris cuando su iteración o área asignada está fuera del conjunto filtrado, pero tienen tareas o casos secundarios que están dentro del conjunto filtrado de iteraciones o áreas de producto.

 

Para que el reporte sea fiable se deben de alimentar correctamente los siguientes parámetros de los elementos de trabajo:

  • Definir los casos de uso y tareas, crear un vínculo Secundario desde cada tarea a un caso de uso y crear un vínculo Secundario desde cualquier subtarea a su tarea primaria.
  • Definir y actualizar los campos Completado y Restante para cada tarea o subtarea durante la iteración o versión.
  • Definir los casos de prueba y crear el vínculo Prueba realiza por desde cada caso de prueba a un caso de uso.
  • Para cada error, crear el vínculo Prueba realiza por al caso de prueba que identificó el defecto de código o un vínculo Relacionado al caso de uso con el que está relacionado el error.
  • Establecer el Estado de cada error en Resuelto cuando se corrija.
  • Especificar las rutas de acceso Área e Iteración para cada caso, tarea, caso de prueba y error.

 

Análisis del reporte

El reporte de Información general muestra el progreso de trabajo global en tres áreas que son importantes para completar y cerrar un caso de uso:

  • Tareas implementadas para completar el caso de uso.
  • Casos de prueba ejecutados para asegurar la calidad de los casos implementados.
  • Errores identificados que indican los problemas con la calidad de los casos de uso.
Progreso del trabajo
  • ¿Corresponde a sus expectativas la cantidad de trabajo que resta para cada caso de uso?
  • ¿Se implementan primero los casos de uso clasificados según su relevancia?
  • ¿Cuántas pruebas se definen para cada caso de uso?¿Cuántas pruebas se superan?
  • ¿Qué casos de uso se implementan que no tienen ningún caso de prueba definido para ellos?
Progreso de la calidad
  • ¿Cuántos casos de prueba se han ejecutado para cada caso de uso y cuántos han superado las pruebas?
  • ¿Cuántos errores activos tiene cada caso de uso?
  • ¿Se encuentran errores para los casos de uso que se prueban?
  • ¿Se resuelven los errores o siguen activos?
Evaluación de riesgo
  • ¿Qué casos de uso están en riesgo?
  • ¿Qué casos de uso no son suficientemente estables para la versión?
  • ¿Qué casos de uso puede distribuir hoy el equipo?

 

Versión positiva del reporte

Un reporte positivo muestra más progreso en los casos de uso que aparecen cerca de la parte superior del reporte. En la imagen que se muestra a continuación se visualiza que el equipo ha realizado más trabajo para los casos que aparecen en el reporte.

 

 

Versión negativa del reporte

Un reporte negativo muestra una o más de los siguientes indicadores:

  • El equipo está realizando más progreso en los casos de uso que tienen un rango inferior que en los que tienen un rango superior.
  • Hay más pruebas con errores que superadas.
  • Se producen errores en las pruebas para un caso de uso, pero no se crea ningún elemento de trabajo de error.

 

Hasta la próxima.

 

Tags: , ,

ASP.NET | Javascript | ORM | TFS

Reportes Agiles en Team Foundation Server – Status on All Iterations Report

por Viviana Chelini  4. noviembre 2010

Siguiendo con los comentarios sobre los reportes ágiles de TFS 2010 iniciados en :

Bug Status Report

Bug Trend Report

Reactivation Report

Build Quality Indicators Report

Burndown and Burn Rate Report

Remaining Work Report

 

Hoy nos toca comentar un nuevo reporte.

Status on All Iterations Report

Este reporte permite realizar un seguimiento del rendimiento del equipo sobre las iteraciones en las que ha participado.

Información que proporciona el reporte

 

El reporte de estado muestra para cada iteración especificada la siguiente información:

  • Casos de Uso cerrados: número de casos de uso que se han cerrado.
  • Progreso (Horas): representación visual y numérica en dos barras que representa los valores para Estimación original (gris), Completado (verde) y Restante (azul claro) basados en el número acumulado de horas que se definen para todas las tareas.
  • Errores: valor numérico y representación visual para todos los errores, agrupados por sus estados actuales de Activo (azul), Resuelto (oro) y Cerrado (verde).Estos valores se derivan de los valores actuales que se especifican durante la iteración y el estado de cada error.

 

Para que el reporte sea fiable se deben de alimentar correctamente los siguientes parámetros de los elementos de trabajo:

  • Definir casos de uso, tareas y errores y especificar las rutas de acceso de Área e Iteración para cada uno.
  • Especificar los campos Estimación original, Completado y Restante para cada tarea o subtarea y actualizar los campos Completado y Restante durante la iteración.
  • Actualizar el Estado de cada artículo, tarea y error cuando progrese de estado activo a cerrado.

 

Análisis del reporte

El reporte permite determinar cuántos casos de uso están listos para la versión comercial y comprender mejor la tasa de progreso del equipo. El reporte permite encontrar respuestas a las siguientes preguntas:

 

  • ¿Coincidió el ámbito de trabajo para cada iteración con la capacidad del equipo?
  • ¿El número de casos de uso cerrados son los esperados por iteración?
  • ¿Está el equipo resolviendo y cerrando más errores?
  • ¿Cuántos casos de uso puede distribuir el equipo?

 

Versión positiva del reporte

En un reporte de estado de iteraciones positivo muestra un progreso de horas a medida que transcurren iteraciones.

 

Versión negativa del reporte

Un reporte de estado negativo podría mostrar uno o más de los siguientes indicadores:

  • No se cerró ningún caso de uso en una o más iteraciones.
  • El número de horas estimadas y completadas varía ampliamente dentro de las iteraciones o entre ellas.
  • El número de errores encontrados no aumenta con cada iteración sucesiva.

     

 

Hasta la próxima.

 

Extendiendo TFS 2010 – Manejo de Eventos

por Victor Passador  1. noviembre 2010

Quisiera abordar en esta oportunidad algún ejemplo de cómo se puede extender, de una manera relativamente sencilla, la funcionalidad de TFS para adaptarlo a necesidades concretas y reales que aparecen diariamente.

Hay varias maneras de extender TFS, pero en esta ocasión, me voy a centrar en el manejo de eventos y sus particularidades y como dije que se puede hacer de manera “relativamente” sencilla, voy a intentar hacerlo en sólo dos pasos:

  1. Escribiendo un servicio web que actualice una base de datos propia con información proveniente de un Work Item modificado.
  2. Eligiendo un evento al que nos vamos a suscribir y vinculándolo con el servicio web.

 

Veamos cómo sale.

Paso 1: El servicio web

El subsistema de eventos de TFS soporta notificaciones basadas en mensajes SOAP, por lo que sólo tendremos que crear un proyecto de tipo Web Service ASP.NET que contenga un método llamado “Notify” y que reciba dos parámetros:

  • eventXml: Es el Work Item serializado. Contiene información acerca de aquellos campos que han cambiado, manteniendo el viejo valor y el nuevo luego de la modificación.
  • tfsIdentityXml: Podemos obtener a través de este parámetro, la URL del servidor TFS que ha realizado la llamada

 

Aquí debajo encontrarán el código del esqueleto del servicio. Sólo restará parsear el work item para obtener la información que nos interese y utilizar ADO.NET o la técnica que prefieran para actualizar la base de datos.

   1: namespace VEMN.ExtendiendoTFS.WebService
   2: {
   3:     [WebService(Namespace = "http://schemas.microsoft.com/TeamFoundation/2005/06/Services/Notification/Extensibility", Description = "")]
   4:     [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
   5:     public class MiServicio : EndpointBase
   6:     {
   7:         [WebMethod]
   8:         [SoapDocumentMethod("http://schemas.microsoft.com/TeamFoundation/2005/06/Services/Notification/03/Notify", RequestNamespace = "http://schemas.microsoft.com/TeamFoundation/2005/06/Services/Notification/03")]
   9:         public void Notify(string eventXml, string tfsIdentityXml)
  10:         {
  11:  
  12:             // Parsing del work item serializado
  13:  
  14:             // Actualización de la Base de Datos
  15:  
  16:         }
  17:     }
  18: }
   1: namespace VEMN.ExtendiendoTFS.WebService
   2: {
   3:     public class EndpointBase : WebService
   4:     {
   5:         /// <summary>
   6:         /// Deserializes a Type
   7:         /// </summary>
   8:         /// <typeparam name="T">Type to deserialize</typeparam>
   9:         /// <param name="serializedType">serialized version of the type</param>
  10:         /// <returns>DeSerialized version of the type</returns>
  11:         protected T CreateInstance<T>(string serializedType) where T : new()
  12:         {
  13:             T customType = new T();
  14:  
  15:             XmlSerializer serializer = new XmlSerializer(typeof(T));
  16:  
  17:             XmlDocument xmlDocument = new XmlDocument();
  18:             xmlDocument.LoadXml(serializedType);
  19:             XmlNodeReader xmlNodeReader = new XmlNodeReader(xmlDocument);
  20:  
  21:             customType = (T)serializer.Deserialize(xmlNodeReader);
  22:  
  23:             return customType;
  24:         }
  25:     }
  26: }

Paso 2: El evento y la suscripción

El subsistema de eventos de TFS nos permite suscribir a los siguientes sucesos:

Build Completion Event

NodesDeletedEvent

Build Status Changed Event

ProjectCreatedEvent

BranchMovedEvent

ProjectDeletedEvent

NodeCreatedEvent

CheckinEvent

NodePropertiesChangedEvent

WorkItemChanged

NodeRenamedEvent

 

La manera de asociar un evento de TFS al servicio que escribimos en el paso 1, es utilizando el comando “BisSubscribe”. Obviamente nos vamos a “colgar” del evento WorkItemChanged.

La manera de hacerlo es la siguiente:

   1: BisSubscribe.exe /eventType WorkItemChangedEvent /deliveryType Soap /address http://tfsserver/WebService/MiServicio.asmx /collection http://tfsserver:8080/tfs/defaultcollection

Algo a tener en cuenta es que, con la aparición de las Project Collections en TFS 2010, debemos utilizar el parámetro “/collection” del commando BisSubscribe en lugar del parámetro “/server” que se usaba en TFS 2008

Sintonía fina

Habiendo publicado el servicio web y estando suscriptos al evento, sólo restará probar toda la maquinaria actualizando algún Work Item y grabando los cambios. No deberá sorprendernos que la llamada al web service no se haga de manera inmediata. Transcurrirán al menos 2 minutos desde la actualización del Work Item hasta que el método “Notify” sea invocado.

Esto es porque a partir de la versión 2010 de TFS se han optimizado muchos procesos, y en esta línea de mejoras, algunas tareas que antes se hacían de manera sincrónica ahora se realizan asincrónicamente.

Este valor de delay fue establecido pensando en servidores que tienen una alta carga de procesamiento y que atienden gran cantidad de usuarios simultáneamente. Con equipos de trabajo más chicos (unos 10 usuarios simultáneos) tranquilamente se puede bajar ese tiempo a 30 segundos sin notar pérdida de performance. Inclusive es posible llevarlo a cero con el mismo resultado.

Para realizar este cambio, tendremos que utilizar la consola de Power Shell con el siguiente script:

   1: [Reflection.Assembly]::Load("Microsoft.TeamFoundation.Client, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")
   2:  
   3:  
   4:  
   5: # Modify the TFS configuration server URL as necessary.
   6:  
   7: $configServer = new-object Microsoft.TeamFoundation.Client.TfsConfigurationServer "http://tfsserver:8080/tfs/"
   8:  
   9:  
  10:  
  11: # Get the TF registry service.
  12:  
  13: $tfsRegService = $configServer.GetService([Microsoft.TeamFoundation.Framework.Client.ITeamFoundationRegistry])
  14:  
  15:  
  16:  
  17: # Set the notification delay to 30 seconds. All collections will use this delay unless they override this value in the collection hive.
  18:  
  19: $tfsRegService.SetValue("/Service/Integration/Settings/NotificationJobDelay", 30)
  20:  

En este ejemplo se baja el tiempo a 30 segundos. Encontrarán que es muy sencillo modificarlo por el valor que consideren más apropiado.

Haciendo la vida un poco más fácil (todavía)

El comando “BisSubscribe” es bastante críptico. Si cometemos algún error de tipeo al utilizar el comando y el web service no es invocado por culpa de ese error, no será sencillo hallar la solución sin ayuda adicional.

Para no perecer en esa tarea, podemos valernos del plug-in denominado “Alerts Explorer” para Visual Studio que viene con las Team Foundation Server Power Tools, que nos permitirá administrar esas suscripciones utilizando una GUI muy amigable e intuitiva.

image

Hasta la próxima !

Tags: , ,

ALM | TFS

Acerca de los Autores

Este es el blog del equipo de VEMN SA 
Presentaremos temas que nos parezcan de interés sobre tecnología .NET, Procesos y Metodologías y todo aquello relacionado con el proceso de desarrollo de Software

Month List