Il presente articolo è stato tradotto automaticamente.
SQL Server
Unit test di cubi OLAP per SQL Server mediante il linguaggio C#
Download del codice di esempio associato
Mi sento un po' come Thomas Jefferson, quando dico, "teniamo queste verità essere lapalissiano, che tutto il codice ha determinati diritti inalienabili e che tra questi diritti è la capacità di essere accuratamente unità testati in modo semplice e conciso, quindi bug possono essere facilmente identificati e interruzioni di produzione ridotti al minimo." Un po ' drammatico, sì, ma ottiene il mio punto.
Naturalmente, la maggior parte dei sviluppatori credono loro codice dovrebbe essere provate, ma cosa succede quando la definizione di "codice" è sfocata? Questa era la situazione, mi ritrovai nel recente, quando ha presentato con una questione complessa e il compito di trovare una soluzione. Un gruppo di sviluppatori è stato coinvolto con la scrittura di un cubo di complessa elaborazione analitica online (OLAP) utilizzando SQL Server Analysis Services (SSAS). Questo cubo aveva numerose dimensioni tutto legati ad un tavolo fatto estremamente complesso. Perché gli sviluppatori sono stati abbastanza abili a sviluppare cubi, sono stati in grado di mettere insieme il cubo, ma convalidando i risultati delle loro query (Multidimensional Expression) è stato un compito arduo. La difficoltà è stata aggravata da una serie di fattori, tra cui la quantità di dati in dimensioni e tabella dei fatti, così come il tempo e le risorse necessarie per costruire il cubo di calcolo. Una volta costruito il cubo, i risultati (prodotti dalle query MDX) sono stati inviati agli utenti. Se gli utenti trovano un problema con i dati, ci sarebbe voluto molto tempo per rintracciare il problema. Inoltre, una volta che il problema di fondo è stato scoperto e fisso, il cubo avrebbe bisogno di essere rigenerato. A peggiorare, se le dimensioni sono stati aggiunti, è stata aggiornata la tabella sottostante o il cubo è stato costruito utilizzando diverse aggregazioni, non non c'era alcun modo per determinare gli effetti completo di questi cambiamenti. Una modifica apparentemente innocente potrebbe avere un effetto di vasta portato e CSS su query al cubo.
La soluzione per l'enigma del cubo è di creare un ambiente e un processo in cui potete fase dimensioni del cubo e fatti utilizzando una quantità limitata di dati ed eseguire query sul cubo utilizzando la versione di produzione dello schema del cubo. Idealmente la versione di prova del cubo sarà creata da zero ogni volta eseguire gli unit test, eliminando la possibilità per gli effetti collaterali che si verificano da manufatti preesistenti. Altri requisiti per unit test framework (e davvero questi si applicano alla maggior parte dei framework di test di unità indipendentemente dall'applicazione di destinazione) per garantire le convalide di prova sono ripetibili e se l'errore si verifica a rapidamente e facilmente individuare perché il test fallito (avendo il test case di dire "non è riuscita perché i dati non corrispondono" è meno di ideale).
In questo articolo, presento un quadro che consente di creare una suite di unit test per convalidare l'output basato su MDX di un cubo OLAP. L'architettura descritta consente la creazione di un cubo utilizzando uno schema esistente, all'interno del proprio database unit test, ricreato ogni volta che viene eseguito la suite di test. Consente inoltre di fornire le query MDX che vengono eseguite contro la versione neonata unit test del cubo. Ulteriormente, convalida i risultati contro un modello pre-esistente e li presenta in formato HTML semplice. Questo modello di test caso convalida rispetto a un modello può essere esteso al framework di unit test in cui i risultati dati sono grandi e complesse.
Panoramica di cubo
Prima di approfondire la soluzione per il problema del cubo-test, andrò brevemente sopra i concetti e i componenti che compongono un cubo. Cubi sono un mezzo per accedere velocemente i dati conservati all'interno di un data warehouse. Cubetti di organizzano e riepilogano i dati in una struttura multidimensionale. Cubi sono la componente principale della tecnologia OLAP e forniscono un meccanismo di facile utilizzo per l'interrogazione di dati con tempi di risposta rapidi e prevedibili. Un cubo è costituito da dati di dimensione e misure (fatti numerici). Il tavolo centrale di un cubo è conosciuto come la tabella dei fatti, ed è la fonte delle misure del cubo. Tabelle dimensionali fa riferimento la tabella dei fatti, e contengono livelli gerarchici di informazioni che possono essere interrogati. La gerarchia di dimensione consente agli utenti di porre domande ad alto livello. Quindi, utilizzando gerarchia della dimensione, gli utenti possono ottenere ulteriori dettagli.
Cubi sono contenuti all'interno di un database. Gli oggetti che compongono la struttura del cubo per un determinato database sono come segue:
- Fonti di dati: Queste sono le fonti delle informazioni deve essere caricato nel cubo.
- Misure: Questi sono i valori numerici rappresentati nel cubo. Essi possono essere date, ma sono solitamente numerici con differenti livelli di aggregazione (ad esempio, Sum, Max, Min e Count).
- Dimensioni: Questi sono gli attributi associati con misure. Dati aziendali, nomi di clienti e regioni geografiche sono esempi comuni di dimensioni.
- Partizioni: Una partizione definisce una parte di fatto dati caricati in un gruppo di misure. Con la creazione di più partizioni, il cubo può essere elaborato in parallelo e memorizzati e interrogati separatamente, quindi migliorando le prestazioni. Si possono anche rielaborare singole partizioni senza influire sulle altre partizioni.
- Ruoli del cubo: Ogni cubo dovrebbe avere almeno un ruolo del cubo per consentire l'accesso agli utenti finali. Ruoli possono consentire l'accesso a tutti i dati o un sottoinsieme di dati memorizzati all'interno del cubo, sulla base di un ID utente individuali o un gruppo di Active Directory.
La definizione dello schema di un cubo può essere estratti da SSAS sotto forma di XML for Analysis (XMLA). XMLA è un protocollo basato su SOAP XML che dà accesso al cubo su HTTP. La definizione di XMLA contiene tutti i dettagli per ogni cinque cubo oggetti descritti in precedenza. XMLA consente di ricreare il cubo sul server o database diversi, rapidamente e facilmente. È la pietra angolare da cui viene creato il cubo unità-testabile.
Una volta creato un cubo ed elaborato, le misure di dati possono essere consultate utilizzando un mix and match di varietà di dimensioni utilizzato per crearlo. Cubi vengono eseguite query con la sintassi MDX sopraccennata. Come una query SQL, una query MDX contiene una richiesta di dati (utilizzando l'istruzione SELECT), un punto dati (tramite l'istruzione FROM) e un filtro di dati facoltativi (utilizzando la clausola WHERE). Ecco un esempio di base:
SELECT {[<axis specification using Measures>]...} ON AXIS(0),
{[<axis specification using a dimension hierarchy>]...} ON AXIS(1)
FROM [<cube>]
WHERE (<filter specification>)
Il cubo Sales di esempio
Ho creato un cubo di esempio che consente rapidamente eseguire query sui dati di vendita per i vari negozi in varie date dai vari ospiti (vedere Figura 1).
Figura 1 Diagramma di esempio cubo Sales Database
Il cubo è costituito da quattro tabelle di collegamento a una tabella dei fatti. Per semplicità, la tabella contiene una misura chiamata quantità, che rappresenta la quantità di un determinato elemento venduto a un determinato cliente in una posizione di archivio su una data data di acquisto. Con questa configurazione del cubo, l'utente può rapidamente eseguire una query per vari fatti utilizzando varie dimensioni. Ad esempio, i dirigenti aziendali possono ottenere una chiara idea di che stanno vendendo prodotti in cui negozi, o essi possono approfondire dettagli quali quali oggetti vendono migliori durante un particolare anno o mese. Avere un gran numero di dimensioni consente un dati sales executive vista in una varietà di modi, fornendo la migliore spaccato la performance dei negozi.
Creando la versione di Unit Test del cubo
Come accennato, la definizione del cubo può essere estratti da SSAS sotto forma di un documento XMLA. Questo documento XMLA è utilizzato per creare la versione di unit test del cubo. Utilizzando la definizione di produzione del cubo assicura che i test eserciterà con precisione tutte le caratteristiche del cubo in questione. Si interfaccia con il motore SSAS utilizzando Microsoft.AnalysisServices.dll, che può essere trovato nelle assemblee SQL Server SDK.
L'oggetto utilizzato per generare il cubo è XMLAtoCube. Il costruttore prende in una directory di configurazione di base in cui è memorizzato il XMLA. La struttura di directory che ho scelto per ospitare il cubo XMLA è < directory base > \ < nome server di produzione > \< nome database di produzione >.
XMLAtoCube contiene un metodo pubblico, CreateCubeFromXMLA, che accetta i seguenti parametri (vedere codice del metodo listato 1 nel file Listings.zip nel download del codice):
- SourceServerName: Il nome del server di produzione che contiene il cubo.
- TargetServerName: Il nome del server che ospiterà la versione di unit test del cubo.
- SourceDatabaseName: Il nome del database di produzione che contiene il cubo.
- NomeDatabaseDestinazione: Il nome del database che ospiterà la versione di unit test del cubo.
- DataSourceProviderDefinition: La stringa di connessione URL a cui punta la versione di unit test del cubo il luogo della sua origine dimensioni e tabella dei fatti. Questa sarà la fonte di dati ridotta dello unit test.
CreateCubeFromXMLA prima stabilisce una connessione con la versione del server Google analytics unit test e scende la versione di unit test del database cubo se già esistente. L'abbandono del database è importante perché assicura i test sono condotti in un ambiente pulito senza alcun residuo di artefatti contaminating l'esito. La connessione al server di Google analytics viene eseguita all'interno del metodo ConnectToServer utilizzando un'istanza di Microsoft.AnalysisServices.Server. Una chiamata a Connect (stringa di connessione del < >) utilizzando il nome del server di unit test passato stabilisce la connessione (Vedi Listato 2 nel download del codice). Una volta stabilita correttamente la connessione al server, la versione di unit test del database cubo viene rimosso se già esistente. Questa rimozione è fatto con il metodo DropDatabase, che è passato nell'istanza del Server collegato e il nome del database unit test a goccia (TargetServerName). DropDatabase assicura che l'istanza del server è connesso, cerca il Microsoft.AnalysisServices.Database utilizzando il nome del database unit test passato e, se il database esiste (istanza del database non è null), il database viene eliminato (vedere Listato 3 nel download del codice).
Il passo successivo è quello di prendere definizione XMLA originale del cubo e generare la versione di unit test. La versione di unit test contiene le stesse dimensioni, gerarchie di dimensione, misure, partizioni, ruoli e così via come il cubo originale. La differenza è che è generato in un nuovo database che punta a un percorso diverso per i relativi dati di origine. Il metodo AddCubeToDatabase crea il cubo di prova (vedere Listato 4 nel download del codice). AddCubeToDatabase legge la definizione XMLA dal file system utilizzando la convenzione di denominazione citata in precedenza. Il nome del file XMLA è passato a un'istanza di XmlTextReader alla costruzione. Il XMLA è letto utilizzando il metodo Microsoft.AnalysisServices.Utils.Deserialize, che viene passato XmlTextReader e una nuova istanza della Microsoft.AnalysisServices.Database. L'istanza di oggetto di Database contiene ora la definizione completa del cubo, ma tale definizione ha ancora del cubo originale database nome e un'origine dati. Semplicemente che punta al database unit test coinvolge impostando le proprietà Name e ID del Database"a nome di database unit test" (NomeDatabaseDestinazione) parametro. Quindi, questo database può essere aggiunti all'istanza del server di Google analytics unit test chiamando Server.Databases.Add (< database unit test >) seguito dal metodo Update.
Dopo aver creato il database, è necessario aggiornare l'origine dati del cubo per la raccolta di dati esterni unit test. L'istanza di Database ha un elenco di istanze di DataSource (di solito solo una fonte di dati è associata a un cubo) e la stringa di connessione di unit test è utilizzata per sostituire la stringa di connessione contenuta all'interno della definizione di XMLA. Dopo la stringa di connessione è sostituita, una chiamata al metodo DataSource si aggiorna all'interno del server SSAS. A questo punto, la personalizzazione della definizione XMLA è completata e i rimanenti pezzi del cubo (DataSourceView, dimensioni e cubi) vengono aggiornati ed elaborati.
Dopo la chiamata a AddCubeToDatabase è completa, la versione di unit test del cubo è stata creata all'interno del server specificato utilizzando il database unit test prescelto. Indica un set personalizzato di dati di origine. Anche se il cubo è stato creato, è ancora vuota. Per popolare le dimensioni con i dati di origine, le dimensioni devono essere elaborate. Il metodo ProcessDimensions viene chiamato e passato l'istanza del Database. Tutte le quote all'interno del Database vengono elaborate utilizzando il metodo Dimension.Process(ProcessType.ProcessFull). Una volta che le dimensioni sono stata trattate con successo, i cubi all'interno del database unit test vengono elaborati utilizzando il metodo ProcessCube. Come ProcessDimensions, ProcessCube accetta l'istanza del Database, consente di scorrere tutti i cubi nel Database e chiama Cube.Process(ProcessType.ProcessFull) (vedere listato 5 nel download del codice). A questo punto, il cubo di unit test è stato creato e popolato con i dati di test mirati. Il passo successivo è quello di eseguire test contro di esso per assicurare che il cubo si comporta come previsto.
Convalida il cubo
Anche se la soluzione per la convalida si rivolge per il cubo, possibile applicare il modello di progettazione utilizzato altri unit test Framework. Il modello impiegato è test utilizzando la convalida del modello. In poche parole: Quando il test viene eseguito, una struttura di dati contenente i risultati è creata e validata contro una versione precedentemente memorizzata della struttura dei dati che è stata ritenuta corretta. Perché è difficile convalidare una struttura di dati binari, una rappresentazione HTML della struttura è presentata per il tester di unità. Il tester utilizza la rappresentazione HTML per convalidare i risultati del test iniziale dello unit test (per assicurarsi che i risultati corrispondano a quanto previsto) ed esaminare che cosa ha causato uno unit test a mancare durante le successive esecuzioni. In un fallimento, l'HTML Visualizza la struttura dei dati originali come pure quale pezzo di dati struttura convalida non riuscita e perché. Questo è fondamentale per aiutare il problema di debug.
Il modo migliore per testare la maggior parte degli scenari è utilizzando la metodologia di collaudo "scatola nera". Un test della scatola nera passa ingresso e uscita di convalida. Perché l'output di un cubo è il risultato di una query, l'input è la query. Utilizzare istruzioni MDX per eseguire query su un cubo. Il cubo interpreta la query MDX, restituisce un risultato. Il risultato è in forma di righe e colonne che sono una rappresentazione delle dimensioni scelto per eseguire la query MDX. Il risultato della query MDX può essere abbastanza complesso perché la query può coinvolgere molte dimensioni, risultando in una varietà di righe e colonne nell'output. I dati della struttura prescelta per contenere che i dati del cubo sono un dizionario di CubeRow istanze digitato il nome della riga cubo. La classe CubeRow contiene due strutture di dati alternativo — quello utilizzato dipende dalla situazione. Una struttura di dati è un dizionario di CubeTuple istanze digitato il nome della colonna cubo. Il CubeTuple è semplicemente un oggetto che contiene il nome della colonna del cubo e il valore della colonna specificata. I dizionario di CubeTuble oggetti è utilizzato quando la colonna data cubo contiene un valore. La seconda struttura di dati è un altro dizionario, mapping di un nome di riga a un'istanza di CubeRow. Perché una query MDX può avere molti livelli di dimensioni di riga, CubeRow contiene un proprio dizionario di nome riga e istanze di CubeRow.
Non solo sono i risultati del cubo memorizzati in un dizionario < String, CubeRow > istanza, i risultati sono archiviati in una stringa HTML. La stringa HTML permette il tester avere una rappresentazione visiva dei risultati cubo. Tabella HTML contiene più livelli di intestazioni di riga e di colonna e le celle di tabella HTML contengono i valori MDX. Figura 2 Mostra la disposizione della rappresentazione HTML di un risultato di query MDX.
Figura 2 il Layout della rappresentazione HTML di un risultato di Query MDX
Dimensione di colonna Didascalia 1 (valore 1) |
Dimensione di colonna Didascalia 1 (valore 1) |
Dimensione di colonna Didascalia 1 (valore 2) |
Dimensione di colonna Didascalia 1 (valore 2) |
||
Dimensione di colonna Didascalia 2 (valore 1) |
Dimensione di colonna Didascalia 2 (valore 2) |
Dimensione di colonna Didascalia 2 (valore 1) |
Dimensione di colonna Didascalia 2 (valore 2) |
||
Dimensione di riga Didascalia 1 (valore 1) |
Dimensione di riga Didascalia 2 (valore 1) |
Valore di risultato MDX | Valore di risultato MDX | Valore di risultato MDX | Valore di risultato MDX |
Dimensione di riga Didascalia 1 (valore 1) |
Dimensione di riga Didascalia 2 (valore 2) |
Valore di risultato MDX | Valore di risultato MDX | Valore di risultato MDX | Valore di risultato MDX |
Dimensione di riga Didascalia 1 (valore 2) |
Dimensione di riga Didascalia 2 (valore 1) |
Valore di risultato MDX | Valore di risultato MDX | Valore di risultato MDX | Valore di risultato MDX |
Dimensione di riga Didascalia 1 (valore 2) |
Dimensione di riga Didascalia 2 (valore 2) |
Valore di risultato MDX | Valore di risultato MDX | Valore di risultato MDX | Valore di risultato MDX |
BaseMDXTest contiene il codice per l'esecuzione di una query MDX e costruire la struttura di dati del risultato MDX, nonché il rappresentante XML. BaseMDXTest utilizza Microsoft.AnalysisServices.AdomdClient.dll, trovato negli assembly SDK SQL Server , connettersi al cubo di SSAS ed eseguire le query MDX. BuildTemplate è il metodo che esegue la query MDX e costruisce il MDX risultato dizionario, così come la rappresentazione HTML. In primo luogo, viene stabilita una connessione al cubo. Al fine di stabilire e aprire una connessione, viene passata la stringa di connessione a un'istanza di MicrosoftAnalysisServices.AdomdClient.AdomdConnection. Quindi viene chiamato il metodo Open nell'istanza della connessione appena creata e l'istanza della connessione viene restituito al chiamante. Una volta creato un collegamento, un'istanza del MicrosoftAnalysisServices.AdomdClient.AdomdCommand metodo è stabilito e viene passata la stringa di query MDX e l'istanza di AdomdConnection. Una chiamata al metodo ExecuteCellSet esegue la query MDX contro la versione di unit test del cubo e restituisce un'istanza di MicrosoftAnalysisServices.AdomdClient.CellSet (vedere Listing 6 nel download del codice).
Dopo aver recuperato l'istanza del set di celle, viene effettuato un controllo per assicurarsi che il set di risultati ha due assi. Asse 0 contiene le colonne e asse 1 contiene le righe. Ogni asse contiene un insieme di posizione oggetti. Una posizione rappresenta una tupla sull'asse determinato e contiene uno o più oggetti membro. Un membro rappresenta le intestazioni di riga o colonna per una determinata posizione (vedere Listing 7 nel download del codice).
Successivamente, viene calcolato il numero di righe e colonne restituite dalla query MDX. Questo viene fatto prendendo il numero di righe (il numero di posizione oggetti sull'asse 1) più il numero di dimensioni della colonna (CellSet.Axes[0].Posizioni [0].Members.Count). Il numero di colonne è aggiunto alle righe perché quando che rappresenta i risultati MDX come una tabella bidimensionale, le colonne sono incluse all'interno del set di righe. Allo stesso modo, il numero di colonne viene calcolato prendendo il numero di posizione oggetti sull'asse 0 più il numero di dimensioni di riga (vedere listato 8 nel download del codice).
Dato il numero di righe e colonne, i dizionario di CubeRow gli oggetti possono essere generati come pure la rappresentazione HTML di output MDX. Listato 9 nel codice di download contiene il codice per attraversare il set di risultati MDX, creando il codice HTML e memorizzare i risultati nel dizionario CubeRow. In primo luogo, il numero di righe è cappio attraverso. Se il numero di riga è maggiore del numero di dimensioni della colonna, quindi è noto che una nuova riga di risultati MDX è disponibile. In altre parole, quando sono state passate le righe delle intestazioni di colonna, i dati MDX sono disponibili. A questo punto, viene creato un nuovo oggetto CubeRow.
Il passo successivo è quello di scorrere in ogni colonna all'interno della riga. Se il numero di riga corrente è inferiore al numero di dimensioni della colonna, la riga corrente è in realtà una riga delle intestazioni di colonna. Per il dizionario, le didascalie di intestazione vengono concatenate per ogni posizione di colonna, separate da due punti. Questo significa che se un'intestazione è composta da molteplici dimensioni, ogni colonna sarà concatenato con la dimensione specificata in ordine decrescente di risoluzione. La generazione di HTML per un'intestazione di colonna è più semplice. La didascalia di dimensione è semplicemente circondata dai tag di intestazione di tabella HTML (< th >< /th >). Per ogni caso, la didascalia di dimensione corrente viene recuperata ottenendo l'intestazione asse (CellSet.Axis[0]) e l'accesso alla posizione di colonna (colonna conteggio corrente meno il conteggio di dimensione riga corrente) e il membro corrente all'interno di tale posizione (riga conteggio corrente).
Se il numero di riga corrente è maggiore del numero di dimensioni della colonna, quindi le intestazioni di colonna non è non più elaborato. Invece, la MDX set riga tuple sono successivamente in linea per l'elaborazione. Simili a colonne, che hanno intestazioni, MDX righe set di risultati possono anche avere le intestazioni. Se il numero di colonna in fase di elaborazione è inferiore al numero di dimensioni della riga, quindi un'intestazione di riga viene elaborata. Per ogni intestazione di riga, un nuovo dizionario < stringa, CubeRow > è creato, aggiunto al dizionario corrente e impostare come il risultato attuale di MDX dizionario. Ciò significa che per ogni intestazione di riga, esiste un dizionario di righe che contiene più dati di risultato granulati MDX.
Estraendo la didascalia di intestazione di riga è simile per estrarre la didascalia di intestazione di colonna. La didascalia di riga viene recuperata dall'oggetto nella posizione corrente colonna dalla posizione presso la riga corrente dal CellSet.Axis[1 membro]. La didascalia di riga è la chiave per il dizionario di CubeRows, e se il dizionario CubeRow attuale non ha la didascalia riga estratta, l'oggetto CubeRow viene aggiunto al dizionario codificato dalla didascalia di fila. Se la didascalia di riga esiste nel dizionario corrente CubeRow, l'oggetto CubeRow viene estratto e impostato come currentCubeRow.
Dopo la riga didascalia membri sono stati esauriti (cioè il conteggio corrente della colonna è maggiore del numero di dimensioni della riga) e le righe di intestazione di colonna sono state attraversate (ovvero, l'attuale numero di righe è maggiore del numero di dimensioni della colonna), è il momento di aggiungere i valori delle celle MDX per l'oggetto corrente CubeRow. Ogni combinazione di un'intestazione di colonna e il valore della colonna è considerato compongono una sola istanza di CubeTuple. Ogni CubeRow contiene un dizionario di CubeTuple oggetti codificati dall'intestazione di colonna. L'intestazione di colonna viene recuperato da una matrice di intestazioni di colonna precedentemente costruito (ricordiamo un'intestazione di colonna è un colon -delimitato da stringa di tutte le didascalie colonna concatenati). L'indice dell'intestazione di colonna è il numero di colonne attuale meno il numero di dimensioni di riga (il conteggio totale colonna include le dimensioni della riga). Il valore corrente del set di celle MDX è estratto mediante l'accesso appropriato bidimensionale (colonna, riga) punto. Ciò è basata sul conteggio colonna corrente (meno il numero di dimensioni di riga) e l'attuale numero di righe (meno il numero di dimensioni della colonna). Questo valore viene aggiunto all'oggetto CubeRow utilizzando il metodo AddTuple, passandogli l'intestazione di colonna e il valore della colonna. Allo stesso tempo, la rappresentazione HTML viene aggiornata aggiungendo il valore della cella MDX tra gettoni di dimensione (/ TD > < td ><) tabella HTML. Vedere Figura 3 per una rappresentazione grafica del dizionario < stringa, CubeRow >.
Rappresentazione di dizionario sia l'HTML del template sono persistenti in un percorso di file precedentemente definito utilizzando il metodo BaseMDXTest.PersistTemplate. Perché il modello deve essere convalidata manualmente dallo sviluppatore di unit test, il test è considerato riuscita, motivo per cui il metodo BaseMDXTest.TestMDXQuery restituisce falso per il successo.
Figura 3 rappresentazione grafica del dizionario CubeRow
Una volta creato il modello, vengono convalidate esecuzioni successive della stessa prova contro il modello memorizzato in precedenza. Quando viene chiamato il metodo TestMDXQuery, in primo luogo è effettuato un controllo per vedere se esiste un test con il nome specificato. Se lo fa e una nuova creazione di modello non è richiesto (richiesta di ricreare il modello può verificarsi se il modello attuale non è corretto), poi il modello di risultato del test viene caricato in memoria. Il modello include la rappresentazione dell'oggetto e la rappresentazione HTML del set di risultati MDX. Il metodo BaseMDXTest.RunComparison esegue la query MDX e confronta i risultati contro il modello memorizzato. I risultati della query MDX vengono attraversati nello stesso modo come erano durante la creazione del modello. La differenza principale tra la creazione del modello originale e la convalida contro il modello è che invece di creare il dizionario < stringa, CubeRow >, le ricerche sono fatte contro il modello dizionario, controllando per vedere se esistono gli stessi risultati di query MDX. Quando scorrendo le righe e le colonne, tabella HTML viene creata nello stesso modo come durante la creazione del modello, tranne che ora sono colorate le celle di tabella HTML. Una cella verde indica che la cella corrisponde al modello originale; una cellula rossa indica una mancata corrispondenza. Colorare le celle e presentandoli in una tabella HTML, il tester di unità ha una vista immediata perché il caso test passati o fallito. Ogni volta che viene trovato un disadattamento, un valore booleano (testPass) è impostato su false per indicare il caso test fallito.
Durante l'attraversamento della MDX query risultati e convalida di loro contro il modello dizionario, ogni CubeTuple (un oggetto che contiene la dimensione della colonna, concatenati nomi e il valore della colonna) trovato viene rimosso dal dizionario corrente CubeRow di oggetti CubeTuple. Pertanto, dopo aver passato l'intero risultato della query MDX, il modello originale dizionario dovrebbe avere oggetti CubeRow con un vuoto oggetti dizionario di CubeTuple se il risultato MDX è stata una partita completa. Altrimenti il risultato della query MDX nuovo era mancante dati che era contenuti nel risultato originale. Il metodo BaseMDXTest.CheckForExtraDataInTemplate esamina il modello dizionario per rimanenti oggetti CubeTuple, l'esecuzione in modo ricorsivo e restituisce il valore true se gli oggetti CubeTuple rimangono. Il testPass Boolean all'interno del metodo RunComparison è impostata su false se sono trovati dati aggiuntivi e fallisce il test case.
Dopo il MDX risultati sono stati completamente attraversati e convalidate il modello dizionario, un'istanza del cuboComparisonResult oggetto restituito. È costruito con il testPass Boolean e tabella HTML che mostra il risultato. Il metodo BaseMDXTest.TestMDXQuery utilizza CubeComparisonResult per costruire una pagina HTML che mostra la tabella HTML risultato di query MDX originale e la tabella di confronto HTML. L'HTML viene mantenuta nel file System mediante l'esecuzione di una chiamata al metodo BaseMDXTest.PersistTestReport, che crea una pagina Web TestReport.html riepilogo elenca tutte le esecuzioni dei test e link ai loro HTML risultato pagine, nonché un riepilogo del numero di casi di test che ha passato e non è riuscito.
Test del cubo di acquisto
Utilizzando entrambi i componenti del framework cubo-test — il codice di creazione-cubo (XMLAtoCube) e il MDX query modello risultato (BaseMDXTest) — è possibile creare unit test case che convalidano il cubo. Sebbene il codice per il quadro è molto esteso, creando i casi di test è semplice e lineare. Listato 10 nel codice download contiene sample unit test per la convalida del cubo acquisto. Questi casi di test utilizzano il framework di test di Microsoft, ma qualsiasi framework di test può essere incorporato.
L'oggetto unit test (PurchaseCubeTest nell'esempio) eredita da BaseMDXTest. Il costruttore predefinito di PurchaseCubeTest costruisce BaseMDXTest con l'URL del server SSAS dove si trova il cubo e la directory di base in cui archiviare il modello di risultato query MDX e risultati dei test successivi.
Un metodo [TestInitialize] viene utilizzato per creare la versione di unit test del cubo acquisto. Esso utilizza la definizione di XMLA del cubo originale e viene creata sul server SSAS unit test (targetServerName), utilizzando un database unit test (NomeDatabaseDestinazione). Segnala, inoltre, l'URL di origine dati per la localizzazione dei dati test di dimensione e fatto. [TestInitialize] viene eseguito una sola volta per un determinato [TestClass], che assicura il cubo viene creato solo all'inizio del test.
I casi test stessi sono eseguiti all'interno di [TestMethod] metodi annotati. Ogni test case è semplice. La query MDX è definita e poi eseguiti utilizzando il metodo ereditato BaseMDXTest.TestMDXQuery, denominazione del test case e passandogli la query MDX. TestMDXQuery restituisce true se passa il test o false se non lo fa, e un metodo superato viene utilizzato per passare o fallire il test di unità. Dopo tutti i test sono stati eseguiti, il documento di prova HTML risultante può essere aperto e può essere esaminati i casi di test fallito. Figura 4 contiene un esempio di output HTML di una delle prove.
Figura 4 l'Output HTML di un Test di esempio
Codice adeguatamente testati
Anche se non è semplice, anche un cubo OLAP può essere provate utilizzando c#. L'inclusione di entrambi i Microsoft.AnalysisServices.dll e i file Microsoft.AnalysisServicesAdomdClient.dll all'interno di assembly SQL Server fornisce le API per creazione e l'esecuzione di query cubi SSAS. L'architettura presentata consente di aggiungere un ricco set di unit test che produce output in un formato leggibile in modo test caso guasti possono essere rapidamente identificati. Il metodo di validazione di test case di modello può essere applicato ad altre architetture di unit test dove la convalida di uscita non è semplice. Esempi di questi spaziano da applicazioni che si basano sulla persistenza di database relazionale tradizionale dove il modello contiene i dati dovrebbe essere memorizzato nel database dopo che l'applicazione viene eseguita, per applicazioni di interfaccia utente che memorizzare lo stato dell'interfaccia utente in una struttura dati e visualizzare l'interfaccia utente in un form HTML.
Non sono molto sicuro se Thomas Jefferson o padri fondatori sarebbe confrontare le libertà di una nazione ai diritti di adeguatamente testati codice, ma sono abbastanza sicuro che gli utenti e supervisori sarebbe contenti di sapere che l'applicazione è stato correttamente messo alla prova.
Mark Nadelson è uno sviluppatore di software professionale con 22 anni di esperienza nel settore delle telecomunicazioni, Internet e finanza. Nel corso della sua carriera ha usato un certo numero di linguaggi di programmazione tra cui Assemblea, C, C++, Java e c#. Nadelson è anche autore di due libri e una serie di articoli tecnici.
Grazie ai seguenti esperti tecnici per la revisione di questo articolo: David Neigler (SAC Capital Advisors LP) e Joe Sampino(SAC Capital Advisors LP)
David Neigler è un gestore di sviluppo nel settore dei servizi finanziari, lavorando al SAC Capital Advisors LP. La sua attenzione è lo sviluppo di sistemi che risolvono i problemi dati big affrontati dalle società finanziarie facendo grandi volumi di trading.
Joe Sampino lavora al SAC Capital Advisors LP, lo sviluppo di piattaforme di enterprise business intelligence per le grandi banche e imprese di investimento. Egli crea e gestisce il data warehouse, cubi di Analysis Services SQL Server e sistemi di analisi/reporting dati per interni, esterni, regolamentazione e conformità ha bisogno. "