SharePoint 2010 y ALM (II)

Hace unas semanas comencé una serie de artículos sobre ALM y SharePoint 2010. Después de haber realizado tres eventos presenciales al respecto y de haber recogido vuestro feedback en relación a los puntos que más os interesaban sigo con la lista de artículos que tenía prevista.

Como os decía en la primera entrada introductoria, dos de los elementos fundamentales a tener en cuenta a la hora de plantearnos la gestión del ciclo de vida de nuestras aplicaciones son los procesos que llevaremos a cabo y las herramientas que utilizaremos para hacerlo. En este segundo artículo quiero reflexionar, precisamente, de las herramientas que nos pueden ayudar en el camino para mejorar la calidad de nuestros proyectos sobre SharePoint 2010.

El primer nombre de nos tiene que venir a la cabeza cuando hablamos de ALM y de SharePoint 2010 es Team Foundation Server. Es un producto de Microsoft, al igual que SharePoint, y seguramente será el que mejor se integre con esta plataforma. Además es una suite completa que nos va a ayudar en todas las fases del desarrollo, desde la gestión inicial de los requerimientos a la gestión de las incidencias que aparezcan. Por otro lado, tenemos que tener en cuenta que es una herramienta con un coste elevado, que no quiere decir que sea un producto caro. Como siempre dependerá de si necesitamos o no todo lo que el producto nos ofrece y de si el producto cubre o no todas nuestras necesidades. Tened también en cuenta que cada criterio que escojamos para elegir una herramienta u otra tendrá una importancia determinada y una valoración relativa. Un ejemplo ilustrativo es el coste. No podemos centrarnos únicamente en lo que cuestan las licencias del software que vamos a utilizar, sino el tiempo que vamos a invertir en implementarla y lo que nos va a costar encontrar gente capacitada para hacerlo.

En mi opinión, la herramienta que escojamos será lo de menos, siempre y cuando cumplamos el objetivo de gestionar adecuadamente el ciclo de vida de nuestras aplicaciones. No hay una verdad absoluta que indique que tienes que elegir una herramienta determinada cuando se cumplen ciertas condiciones. En nuestro caso particular, tuvimos en cuenta los conocimientos del equipo técnico de diferentes herramientas y al final decidimos no utilizar TFS por las siguientes razones:

  1. Nuestro equipo técnico tenía más experiencia en otras herramientas
  2. El coste de la herramienta era demasiado elevado para asumirlo
  3. Necesitamos desarrollar aplicaciones para otros dispositivos como iPhone o Blackberry
  4. Necesitabamos tener todo montado en un corto espacio de tiempo

A partir de este momento hablaré, por lo tanto, de otras herramientas. En cualquier caso, en ningún momento desaconsejo el uso de TFS. Es más, si no conocéis otra alternativa que os satisfaga, siempre sería una opción recomendable. De hecho, si estáis interesados, os recomiento unos artículos de Chris o’Brien que os darán muchas pistas sobre cómo comenzar ()

Dicho esto, y para daros algún nombre, antes de descartar TFS tuvimos que buscar alternativas que nos permitieran gestionar el ciclo de vida de nuestras aplicaciones. Según el area de actuación, escogimos estas herramientas:

  • Pruebas unitarias y de aceptación: NUnit y NCover
  • Pruebas de aceptación: Cucumber y Capybara
  • Build Server: Jenkins y MSBuild
  • Gestión de requerimientos y de incidencias: Beezy

Como tampoco pretendo escribir la biblia del ALM, sino incidir en aquellos puntos de dolor a la hora de trabajar con SharePoint 2010, los siguientes artículos los destinaré a cubrir aquellas áreas que más nos van a ayudar a mejorar la calidad de nuestros proyectos SharePoint. De aquí a final de año escribiré sobre los siguientes temas:

  • Pruebas unitarias
  • Pruebas de aceptación
  • Automatización del despliegue

Si, además de estos tres puntos, estáis interesados en algo concreto sobre lo que habéis visto en las sesiones que he ido haciendo, no dudéis en ponerme un comentario y haré todo lo posible por escribir también algo al respecto.

Ojo al modificar tu servicio WCF…

Hoy he pasado un mal rato intentando solucionar un problema que, al final, era más simple de lo que parecía. Resulta que para cambiar una pequeña funcionalidad tuve que añadir un parámetro a uno de los métodos de un servicio WCF. El cambio vendría ser de lo siguiente:

[OperationContract,

WebGet(UriTemplate = "/MyMethod?parameter1={parameter1}",

       ResponseFormat = WebMessageFormat.Json)]

int MyMethod(int parameter1);

A lo siguiente:

[OperationContract,

WebGet(UriTemplate = "/MyMethod?parameter1={parameter1}",

       ResponseFormat = WebMessageFormat.Json)]

int MyMethod(int parameter1, int parameter2);

Bueno, pues que sepáis que hacer esto hacía que cualquier otro método de mi servicio dejara de funcionar con un error 401 (cortesía de SharePoint). Tras depurar el error vi que en realidad la causa de mi problema era que el método está declarado como GET y que en el UriTemplate no estaba especificando mi nuevo parámetro. Al final el método debería quedar así:

[OperationContract,

WebGet(UriTemplate = "/MyMethod?parameter1={parameter1}&parameter2={parameter2}",

       ResponseFormat = WebMessageFormat.Json)]

int MyMethod(int parameter1, int parameter2);

Sí, lo sé, es una chorrada de artículo y no sólo no aporto nada sino que os he hecho perder el tiempo a la mayoría, pero de alguna manera tenía que expulsar la mala leche que me ha entrado al descubrir el motivo de que mi sitio hubiera dejado de funcionar.

[EVENTO] SharePoint 2010 y ALM ¿Es posible?

Antes de que lo digáis, no, no es un dejavú. Será el tercer evento relacionado con SharePoint 2010 y ALM en muy poco tiempo, pero es un tema que merece la pena y seguiré insistiendo tanto como pueda en su importancia. Después de haber hecho un evento presencial en Barcelona y otro presencial en Andorra, le ha llegado el momento a la gente del SUGES (Grupo de Usuarios de SharePoint de España) para aguantarme una hora y media hablando de conceptos tales como calidad de software, pruebas unitarias y de integración, tests de aceptación o integración contínua y, evidentemente, siempre desde el punto de vista del profesional del mundo del SharePoint.

Sé que mezclar ambos mundos no es tarea sencilla, y sé que muchos de vosotros tendríais mucho que decir al respecto, tanto si trabajáis con SharePoint como si no, así que espero que se presente tanta gente como sea posible y me déis caña hasta en el carné de identidad.

Decir también que dejé parada la serie de artículos que tengo preparada relacionados con esta temática, justamente esperando a estos tres eventos, con la intención de recoger vuestro feedback y, sobretodo, vuestras dudas. Os invito, por tanto, a que vengáis y me expongáis aquellas cuestiones que más despierten vuestro interés. Además de responder todas las dudas que me sea posible, prometo escribir tantos artículos específicos como sea necesario para resolver todas las cuestiones que se abran.

Os dejo aquí más información del evento así como los links de registro.

SharePoint 2010, Servicios REST y Claims

Una de las cosas en las que estoy trabajando actualmente requería disponer de un servicio WCF REST para interactuar con SharePoint 2010. Este servicio se consumía mayoritariamente desde javascript via AJAX y no presentaba mayores problemas y hace un tiempo surgió la necesidad de hacer llamadas al mismo servicio desde diversos webparts y event receivers de manera que el punto de entrada al corazón de la aplicación fuera siempre el mismo. Todo parecía funcionar correctamente hasta que en una de las pruebas de despliegue detectamos un error extraño similar al siguiente:

The remote server returned an error: (400) Bad Request. Exception: System.Net.WebException: The remote server returned an error: (400) Bad Request.     at System.Net.WebClient.UploadDataInternal

Como el error en sí no era demasiado descriptivo metí unas cuantas trazas y utilicé algún que otro Fiddler para determinar la causa real del problema. Así es como di con el siguiente error:

Message: 403 FORBIDDEN

Perfecto, habíamos pasado de un Bad Request (400) a un Forbidden (403). Además tenía todo el sentido del mundo porque el error se daba únicamente en el entorno donde teníamos corriendo el código en una aplicación web con autenticación basada en Claims. Determinado el error y su más que probable causa, encontrar una solución era sólo cuestión de tiempo. Y la solución vino de la mano de Justin Kobel y de este artículo.

Aquí no sólo encontramos el código necesario para realizar las llamadas de manera adecuada, sino que se explica también cómo hacer para distinguir si estamos en una aplicación web clásica o en una basada en notificaciones. Yo tuve que cambiar algo el código para adaptarlo a mis necesidades pero la esencia es la misma y consiste en aprovechar la cabecera Cookie para nuestra llamada, tal y como muestra el siguiente listado.

webClient = new WebClient { Credentials = CredentialCache.DefaultNetworkCredentials };

webClient.Headers[HttpRequestHeader.ContentType] = "application/json";

 

IClaimsPrincipal principal = HttpContext.Current.User as IClaimsPrincipal;

if (principal != null)

{

   NameValueCollection headers = HttpContext.Current.Request.Headers;

   webClient.Headers["Cookie"] = headers["Cookie"];

}

 

var receivedData = webClient.UploadData(url, verb, memoryStream.ToArray());

var response = (T)jsonSerializer.ReadObject(new MemoryStream(receivedData));

Veréis que en un punto del artículo hace el autor se salta la validación de los certificados en el momento de la autenticación. Si queréis información sobre como hacer esto de manera adecuada, os recomiendo este artículo de mi compañero Jordi Ruiz.

[EVENTO] SharePoint 2010 y ALM

El próximo viernes día 25 de Noviembre tendré el placer de participar en un evento para el grupo AndorraDotNet. En dicho evento daré algunas ideas sobre cómo se puede mejorar la calidad y la mantenibilidad de nuestro trabajo cuando desarrollamos sobre SharePoint 2010.

Os dejo aquí un enlace con más información sobre el evento por si alguien se anima a acercarse a Andorra. Como siempre, no prometo nada sobre la calidad del ponente, pero se hará todo lo posible para que el tiempo que dediquéis esté bien invertido.

Novedades, eventos y demás…

Estas últimas semanas han sido un poco especiales. Entre los días de fiesta, los eventos y las certificaciones he andado más fuera de la oficina que dentro de ella. A modo de resumen, y también como recordatorio de lo que queda hasta fin de semana, deciros que la semana pasada se organizó el segundo evento presencial del Grupo de Usuarios de Catalunya de SharePoint (SUG.CAT) y del cual podéis descargar todo el material aquí. Aproveché también un momento de ocio para acercarme a un centro de certificaciones y sacarme, por fin, la certificación PRO de SharePoint 2010 Development que estaba pendiente desde hacía ya demasiados meses.

Por otro lado, mañana estaré en Madrid junto a algunos compañeros MVP de SharePoint, Proyect Server y Office 365 en el CEUS, en la sesión de Ask to the Experts de la tarde. Pasaré el día por allí así que si alguien quiere charlar seguro que podremos encontrar un hueco. De Madrid iré a Fuengirola a participar en los Community Days de Microsoft. Tanto de una cosa como de la otra, intentaré sacar algo de tiempo para escribir en este blog las experiencias que tenga.

Disponible la documentación del segundo evento presencial de SUG.CAT

Ya podéis descargar aquí toda la información sobre el evento presencial del pasado jueves 3 de Noviembre. Podréis encontrar las dos presentaciones que hicimos el compañero Edin Kapic y yo, así como la sesión completa grabada en video. En lo que a mí respecta, empiezo a concentrarme en ampliar aquellas partes de la presentación que quedaron poco desarrolladas en forma de artículos en este blog.

Si alguno de vosotros asistió al evento, o ha visto el video, y quiere información adicional sobre alguno de los puntos, que no dude en poner aquí un comentario para meterme presión Winking smile

Anidando CDATAs, o cómo no morir personalizando el CoreResultsWebPart

Cada vez que he tenido que hacer una personalización del elemento web de resultados de búsqueda de SharePoint (CoreResultsWebPart) me he encontrado con el mismo problema: el despliegue. La teoría es muy simple, sobre un sitio creado se edita el elemento web, se obtiene el valor del campo XSL, se edita con cualquier editor de XSL, se guarda el webpart con el nuevo valor de la propiedad hasta que obtenemos el resultado deseado y finalmente exportamos el elemento web para insertarlo donde nos convenga en nuestro paquete de despliegue.

¿Pero qué pasa cuando metemos variables en juego? En ocasiones tenemos que introducir valores multilenguaje o urls relativas a la colección de sitios en la que nos encontramos. Por cierto, si habéis llegado hasta aquí y no he despertado vuestro interés, o bien es por que tenéis totalmente resuelto este problema, o bien es porque no os habéis visto en la necesidad de crear algo productizable. Si, como digo, no he despertado vuestra curiosidad a estas alturas, os recomiendo no perder más tiempo en este artículo, ya escribiré cosas mejores Winking smile.

Bien, si seguís leyendo a estas alturas, imagino que estaréis esperando la fórmula mágica para hacer esta tarea un poquito más simple de lo habitual. Primero, dediquemos unas líneas al método tradicional. Una vez obtenido el valor para la propiedad XSL anteriormente mencionada, escapamos el código y lo insertamos en el XML de aprovisionamiento. Si habéis hecho esto en alguna ocasión, estaréis conmigo en que como se te escape algún pequeño error en este punto, depurarlo va a ser poco menos que imposible. Además, la próxima vez que hagas un cambio vas a tener que repetir todo el proceso. No sé a vosotros, pero a mí eso no me gusta nada de nada. Hasta hoy esto era un trance por el que tenía que pasar, pero el frotar se va a acabar…

Una solución, como habréis deducido del título del post, consiste en anidar CDATAs. Pero, ¡si no se puede! ¡si no está permitido según el estándar! Hoy he encontrado una solución muy original de un tal Nat Dunn y que podéis encontrar aquí. La solución consiste en utilizar el siguiente patrón, teniendo en cuenta que el primer CDATA contendría el elemento web y que el CDATA anidado contendría el valor de la propiedad XSL.

<![CDATA[

 

<![CDATA[<!-- Contenido del CDATA anidado -->]]]]><![CDATA[>

      

]]>

De acuerdo pero, ¿cómo queda esto al final? El siguiente listado muestra partes del fichero de aprovisionamiento con el que he hecho las pruebas. He dejado a propósito otra propiedad (SampleData) para demostrar las diferencias entre el modo habitual de tratar este tipo de propiedades y el modo que os estoy proponiendo.

<![CDATA[<webParts>

<webPart xmlns="http://schemas.microsoft.com/WebPart/v3">

  <metaData>

    <type name="..." />

  </metaData>

  <data>

    <properties>

      <property name="SampleData" type="string">&lt;All_Results&gt;

        &lt;Result&gt;

          &lt;workid&gt;1&lt;/workid&gt;

          &lt;rank&gt;222&lt;/rank&gt;

          &lt;title&gt;Title of document or web page&lt;/title&gt;

          &lt;author&gt;Author of document or web page&lt;/author&gt;

          &lt;size&gt;1025&lt;/size&gt;

          &lt;sitename&gt;http://www.sample.com&lt;/sitename&gt;

          &lt;url&gt;http://www.sample.com/folder/document.aspx&lt;/url&gt;

          &lt;imageurl&gt;/_layouts/images/aspx16.gif&lt;/imageurl&gt;

          &lt;description&gt;This is the summary of the document or web page. The summary is generated from the original document based on matches with query terms. In some cases, the summary is a description provided by the author.&lt;/description&gt;

          &lt;write&gt;December 26, 2004&lt;/write&gt;

        &lt;/Result&gt;

      &lt;/All_Results&gt;

      </property>

      <property name="Xsl" type="string">

        <![CDATA[

          <?xml version="1.0" encoding="iso-8859-1"?>

          <xsl:stylesheet version="1.0"

              xmlns:xsl="http://www.w3.org/1999/XSL/Transform"

              xmlns:srwrt="http://schemas.microsoft.com/WebParts/v3/searchresults/runtime"

              xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime">

            <xsl:output method="xml" indent="no"/>

            <xsl:param name="Keyword" />

            <xsl:param name="ResultsBy" />

            <xsl:param name="ViewByUrl" />

            <xsl:param name="ShowDropDown" />

            

            <!-- Un montón de código aquí -->

            

                </xsl:otherwise>

              </xsl:choose>

            </xsl:template>

 

            <!-- End of Stylesheet -->

          </xsl:stylesheet>          

        ]]]]><![CDATA[>

      </property>

      

      <!-- Un montón de propiedades aquí -->

      

    </properties>

  </data>

</webPart>

webParts>]]>

No se vosotros, pero yo me he llevado una alegría al ver que esto funcionaba. Antes de acabar, un par de puntos:

  1. Esto está funcionando ahora, pero puede tener algún efecto secundario, como siempre. Si detecto alguno, actualizaré el artículo e indemnizaré a todos mis subscriptores con 100€ en la MartosStore
  2. He leído por ahí que nunca deberíamos anidar CDATAs jamás de los jamases. Lo único que os puedo decir es que si por cada vez que lo haces, dios mata a un gatito… lo dejaré de hacer.

¿Te funciona el intellisense pero no compila?

Hoy toca ese tipo de recordatorios que, no por ser cosas aparentemente triviales, dejan de ser importantes. En el caso que me ocupa, estuve el otro día haciendo una pequeña prueba de concepto y me pasé un buen rato con un error bastante curioso. Un código que tenía funcionando perfectamente en un proyecto no me compilaba en esta prueba de concepto. Las líneas conflictivas eran:

SPLimitedWebPartManager limitedWebPartManager;

SPUtility.GetGenericSetupPath("TEMPLATE");

Estas dos líneas, aparentemente sencillas, devolvían los siguientes dos errores:

'Microsoft.SharePoint.Utilities.SPUtility' does not contain a definition for 'GetGenericSetupPath'

The type or namespace name 'SPLimitedWebPartManager' could not be found (are you missing a using directive or an assembly reference?)

Antes de ir a la solución, es necesario entender el momento de frustración por el que se pasa. El sistema no encuentra elementos que debería encontrar y que además, son de lo más común del mundo. Eliminas y vuelves a crear la referencia a Microsoft.SharePoint.dll una y otra vez. Haces mil cambios en el código hasta dejar prácticamente aisladas estas dos llamadas. Nada, siempre el mismo error.

Como no podía ser de otra manera, el error viene causado por una tontería. Como sabréis, cuando creáis un proyecto de SharePoint se os da la opción de elegir entre Farm Solution y Sanboxed Solution. No os voy a hablar de las diferencias entre un modo y el otro, pero simplemente deciros que el modelo de objetos de SharePoint cuando estáis en modo Sanbox se reduce bastante. De esa manera, espacios de nombre, clases o miembros que funcionan perfectamente en soluciones de tipo granja, quedan deshabilitados completamente en modo Sandbox. Si váis, por ejemplo, a esta página, Veréis que la clase SPLimitedWebPartManager no está disponible para Sandbox.

La solución a este problema puede ser muy simple o muy compleja en función de la siguiente pregunta: ¿realmente necesitáis que el código funcione en modo SandBox? si la respuesta es no, os bastará con ir a las propiedades del proyecto y cambiar el valor de la propiedad Sandboxed solution. Si la  respuesta es seguramente la solución pasará por buscar una alternativa, si es que la hay, que no haga uso de los elementos que nos están dando problemas. Si tenemos la opción de desplegar un Sandbox Proxy será una buena noticia, porque siempre podremos trasladar allí el código conflictivo.

SharePoint 2010 y ALM. ¿Es posible?

Muchos de vosotros habréis notado un descenso importante en la frecuencia de artículos en este blog. Históricamente siempre me ha pasado esto, empezando con mucho ritmo pero, a medida que se acercaba el final del año y con las urgencias que esto acaba acarreando, me acababa dedicando a todo menos a actualizar el blog.

Este año, no obstante, la razón ha sido otra. Las últimas semanas las he dedicado a una parte de mi trabajo que siempre he identificado como la más importante, pero que siempre ha quedado en un segundo plano: ALM o la Gestión del Ciclo de Vida de las Aplicaciones. Ahora que ya puedo decir con orgullo que la mayor parte de la infraestructura necesaria está en su lugar, y aprovechando que tengo preparados unos cuantos eventos que giran en torno a este asunto he pensado escribir una serie de artículos, empezando por la introducción que haré a continuación.

Antes de comenzar, una puntualización: ahí fuera hay verdaderos expertos en ALM y no querría yo meterme en su terreno. Aunque en ocasiones hablaré de forma genérica, quiero dejar claro que yo voy a hablar de ALM en el mundo SharePoint, una combinación sobre la que no hay tanto material, almenos en este país. No obstante, si digo alguna barbaridad y algún experto en ALM quiere corregirme, será más que bienvenido J

ALM es un asunto que genera cierta controversia. Pese a que la mayoría de profesionales del sector opinamos que poner atención a este asunto es primordial y aumenta espectacularmente la calidad de nuestro software, es rara la ocasión en que realmente se ponen todos los medios necesarios. Normalmente el argumento que se utiliza para no destinar presupuesto a esta partida es que es difícil de justificar de cara al cliente y, efectivamente, es un argumento totalmente válido. Cuando te compras un coche tú eliges las llantas, el número de marchas, los caballos, etc., pero el vendedor nunca pone en el presupuesto una línea donde se te cobren los procesos de calidad que han seguido y el I+D que han necesitado para construir el coche que tú estás comprando. ¿Cuál es la solución entonces? Mi opinión es que SIEMPRE hay que poner especial atención a este tema y después, a la hora de justificarlo de cara al cliente, plantear que el coste de hacer las cosas bien es un factor multiplicador en el precio por funcionalidad que se le va a cobrar.

Muchos diréis que es imposible, al menos en países como España, hacer esto que digo. Que en general aquí se mira el precio por hora final o el precio total del proyecto para decidirse entre un proveedor u otro. Pues mi objetivo con esta serie de artículos es convenceros de que ahí estáis equivocados. Yo no creo que hacer las cosas bien sea necesariamente más caro que hacerlas rápido. En los próximos artículos os explicaré cómo un buen trabajo en este apartado hace que la calidad de los desarrollos aumente, y un aumento de la calidad del software implica una disminución del número de errores y una mayor mantenibilidad del código, con lo que hacemos que el tiempo total del desarrollo y los costes recurrentes de nuestros clientes disminuyan. ¿Acaso no pasa esto en otros sectores? ¿Acaso no prefieres pagar más dinero por un elemento de más calidad que nos asegure más durabilidad o menos problemas a futuro? Evidentemente siempre nos encontraremos con quien prefiere pagar menos (o dispone de menos dinero para gastar) y se decantará siempre por la solución más barata pero, desengáñate, siempre habrá alguien más barato que tú. Si quieres luchar por conseguir esos clientes entrarás en un sistema perverso en el que facturas por debajo de coste (si no lo haces tú lo harán otros) esperando a que una vez conseguido el cliente sea más fácil subir la tarifa. ¿Cuántas veces habéis visto que, cuando quieres subir la tarifa para cubrir tus costes, el cliente se decanta por un proveedor más barato? Mi idea es que si un proveedor cobra X por un trabajo de 1 mes y tú cobras 2X por ese mismo trabajo, a priori estás cobrando más dinero. Si el primer proveedor se retrasa un mes y sigue cobrando lo mismo, evidentemente el cliente estará pagando menos dinero pero tendrá que asumir un retraso. Si resulta que ese proveedor te cobra por horas al final estarás pagando lo mismo. Además, si después estás un año resolviendo incidencias o si después el código fuente acaba siento tan poco mantenible que necesitas perfiles extremadamente altos para resolver sus incidencias, te aseguro que los costes se multiplicarán exponencialmente.

En mi opinión todos deberíamos luchar en este sector para que todo el software que se desarrollase tuviese la máxima calidad. En ese momento podríamos usar términos como Ingeniero/a o Arquitecto/a con todas las de la ley. Seguramente al inicio podría resultar un poco caos porque, no nos engañemos, la inversión inicial necesaria para poner todo esto en marcha no es pequeña, y no todas las empresas están dispuestas a hacerla. Es nuestro trabajo educar primero a nuestras empresas, haciendo ver a las personas que toman decisiones lo importante de esta inversión y las ventajas que aportan a medio y a largo plazo, y de la misma manera hacer ver esto a nuestros clientes. Yo creo que con un poco de paciencia podremos conseguir grandes cosas en este aspecto.

En los siguientes artículos de esta serie os hablaré de dos cosas que necesitáis para convencer a la gente de la importancia del ALM: herramientas y métricas. Las herramientas nos van a ayudar a llevar todos los procesos necesarios a cabo, y las métricas nos van a servir para mostrar el valor del tiempo invertido de manera que sea entendible por personal no técnico. Imaginad, por ejemplo, que sois capaces de decir que el número de errores decrece en un 80% o que el porcentaje de código fuente cubierto por una prueba unitaria es del 95%. Con este tipo de datos no resulta demasiado complejo poner un número al lado indicando la cantidad de horas no malgastadas en mantener un código y que pueden ser facturadas en otro proyecto. En el momento en que ese número de horas se equipare con el número de horas utilizadas para montar las herramientas de las que os hablaré ya habremos hecho buena la inversión y, a partir de ese momento, el beneficio será evidente.

En fin, acabo aquí la introducción a este asunto que seguro que genera muchas discusiones. Seguro que al leer esto algunos pensáis que en vuestra empresa esto no es viable o que lo habéis probado pero no os han dejado. Después habrá gente que no estará de acuerdo con las herramientas que os iré exponiendo a medida que escriba los siguientes artículos y también habrá alguno que saque a relucir el eterno dilema de lo que es un arquitecto y lo que no lo es. Ya sabréis lo que diré: cualquier opinión tiene que ser respetada 😉