Pour enfoncer le clou de l’article de Florian Eiden « BI.Quality : tests automatisés pour comparer des données entre SSAS et SQL Server » je vous propose de voir comment écrire nos propres tests unitaires dans nos projets décisionnels Microsoft.
Je vais commencer par remercier Fabrice de m’avoir montré comment réaliser cela directement dans Visual Studio.
- Créer un projet de Test Unitaire
- Créer une classe qui va assurer la connexion et la gestion des données OLAP (Uniquement si vous voulez faire des tests avec OLAP)
/** * @author: Fabrice Michellonet */ using System; using Microsoft.AnalysisServices.AdomdClient; namespace BiTests { public class MicroMd { private readonly string _connectionString; public MicroMd(string connectionString) { _connectionString = connectionString; } public T GetScalar(string mdx) { using (AdomdConnection conn = new AdomdConnection(_connectionString)) { using (AdomdCommand cmd = new AdomdCommand(mdx, conn)) { conn.Open(); var cellset = cmd.ExecuteCellSet(); if(cellset.Cells.Count > 1) throw new InvalidOperationException("The query must return exactly 1 cell"); return (T)cellset.Cells[0].Value; } } } } }
- Créer une/des classes dans laquelle nos tests seront joués.
/** * @author: Fabrice Michellonet */ using System.Collections.Generic; using System.Data.SqlClient; using System.Linq; using Dapper; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace BiTests { [TestClass] public class BiTestSample { private readonly SqlConnection _sqlConnection; private readonly MicroMd _microMd; public BiTestSample() { _sqlConnection = new SqlConnection( "Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=AdventureWorksDW2012;Data Source=(local)"); _microMd = new MicroMd( "Provider=MSOLAP.5;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=AdventureWorksDW2012;Data Source=(local)"); } [TestMethod] public void OlapInternetOrderCountShouldBeEqualTo27659() { var olapResult = _microMd.GetScalar("SELECT {[Measures].[Internet Order Count]} ON 0 FROM [Adventure Works]"); Assert.AreEqual(olapResult, 27659); } [TestMethod] public void SQLInternetOrderCountShouldBeEqualTo27659() { IEnumerable sqlResult = _sqlConnection.Query("SELECT count(distinct [SalesOrderNumber]) as Cnt FROM [dbo].[FactInternetSales]"); Assert.AreEqual(sqlResult.Count(), 1); Assert.AreEqual(sqlResult.First().Cnt, 27659); } [TestMethod] public void OrderCountShouldBeEqualInBothSystems() { var olapResult = _microMd.GetScalar("SELECT {[Measures].[Internet Order Count]} ON 0 FROM [Adventure Works]"); IEnumerable sqlResult = _sqlConnection.Query("SELECT count(distinct [SalesOrderNumber]) as Cnt FROM [dbo].[FactInternetSales]"); Assert.AreEqual(olapResult, sqlResult.First().Cnt); } } }
- Lancer les tests :
- Résultat :
Je constate que le test qui me permet de voir si les données dans la base SQL sont celles que j’attendais est passé, par contre les tests OLAP ont échoué.
Forcement, j’ai oublié de lancer mon serveur SSAS… Deuxième chance :
Voici une présentation basique des tests qu’il est possible de réaliser pour valider les données présentes dans un cube OLAP, il faut bien sûr approfondir pour pouvoir faire des tests plus complets et plus automatisés. D’autres articles à venir sur le sujet.
2 Comments
Tester les projets BI est un must (souvent sous-estimé) et peut s’avérer très complexe et rapidement chronophage. L’approche suggérée (écrire des tests unitaires en C#) ici fonctionne a plusieurs points faibles:
1. Cela demande des connaissances en C#, ce que tout le monde ne dispose pas nécessairement (Ce n’est pas une core-knowledge pour un développeur BI).
2. Mine de rien, cela demande un compilateur C# (ou un IDE tel que Visual Studio), pas toujours évident d’avoir accès à cela dans certaines entreprises.
3. La partie utile du test est moyée dans la masse. Dans les tests décris ce qui est pertinent c’est la query et le résultat attendu, le reste n’est que de la plomberie.
4. Quand le résultat attendu est plus complexe qu’un simple chiffre (quelques lignes et colonnes), le test s’allonge, rendant encore plus la partie importante du test noyée dans le code.
5. En l’absence du sous-framework spécifique à la BI, il faut que chacun réinvente la plomberie (classe MicroMd dans ce cas-ci). Quand les tests se veulent plus complexes que ceux proposés ici en exemple, la plomberie peut devenir bien plus complexe à écrire et maintenir.
6. En l’absence d’un outil spécifique, il est difficile de généraliser l’approche pour générer automatiquement de tels test-suites dans le cadre d’une non-regression entre deux versions par expl.
L’utilisation d’un framework de tests unitaires spécifiques à la BI (NBi ou BI.Quality ou QueryUnit), tel que Florian Eiden, le décris permet de corriger ces faiblesses et donc d’être plus rapidement efficace en se concentrant directement sur l’essentiel (la query, la comparaison à mettre en oeuvre et le résultat attendu) plutôt que sur la plomberie.
Notons aussi que les premiers tests d’un projet BI ne devraient pas êtres des tests aussi complexes que le résultat d’une query. Simplement vérifier que les dimensions, mesures ou que les membres adressés existent bien (et ne sont pas invisibles pour l’utilisateur ou mal orthographiés ou oubliés) est un travail qui permet d’éviter de nombreuses régressions et met en valeur votre release auprès de vos stakeholders car elle ne comporte pas les petits bugs « stupides » habituels qui agacent les personnes qui utiliseront votre release. Un framework tel que NBi (http://nbi.codeplex.com) va vous aider également à écrire rapidement ce genre de tests et augmentera la qualité de votre release.
Bonjour,
En voilà une réponse complete et argumentée.
Je suis d’accord 🙂