He terminado de leer el último libro de Robert C. Martin, Clean Code.
De Robert, había leído otros dos libros, “UML para programadores Java”, una guía práctica y sin rodeos de cómo usar UML en proyectos reales; y cuando digo práctica es que no se anda por las ramas y en ocasiones en un tono incluso “irónico” explica perfectamente cómo debemos usar UML.

El otro libro es Agile Principles, Patterns, and Practices in C# (Robert C. Martin Series)
, que puedo decir de este libro ampliamente comentado, uno de los que se deben tener. (Ya sabéis que se lo recomiendo a todo el mundo)
Bueno, de modo que “Clean Code: A Handbook of Agile Software Craftsmanship (Robert C. Martin Series)
” tenía todos los boletos de ser un gran libro. No ha defraudado en absoluto.
Apenas empezarlo, en la introducción ya me había pillado. (Ilstración de la introducción)

El libro explica cómo escribir buen código, código legible y eficiente. Los ejemplos son en Java, pero tener en cuenta que estamos hablando de cómo escribir buen código, habla del significado de los nombres, de las funciones, de los argumentos, del tipo de retorno, de cómo comentamos el código, de las reglas de formato, de objetos y estructuras de datos, de la gestión de errores, de las pruebas unitarias, del diseño simple, de sistemas, de concurrencia, de refinamiento, de olores y heurística. Habla de estilo, de buen estilo.
De veras, me ha parecido un libro impresionante, con unos ejemplos claros, con un estilo cuidado y detallado, sin dejar cosas fuera, insistiendo en las cosas importantes (esto a mí me gusta, así entran mejor las cosas)
Vamos un libro que entra de lleno en mi TOPTEN.
El Community
Tour 2008 del Guill-e consiste en que, después de varios meses de un arduo
trabajo de coordinación, nos hemos organizado muchos grupos de usuario (los de
Málaga,
Madrid,
Valencia,
Reus,
Barcelona,
Igualada,
Vic,
Andorra,
Pamplona,
Murcia,
Albacete,
Huelva,
Bilbao,
La Coruña,
Mallorca, Cantabria, Valladolid y
también SecondNug) y
hemos quedado con el amigo Guillermo Son para que haga una pequeña ;) gira y
venga a hacernos una visita a todos, a enseñarnos las cosas nuevas que ha
aprendido del lenguaje ese en el que no se pierde el tiempo poniendo puntos y
comas (expresión suya).
Guille nos ha contando que está intentando echar un cable a un chaval que está
en una situación muy apurada y hemos decidido ayudarle también así que la gira
es solidaria con
Juanma. Para animar a la colaboración se sortearán durante la gira un montón
de regalos:
1 Visual Studio 2008 Profesional
2 suscripciones
MSDN Premium con Visual Studio Team System 2008 Team Suite (valorada cada
una en más de 5.000 Euros).
10 Packs de Productividad que incluye Resharper y dotTrace
16 libros de Novedades de Visual Basic 9.0 (uno para cada evento)
16 libros de Novedades de C# 3.0 (uno para cada evento)
65 Suscripciones a la revista dotNetManía (48 de 3 meses y 16 de un año)
En Pamplona, además tenemos la suerte de volver a contar con David Salgado, que
hará de telonero de lujo y nos hablará de opciones para del desarrollo de un
sitio web .NET.
Os esperamos el día 15 de octubre de 16:30 a 21:00 en el salón de actos de los
Centros de Excelencia Software, polígono industrial Elorz-Mocholí en Noain.
![]()
La agenda:
16:30-17:00: Bienvenida y registro. Reunión del grupo de usuarios
NavarraDotNet. Orden del día: nuestros saraos
17:00-18:30:
Opciones para el desarrollo de un sitio web .NET, David Salgado
Con la llegada del SP1 de .net
3.5, se abre el abanico de opciones a valorar a la hora de desarrollar un sitio
web. Hasta ahora contábamos con
ASP.NET y algunas pinceladas de
ASP.NET AJAX. A dia de hoy contamos además con una nueva versión de Visual
Studio, ASP.NET MVC,
ASP.NET Dynamic Data,
ASP.NET Dynamic Services, un
soporte mejorado de ASP.NET AJAX e
Internet Explorer 8 como navegador. Descúbrelos, resuelve tus dudas y decide qué
es lo más adecuado para tus desarrollos.
18:30- 19:00: Merienda
patrocinada por el CES
19:00 -21:00: El Guille con
la comunidad, Guillermo Som
Novedades y ejemplos prácticos de Visual Basic 9, ejemplos prácticos de
uso de LINQ. Aprovecha la primera visita que hace elGuille a
Pamplona: ¡pregúntale al Guille!
Como siempre, la entrada es gratuita previo registro en:
Inscripción a través de Microsoft
Inscripción a través de CEIN
Y tenéis más información y el fantástico cartel que ha hecho nuestro
Sergio Jimenez en
http://www.navarradotnet.com/post/el-Guille-en-Pamplona!!!.aspx.
(by: Elena)
Aquí continúa el drama de Unit Test para SharePoint. Esta vez hemos reunido esfuerzos entre nosotros, Carlos Segura (http://www.ideseg.com ) y Gustavo Velez (http://www.gavd.net ), para intentar sacar algo en claro. Programadores del mundo de SharePoint, uníos! ...
Unit Test, SharePoint y que es lo importante:
Testeo Unitario es una técnica de programación que permite asegurar que lo que se ha programado hoy cumple las condiciones exigidas, y que las seguirá cumpliendo en el futuro, cuando se hagan modificaciones en el código fuente. Existe numerosa información al respecto, tanto en libros de texto como en internet, así que no repetiremos las bases de la técnica; en resumen, es deseable que se
cumplan algunas condiciones:
- El código de Pruebas Unitarias debe ser independiente de cualquier FrameWork que se esté utilizando para garantizar que no hay dependencias, es decir, circunstancias que no se puedan repetir en el futuro. En nuestro caso, no se desea tener que utilizar una instancia de SharePoint para ejecutar el testeo, pues es prácticamente imposible crear dentro de algunos meses/años un sistema de SharePoint que sea exactamente igual al utilizado originalmente
- El código de Pruebas debe ser fácil y rápido de escribir. El (valioso) tiempo de programación se debe utilizar para programar la funcionalidad, no para programar el sistema de pruebas
- El código de prueba tiene que ser igual para todos los desarrolladores en el equipo de desarrollo. Esto tiene que ver con el primer punto: si no existen dependencias (configuraciones, por ejemplo) con el FrameWork utilizado, no hay riesgos de que dos desarrolladores obtengan diferentes resultados. O que el sistema de compilación automática produzca resultados impredecibles (Night Build, Continuous Build, Regretion e Integration Test)
Unit Test es comúnmente utilizado en desarrollo de software, y existen varias herramientas que lo facilitan. Visual Studio (versión profesional y superior) provee todas las herramientas necesarias para generar Unit Test con un clic; si no se dispone de una de estas versiones de Visual Studio, existen herramientas gratuitas que pueden hacer el mismo trabajo (NUnit, http://www.nunit.org/, xUnit, http://www.codeplex.com/xunit y TestDriven, http://www.testdriven.net/ por ejemplo).
Cuando se desean hacer Pruebas Unitarias para SharePoint es necesario utilizar técnicas suplementarias que permitan crear “imágenes fantasmas” de sus clases. Esto se puede conseguir de diferentes formas, por medio de Mocking o Stubbing, por ejemplo
•
http://geeks.ms/blogs/gvelez/archive/2007/08/04/mocks-mocking-mockers-y-sharepoint.aspx•
http://geeks.ms/blogs/gvelez/archive/2007/08/12/stubs-stubbing-stubbers-y-sharepoint.aspx•
http://www.ideseg.com/SharePointPruebasUnitarias1.aspxOtras técnicas, como la utilización de Plantillas o Copias de Seguridad son utilizables, pero no cumplen las condiciones ideales indicadas al principio.
Mocking es una técnica que permite crear objetos “falsos” de un determinado FrameWork, y luego “convencer” al código a probar que tiene que usar los objetos falsos, y no los que obtendrán del FrameWork en su trabajo real. Esta técnica permite cumplir todas las condiciones indicadas. Desafortunadamente, por la forma de programación de SharePoint no es posible usar Mockers tradicionales.
La nueva versión de
TypeMock (versión 5.0, http://www.typemock.com ) permite crear objetos mock que funcionan bajo estas condiciones, haciéndolo ideal para crear Unit Test para SharePoint. Desafortunadamente,
TypeMock es una herramienta comercial, pero se puede bajar del sitio indicado una versión de prueba completamente funcional por 30 días.
Otra de las motivaciones para usar TypeMock, es que el equipo de SharePoint Guidance está usando TypeMock en sus ejemplos; el porqué es simple, a pesar de que existen otras alternativas en el mercado, y algunas de uso libre, ninguna de ellas es capaz de mockear clases selladas o clases que no tienen un constructor público. La API de SharePoint cuenta con innumerables clases y una gran parte de ellas están selladas y carecen de constructores públicos por lo que TypeMock es la única alternativa por el momento.
Mockeando a SharePoint
1 - El caso más sencillo: mockear a SPSIte y SPWeb. El método a probar tiene la siguiente forma:
public static string TestMock_01()
{
String strReturn = String.Empty;
try
{
using(SPSite mySite = new SPSite("http://MiServidor"))
{
using(SPWeb myWeb = mySite.OpenWeb())
{
strReturn = myWeb.MasterUrl;
}
}
}
catch (System.Exception ex)
{
strReturn = ex.ToString();
}
return strReturn;
}
Y el método de Pruebas Unitarias con TypeMock seria:
public void TestMethod1()
{
using (RecordExpectations recorder = RecorderManager.StartRecording())
{
SPSite mySiteMocked = new SPSite("");
SPWeb myWebMocked = RecorderManager.CreateMockedObject<SPWeb>();
recorder.ExpectAndReturn(mySiteMocked.OpenWeb(), myWebMocked);
recorder.ExpectAndReturn(myWebMocked.MasterUrl, "abcd.master").RepeatAlways();
}
string expected = "abcd.master";
string actual;
actual = Program.TestMock_01();
Assert.AreEqual(expected, actual);
}
Bajo el estamento “using” se crean objetos SPSite y SPWeb “falsos”. Todos los objetos creados bajo el “recorder” serán después utilizados como objetos de trabajo en la función a testear, en lugar de los objetos “reales” obtenidos del FrameWork de SharePoint. Esto permite garantizar que en el ejemplo, no importa qué tipo de configuración tenga la instalación actual de SharePoint, siempre se le va a “hacer creer” al método a testear que la página maestra del Web se llama “abcd.master”.
Luego de crear los objetos mockeados, se inician las variables a esperar (expected), se ejecuta el método a probar y el resultado se compara con lo esperado.
2 - Yendo algo más lejos: mockeando colecciones. Cuando se desea utilizar la misma sintaxis para crear objetos mockeados de colecciones se encuentran diferentes dificultades. En las colecciones de SharePoint se ha mantenido el diseño existente en versiones anteriores por lo que funcionan como lo hacían en Net 1.1: una clase que implementa IEnumerable y una clase anidada que implementa IEnumerator; para poder recorrer colecciones de objetos mockeados se debe reproducir este comportamiento y lo que a priori puede parecer fácil en realidad no lo es…
En primer lugar se debe mantener una colección de objetos paralela a través del cual podamos devolver un enumerador; se puede ver un ejemplo de esta técnica en (
http://dotnetforum.dk/blogs/mac/archive/2007/12/21/first-steps-with-typemock-and-the-sharepoint-api.aspx), lo cual nos obliga en cierta manera a crear métodos para reproducir las colecciones de objetos de SharePoint.
En parte motivados por esto y por la necesidad de poder realizar los tests de la manera más sencilla posible hemos creado un conjunto de clases envoltorio que nos permitirán extender los objetos a mockear de SharePoint de una manera más elegante.
Por ejemplo, para el siguiente método a probar, en el que se necesita recorrer la colección de Listas en el Web de más alto nivel:
public static string TestMock_02()
{
string strReturn = String.Empty;
try
{
using (SPSite mySite = new SPSite("http://MiServidor"))
{
using (SPWeb myWeb = mySite.OpenWeb())
{
int intTeller = 0;
foreach (SPList oneList in myWeb.Lists)
{
Debug.WriteLine(oneList.Title);
intTeller++;
}
strReturn = intTeller.ToString();
}
}
}
catch (Exception ex)
{
strReturn = ex.ToString();
}
return strReturn;
}
Se puede utilizar un método de prueba con la siguiente sintaxis:
[TestMethod]
public void TestMethod2()
{
MockSPSite mockSite = new MockSPSite("TestSite"); // 1
MockSPWeb mockWeb = new MockSPWeb("TestWeb"); // 2
MockSPList mockList0 = new MockSPList("MyList0"); // 3
MockSPList mockList1 = new MockSPList("MyList1");
MockSPList mockList2 = new MockSPList("MyList2");
mockWeb.Lists = new MockSPListCollection(new[] // 4
{
mockList0,
mockList1,
mockList2
});
mockSite.ExpectGetAlways("RootWeb", mockWeb.GetInstance()); //5
SPWeb WebMocked = mockWeb.GetInstance(); // 6
using (RecordExpectations recorder = RecorderManager.StartRecording()) // 7
{
SPSite SiteMocked = new SPSite(""); // 8
recorder.ExpectAndReturn(SiteMocked.OpenWeb(), WebMocked); // 9
}
string expected = "3"; // 10
string actual;
actual = Program.TestMock_02();
Assert.AreEqual(expected, actual);
}
Aquí se pueden distinguir tres zonas con código:
- En la primera parte, líneas 1 a 7 se crean todos los objetos “falsos” necesarios. Líneas 1 y 2 crean objetos del tipo SPSite y SPWeb. Las líneas bajo el numero 3 crean tres Listas mockeadas y en la línea 4 se agregan las Listas a la Colección de Listas del objeto SPWeb mockeado. En la línea 5 se agrega a su vez el objeto SPWeb como la Web de nivel superior del objeto SPSite mockeado y finalmente, en la línea 6 se crea un objeto del tipo SPWeb nuevo basado en el objeto SPWeb mockeado. Esto es necesario para el código en la segunda zona, que no permite utilizar objetos mockeados directamente
- En la segunda zona, líneas 7 a 9, se crean los objetos que se le van a entregar a la clase a testear por medio de un “recorder” de TypeMock. En la línea 8 se crea un objeto SPSite que va a substituir el SPSite en la clase a testear, y en la línea 9 se le asigna el valor del objeto SPWeb mockeado con las Listas creadas en la primera parte.
- La tercera zona, desde la línea 10, incluyen el código para los valores esperados y los valores que regresan del método a testear y los comparan en la aserción.
La primera parte del código utiliza las clases envoltorio comentadas anteriormente (MockSPSite, MockSPWeb, etc). Estas clases tienen la forma:
namespace SPTypeMock.Core
{
public class MockSPSite : MockSP<SPSite>
{
public MockSPSite(string url) : base(true)
{
if (string.IsNullOrEmpty(url))
{
throw new ArgumentNullException("url");
}
Mock.ExpectGetAlways("Url", url);
}
}
}
Estas clases sirven para simplificar la creación de los objetos mockeados, y no son más que herencias de tipos definidos (SPSite en este caso), con algunos constructores específicos y métodos para conectar sus colecciones de objetos. Las clases de envoltura permiten reutilizar el código una y otra vez, sin que la escritura de las pruebas signifique el tener que escribir mas código que el código a testear (una de las condiciones señaladas al principio).
Todas estas clases se encuentran en la biblioteca
SPTypeMock que podéis encontrar en
CodePlexSPTypeMock usa dos clases, la primera es
MockSP<T> que es una clase abstracta desde la cual mockearemos los objetos de SharePoint, la única peculiaridad de esta clase está en el constructor, que tiene un parámetro bolean, que se encarga de añadir la propiedad ID de la clase; las clases de SharePoint tienen un ID, en la mayoría de ellas es un Guid, pero en otras como SPListItem es un int.
La propiedad Mock de esta clase nos da acceso al objeto mock que se encuentra en el interior, debemos usar esta propiedad para establecer las expectativas.
El método GetInstance, se encarga de devolvernos una instancia real del objeto mockeado.
La segunda clase es
MockSPCollection<TCollection,TItem> que es otra clase abstracta desde la cual heredaremos las colecciones de SharePoint. MockSPCollection, hereda a su vez de List<TItem> de modo que así conseguimos tener la colección paralela necesaria para trabajar con las colecciones de SharePoint.
Disponemos de dos constructores uno que se encargará de crear colecciones vacías y otro al que podemos pasarle una lista de elementos que formarán parte de la colección. Al obtener una instancia de la colección por medio de GetInstance(), establecemos que la interfaz IEnumerable será obtenida de la lista; también aquí nos encargamos de mockear el index por defecto que será a través de un int.
Si las colecciones que deseamos usar tienen otros índices como SPListCollection, que tiene un índice por título de la lista y otro por Guid, podemos sobrescribir el método CustomIndex en las clases heredadas implementando dicha funcionalidad.
No todo es perfecto...
No todo ha sido solucionado, algunos problemas quedan aún por resolver:
- La instalación de TypeMock no permite seleccionar un directorio de instalación, lo que limita la utilización de programas de compilación automático, como Cruise Control por ejemplo
- Los objetos mockeados creados en las dos primeras zonas de la clase de prueba son creados en un Thread diferente al utilizado por SharePoint al crear los objetos en el método a testear. Esto tiene como consecuencia que si se desea destruir los objetos al final del método a probar (por medio de un “using” para el SPSite y/o el SPWeb, o por medio de un “Dispose()” al final del método), SharePoint producirá un error en sus logs indicando “ERROR: request not found in the TrackedRequests. We might be creating and closing webs on different threads”
- Es necesario crear aun muchas más clases de envoltorio
Evento: “MDA para Dummies, continuación…”
Día: 18 de abril 2008, hora: 18:30-20:30
Lugar: Sistema Formacion. Plaza Pintor Paret, 1. 31008 Pamplona
Colaboran: Sistema Formación, Masbytes, Solnatec, navarraDotNet, MSDN
Ponente: David Marzo. Solnatec, navarraDotNet
Agenda:
18:30 - 19:00: Reunión de navarraDotNet. Orden del día: nuestros saraos
19:00 - 20:30: “MDA para Dummies, continuación…”. David Marzo. Solnatec. (http://www.solnatec.com)
Demostración de uso de una herramienta MDA en el día a día de un desarrollador.
Entrada libre previo registro en:
http://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032376397&culture=es-es
Evento: Desarrollar software no es sólo picar codigo
Día y hora:
jueves 15 de mayo de 18:30 a 21:00
Lugar:
Centros de Excelencia Software. Salón de Actos. Polígono Industrial Mocholi, Plaza Cein. 31110 Noáin. Navarra
Colaboran:
Centros de Excelencia Software, Acciona Energía, Masbytes, PlainConcepts, MSDN, navarraDotNet
Ponentes:
Unai Zorrilla Castro. Plain Concepts. Microsoft MVP Compact Framework
(http://geeks.ms/blogs/unai/Default.aspx)
Carlos Segura Sanz. NavarraDotNet. Microsoft MVP SharePoint Server
(http://www.ideseg.com)
Agenda:
18:30 - 19:00. Reunión del grupo de usuarios navarraDotNet. Orden del día: nuestros saraos
19:00 - 21:00. Desarrollar software no es sólo picar codigo. Unai Zorrilla y Carlos Segura.
Se hará un repaso por todos los procesos implicados en Integración Continua como pilar de desarrollo,
testeos unitarios, cobertura de pruebas, construcciones de software y seguimiento de los procesos.
Hablaremos de las herramientas que utilizamos: Cruise Control, Visual Studio Team System,
NUnit, Xunit, Csubversion, NCover, NMock
Entrada libre previo registro en:
http://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032376398&Culture=es-ES
Dentro del proceso de integración continua que uso, los proyectos que no tienen un archivo FxCop, los proceso usando una plantilla a la que añado mediante una tarea en el MsBuild, los targets necesarios para después poder ver si hay algo muy cantoso …
La cosa es que en el resto de proyectos mantengo un archivo FxCop, en el que voy excluyendo algunas de esas cosas cantosas tras revisar el código. El problema viene cuando en el build server, se ejecuta el FxCop, y genera el informe, ya que en este informe aparecen todas las incidencias, incluidas las que yo he excluido. (grrr)
De modo que he decidido acabar de una vez con el problemilla.. lo que hago ahora es procesar el informe de FxCop con el XSL (que os dejo abajo) para que cuando el CC, haga el merge, solo estén las activas.
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="//Message">
<xsl:if test="self::node()/@Status='Active'">
<xsl:copy-of select="self::node()" />
</xsl:if>
</xsl:template>
</xsl:stylesheet>
Para procesar el XML, podéis usar la tarea XSLT del Community.Tasks, para MSBuild.
<Exec Command="$(FxCopExe) /project:$(FxCopProject)/out:$(ArtifactPath)\$(FxCopReport)temp" />
<Xslt Inputs="$(ArtifactPath)\$(FxCopReport)temp"
Xsl="$(FxCopActive)"
Output="$(ArtifactPath)\$(FxCopReport)" />
Y listo ..