
Buenas,
después de 3 días encerrado y aburrdo en un hospital, empiezo a desempolvar algunos posts que estaban a medio hacer. Uno de ellos es comentar una solución que organizamos con el amigo JuanLu para escenarios donde se requieran ejecutar pruebas unitarias que utilicen Microsoft Outlook (teniendo en cuenta esto que comenté hace 2 días por las dudas).
Warning, no es posible crear pruebas unitarias para proyectos del tipo AddIn de Outlook
Antes de comentar como configuramos las pruebas unitarias, es necesario tener que cuenta que por cuestiones de seguridad y de interfaz en un ensamblado del tipo AddIn de Outlook, si queremos crear pruebas unitarias a partir del mismo nos encontraremos con el siguiente error en el asistente para la creación de pruebas unitarias de Visual Studio:

Asi que la sugerencia en este escenario es implementar toda la funcionalidad que requerimos de Outlook en un proyecto del tipo Biblioteca de Clases y sobre el mismo creamos las pruebas unitarias.
Creando pruebas unitarias para interactuar con Outlook
Pues bien, a modo de ejemplo he creado una clase que posee 2 funciones que retornan la cantidad de elementos que hay en el Inbox y en en Calendar:
1: public class Engine
2: {
3: public int GetMails()
4: {
5: _Application app = new Application();
6: int ret = -1;
7: Microsoft.Office.Interop.Outlook.MAPIFolder inbox =
8: app.GetNamespace("MAPI").GetDefaultFolder(OlDefaultFolders.olFolderInbox);
9: if (inbox != null)
10: ret = inbox.Items.Count;
11: return ret;
12: }
13: public int GetCalendars()
14: {
15: _Application app = new Application();
16: int ret = -1;
17: Microsoft.Office.Interop.Outlook.MAPIFolder cals =
18: app.GetNamespace("MAPI").GetDefaultFolder(OlDefaultFolders.olFolderCalendar);
19: if (cals != null)
20: ret = cals.Items.Count;
21: return ret;
22: }
23: }
Sobre esta clase, también he creado un par de pruebas unitarias para probar el funcionamiento de la clase Engine:
1: /// <summary>
2: ///A test for GetCalendars
3: ///</summary>
4: [TestMethod()]
5: public void GetCalendarsTest()
6: {
7: Engine target = new Engine();
8: int actual;
9: actual = target.GetCalendars();
10: Assert.IsTrue(actual > 0);
11: }
12:
13: /// <summary>
14: ///A test for GetMails
15: ///</summary>
16: [TestMethod()]
17: public void GetMailsTest()
18: {
19: Engine target = new Engine();
20: int actual;
21: actual = target.GetMails();
22: Assert.IsTrue(actual > 0);
23: }
Si lanzamos las pruebas unitarias podremos ver como se levanta el proceso de Outlook sin mostrar la interfaz y que se ejecutan las pruebas correctamente. Otra opción es tener el Outlook en ejecución y lanzar las pruebas para ver el resultado.
Integrando el proceso con TFSBuild
Para lograr automatizar el proceso de construcción y pruebas, el paso siguiente es configurar un build que compile y ejecute estas pruebas. Antes de continuar debermos tener en cuenta que, ya que estamos trabajando con Outook; es muy probable que el usuario con el que se ejecuten estas pruebas necesite tener configurado su perfil de Outlook para poder trabajar. Si intentamos utilizar el servicio de Team Foundation Server Build, que por defecto suele estar configurado con el usuario TFSBuild; debemos configurar el perfil de Outlook de este usuario.
Sin embargo al momento de lanzar una compilación utilizando el servicio de TFS Build nos encontraremos con que la compilación se ejecuta correctamente, pero al momento de ejecutar las pruebas tendremos un error similar al siguiente:
Test method JL02.Test.EngineTest.GetMailsTest threw exception:
System.Runtime.InteropServices.COMException: The file
C:\Documents and Settings\TFSBUILD\Local Settings\Application
Data\Microsoft\Outlook\Outlook.pst cannot be opened..
Donde podremos ver que el proceso de compilación no puede lanzar Outlook ya que en el perfil del usuario TFSBuild no es posible acceder al archivo de datos propio de Outlook.
Para solventar este problema, podemos cambiar la confíguración del proceso de compilación TFS Build para que no se ejecute como servicio de Windows sino para que se ejecute como un programa más, asociado a un perfi de usuario.
En este post, explique cómo configurar el servicio de TFS Build para que interactue con el Desktop; pero para este caso es bueno recordar los pasos para realizarlo.
1. Detener el servicio de windows Team Foundation Server Build.
2. Abrimos una ventana de comandos y lanzamos el exe de TFSBuild para se ejecute en modo interactivo, con el comando
"C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\PrivateAssemblies\TFSBuildService.exe"
3. Debemos dejar el proceso en ejecución para que las peticiones al servicio de compilación se ejecuten en este proceso.
4. Si tratamos de procesar una compilación, nos encontraremos con el siguiente error:
ya que por defecto el agetne de compilación recibe peticiones en el puerto 9191 y el servicio interactivo está configurado en el puerto 9192.
5. Para solucionar este problema, crearemos un nuevo agente que utilice el puerto 9192.
6. Dentro del panel Team Explorer seleccionamos el directorio Builds, desplegamos el menú contextual y seleccionamos la opción Manage Build Agents.
7. En el formulario de configuración de agentes. creamos un nuevo agente con la siguiente información, donde los datos del servidor son los mismos, pero he cambiado el puerto a 9192.
8. El nuevo agente debe aparecer en el listado de agentes de compilación disponibles.
9. Lanzamos una nueva compilación configurando para que se utilice el agente que hemos creado en los pasos anteriores.
10. Y nuestro proceso de compilación ya posee acceso al proceso de Outlook y al perfil del usuario que lo ejecuta para poder ejecutar las pruebas unitarias correctamente. La siguiente imagen muestra como se han ejecutado 2 pruebas unitarias y una ha pasado correctamente y la otra posee un error.
11. En este punto ya tenemos integradas nuestras pruebas unitarias que utilizan Outlook dentro del proceso de compilación y podremos ver la evolución de las mismas aprovechando las ventajas de TFS que no comentaré porque ya bastante hemos posteado al respecto.
Espero que además de a JuanLu a alguien le sea de utilidad y recuerden que lo interesante de este enfoque es que se pueden levantar varios agentes, utilizando diferentes perfiles de usuario de correo para ejecutar las pruebas con diferentes configuraciones.
Saludos @ Home
El Bruno