Ya tenemos RadarCube NET Windows Forms for Microsoft Analysis Services

El mercado de los controles del tipo «pivot table» empieza a activarse. Señores… hay demanda para un sustituto de los Office Web Controls, y RadarSoft está echando el resto. Hoy han lanzado RadarCube NET Windows Forms, un control Winforms para .NET 2.0 que permite presentar datos multidimensionales en nuestras aplicaciones Windows. Podéis encontrar más información y unos cuantos pantallazos en esta URL: http://www.radar-soft.com/products/radarwin_msas.aspx.


Además hoy han anunciado que bajan los precios del RadarCube ASP.NET.


Dos estupendas noticias… a ver si hay suerte y se empiezan a popularizar herramientas que hasta ahora estaban reservadas sólo a una élite. Como diría Groucho… ¡¡¡Más madera!!!

Testeo unitario de cubos OLAP

En Internet no se encuentran muchas páginas sobre cómo testear un cubo OLAP… probablemente, como en toda tecnología «emergente», cada uno se las arregle como pueda y pocas cosas estén ampliamente extendidas. Sin embargo, con el resto de tecnologías «más convencionales» todo el mundo tiene una opinión formada sobre el testeo unitario o el «test driven development» (generalmente para bien). ¿Se pueden conciliar ambos terminos? ¿Puedo escribir «unit tests» para mis cubos OLAP?


La respuesta es «SIN DUDA». El mundo del Business Intelligence puede beneficiarse en gran manera del testeo unitario, gracias a lo que se conoce como «Data Driven Unit Test». ¿De qué va esto?


Analicemos las siguientes sentencias SQL y MDX, lanzadas respectivamente contra la base de datos «Adventure Works» y el cubo de Analysis Services correspondiente:




  • SELECT Production.Product.ProductNumber AS Product, 
        SUM(Sales.SalesOrderDetail.OrderQty) AS Quantity
    FROM Sales.SalesOrderDetail, Production.Product
    WHERE Sales.SalesOrderDetail.ProductID = Production.Product.ProductID
    GROUP BY Production.Product.ProductNumber
    ORDER BY Product ASC



  • SELECT NON EMPTY [Product].[Product Key].[Product Key] ON ROWS,
        [Measures].[Order Quantity]
    ON COLUMNS
    FROM
    [Adventure Works]


Si las ejecutamos, ambas producen resultados similares… una sobre el sistema OLTP y la otra sobre el sistema OLAP. Vaya, empezamos a entender… ¡si ambos sistemas producen resultados similares, eso debe significar que nuestro sistema OLAP funciona correctamente! Eso es el Data Driven Unit Testing, y nos vendrá de miedo para probar nuestros cubos. Recordemos que el escenario habitual en un desarrollo de BI será partir de un sistema existente, así que… ¿qué mejor prueba de que nuestro sistema funciona, que demostrar que devuelve los mismos resultados que el sistema de partida?. Cuantos más cruces de dimensiones comparemos con salidas del sistema OLTP, mejor será nuestra batería de tests.


Es difícil, por no decir imposible, tener una cobertura del 100% del cubo, pero como se suele decir, testear algo es infinitamente mejor que no testear.


Data Driven Unit Test en Visual Studio Team System


Para realizar testeo unitario guiado por datos, tenemos que partir de una tabla de base de datos en la que tendremos almacenado cada uno de nuestros juegos de pruebas. En el ejemplo que he puesto, si no disponemos de tabla, tendremos que crear una vista.



  • CREATE VIEW Test.vOrderQuantityPerProductKey AS
    SELECT
    Production.Product.ProductNumber AS Product,
    SUM(Sales.SalesOrderDetail.OrderQty) AS Quantity
    FROM Sales.SalesOrderDetail, Production.Product
    WHERE Sales.SalesOrderDetail.ProductID = Production.Product.ProductID
    GROUP BY Production.Product.ProductNumber

Este es el punto que menos me gusta, tener que partir obligatoriamente de una tabla accedida mediante OleDB y no poder partir de una sentencia SQL… pero bueno, sigamos a lo nuestro. Nos ponemos las botas de programar, nuestra música favorita, y creamos un nuevo proyecto de tipo «Test Project».



Visual Studio creará por nosotros una clase de test, con un método de test. Tendremos que indicar que el método de test es «Data Driven», para eso, editamos las propiedades del test e indicamos:



  • Data Connection String: Cadena de conexión a nuestra base de datos.

  • Data Table Name: El nombre de la tabla donde se encuentran los valores a probar, junto con los resultados esperados.

  • Data Access Method: Squential. Con esto indicamos que se deberá probar secuencialmente con todos y cada uno de los valores de la tabla.



Como resultado de la edición de estas tres propiedades, Visual Studio decorará nuestro método de test con un atributo DataSource, señal clara de que nuestro test es guiado por datos.


        [DataSource(«System.Data.SqlClient»,
            «Data Source=.;Initial Catalog=AdventureWorks;Integrated Security=True»,
            «Test.vOrderQuantityPerProductKey»,
            DataAccessMethod.Sequential),
            TestMethod()]


Rematando la faena: escritura del test


Escribir el test unitario es sencillo… lo primero que tenemos que hacer es tener una propiedad de tipo TestContext, llamada TestContext. En esta propiedad, Visual Studio nos irá dejando el contexto de cada test, es decir, en nuestro caso, los valores para cada uno de los juegos de prueba.


        private TestContext _myTestContext;


        public TestContext TestContext
        {
            get { return _myTestContext; }
            set { _myTestContext = value; }
        }


Lo siguiente es escribir el test:



        public void OrderQuantityPerProductKeyTestMethod()
        {
            // Construimos la sentencia MDX para el producto actual, y obtenemos la cantidad del cubo.
            String mdxQuery = «SELECT [Measures].[Order Quantity] ON COLUMNS »  
                              + «FROM [Adventure Works] WHERE [Product].[Product Key].[«
                              + TestContext.DataRow[«Product»]
                              + «]»;
            AdomdCommand mdxQueryCommand = new AdomdCommand(mdxQuery, _adomdConnection);
            CellSet cubeResult = mdxQueryCommand.ExecuteCellSet();


            // Comparamos el resultado del cubo, con el resultado de la base de datos.
            int result = (int)cubeResult.Cells[0].Value;
            int expected = (int)TestContext.DataRow[«Quantity»];
            Assert.AreEqual(expected, result, 16);


        }


Como veis, me limito a ejecutar una sentencia MDX que me devuelva de los cubos OLAP el valor equivalente al del juego de ensayo. Para obtener el juego de ensayo, leo del diccionario «DataRow» del TestContext cada una de las columnas de mi tabla de pruebas, y por último pruebo con un Assert que los resultados del cubo sean los esperados.


La invocación de Assert.AreEqual tiene un tercer parámetro que vale 16… ¿qué significa?


Este parámetro, es el «delta» de la función. Muchas veces, cuando metemos datos en un cubo por medio de un ETL, durante el proceso de limpieza se pierde precisión en los datos. Como resultado de la limpieza, los valores extraidos de la base de datos OLTP y OLAP podrían no coincidir… pues bien, el «delta», es la desviación que toleraremos en nuestra prueba (en este caso, +/- 16 enteros). Podéis descargaros el proyecto completo que he adjuntado a este post, y experimentar todo lo que queráis (por ejemplo, probad a bajar el valor del delta y observad qué pasa…).


Despidiendo el post


Hemos visto cómo los test unitarios no están de más en el mundo de la inteligencia de negocios… y recordad que tal y cómo dice SCRUM, un proyecto no está terminado mientras no esté probado.


Happy testing!

RadarCube for Analysis Services (o cómo el ratón a veces rinde más que el puma)

Ahora que los Office Web Control ya son historia, Microsoft nos ofrece MOSS 2007 y su espectacular Excel Services como solución de representación de datos multidimensionales. Hoy lo he estado probando y ver cómo se muestran en la web las hojas de trabajo de Excel 2007 por obra y arte de AJAX es espectacular (hablo de la tecnología, no de cierto producto de limpieza) . Si tenemos Sharepoint implantado en nuestra empresa, no cabe duda de que sería una locura no aprovecharlo para representar nuestros tableros de mando… ¿pero merece la pena implantar Microsoft Office Sharepoint Server 2007 si sólo queremos representar tableros de mando ¿Necesitamos toda esta artillería para cazar perdices? Sharepoint es probablemente la solución que nos permite realizar un "Dashboard" en el menor tiempo, además de ser una de las soluciones más versátiles y personalizables que he visto en mi vida. Un auténtico puma.

Sin embargo, tiene algunos aspectos que pueden restarle puntos a la hora de convertirse en la estrella de nuestros proyectos:

  • MOSS 2007 es complejo de desplegar y administrar. Bueno, esta es la opinión de un total principante en Sharepoint, pero a pesar de lo que nos diga Microsoft, no parece que sea la mejor opción para una solución "out of the box" (aunque sólo sea por el número de servicios que tenemos que activar y desplegar). No olvidemos que se trata de un CMS completo, y que el "Excel Services" sólo es un pequeño apéndice del todo.
  • El coste de la licencia podría ser prohibitivo para pequeñas empresas. Todavía no he encontrado ninguna aclaración de lo que podría costar, pero si nos ponemos en los precios de Sharepoint 2003, la broma podría costarnos cerca de los 1500$ – 3000$ por implantación (dependiendo de los tipos de licencia que elijamos… etc)
    (http://reviews.cnet.com/Microsoft_Office_SharePoint_Portal_Server_2003/4014-3526_7-30541138.html)
  • Requiere una máquina potente. Recomiendan que se instale en una máquina con 2Gb de memoria. Yo lo he instalado en un virtual server con 640Mb asiganados a la máquina virtual, y creedme que en mi equipo con 1 Gb de memoria física se arrastra.
  • Requiere Excel 2007 para publicar nuestras pivot table: al final Excel Services representa los datos de una hoja Excel, con lo que estamos condenados a que Excel sea nuestra herramienta de desarrollo de "dashboards" (cierto es que Excel es el software preferido de los analistas de negocios, así que en cierto modo esta desventaja no es muy seria).

A veces, en proyectos pequeños, nos sobra el puma y nos basta con un ratón. Buscando ese ratón, he dado con el nuevo RadarCube ASP.NET for Microsoft Analysis Services. Es algo menos espectacular que Excel Services, pero a cambio nos ofrece:

  • Precios de 450$ para un único desarrollador y servidor, 2500$ en una versión libre de royalties para un equipo de desarrollo no distribuido, y 5000$ en versión ilimitada, con fuentes. ¡Calderilla para un desarrollador de Bilbao!
  • Posibilidad de conectarse a SSAS o a cubos locales (archivos "cub")
  • Informes preconfigurados, o interfaz de tipo "pivot table".
  • Posibilidad de conectarse con los controles gráficos de Dundas, para representar de forma gráfica los datos seleccionados en el control
  • Apariencia personalizable por medio de hojas de estilo

El control de RadarSoft es para ASP.NET 2.0, soporta Ajax, y presenta este aspecto:

Bueno, en la web del producto encontraréis ejemplos mucho más espectaculares que el mío (no he dedicado demasiado tiempo a "embellecer" el ejemplo). Podéis consultarla en:
http://www.radar-soft.com/products/radaraspnet_msas.aspx

Como puntos negativos que le he visto a la versión 1.03:

  • Fallitos al representar las "Measures" estructuradas con "DisplayFolders" (carpetas). No graves: en la base de datos de AdventureWorks los DisplayFolders los coge en inglés (a pesar de estar la máquina configurada en castellano). En una base de datos mía, con metadatos en castellano e inglés, cogía correctamente los metadatos en, pero sólo me cogía el primer nivel de carpetas (no subcarpetas). Los hechos más allá del primer nivel de subcarpetas, me los mostraba en la raíz.
  • Cuando una dimensión tiene un único nivel, no muestra dimensión y nivel… sino que muestra directamente el nivel de la dimensión. Es un pelín raro, aunque uno se acostumbra.
  • En tiempo de diseño, deja establecer la propiedad "Cube" por medio de un ComboBox. Pues bien, este combo, mezcla cubos, perspectivas y dimensiones… hay que tener cuidado al seleccionar algo que sea un cubo o una perspectiva.
  • En general… es una primera versión, y tiene algunos signos de inmadurez, pero no es nada que parezca especialmente grave.

Bueno, pues aunque os parezca mentira, RadarSoft no me ha pagado por escribir esto… La moraleja que quería transmitir es que es el proyecto quien manda, y es el proyecto quien nos dirá si se requiere un puma, un ratón, o si tenemos que arreglarnos con un jilguero con careta de rapaz. Así que desde aquí animo a las empresas a que produzcan controles de representación de datos multidimensionales: es un segmento del mercado en el que todavía cabe mucha fauna, y en el que nosotros los desarrolladores, sabemos apreciar la diversidad.