Comment valider l'intégrité de vos données SAS ? Maîtrisez PROC COMPARE et le masquage binaire

ATTENTION : Ce contenu est DÉSACTIVÉ. Il est invisible pour les visiteurs.
Niveau de difficulté
Débutant
Publié le :
Michael

Le Conseil de l'Expert

Michael
Responsable de l'infrastructure Viya.

a macro %ut_assert_dataset_content est un pilier pour la mise en place de tests unitaires (CI/CD) dans un environnement SAS, permettant de garantir la non-régression lors de modifications de code. Sa force réside dans l'exploitation intelligente de la variable macro automatique &SYSINFO, générée par la PROC COMPARE. Contrairement à une vérification visuelle, cette approche programmatique permet d'automatiser la validation de milliers d'observations en une fraction de seconde.

L'expertise technique ici se concentre sur l'utilisation du masque binaire (bmask) et de la fonction logique %SYSFUNC(BAND). Par défaut, PROC COMPARE peut signaler des différences mineures (comme un format ou un libellé différent) qui ne sont pas toujours critiques. En appliquant un masque de bits (opérateur AND), vous filtrez les codes de retour pour ne faire échouer le test que sur des critères fondamentaux : valeurs de données discordantes, observations manquantes ou structures de variables divergentes.

Une astuce d'expert pour renforcer ce test consiste à toujours s'assurer que vos datasets sont triés selon la même clé avant l'appel de la macro, car une différence dans l'ordre des observations activerait le bit de comparaison de &SYSINFO même si les données brutes sont identiques. L'intégration de cette assertion dans un framework de log (%ut_log_result) permet enfin de générer des rapports de conformité prêts pour l'audit.

La macro `ut_assert_dataset_content` est une assertion de test unitaire conçue pour valider que deux datasets sont identiques en termes de contenu. Elle utilise `PROC COMPARE` pour effectuer la comparaison. Le résultat est ensuite analysé via la variable macro automatique `&SYSINFO`. Un masque binaire (`bmask`) est utilisé avec la fonction `%SYSFUNC(BAND())` pour ignorer certaines différences (comme les libellés de variables ou les formats) et se concentrer sur les différences de contenu réelles (valeurs, observations ou variables manquantes). La macro met à jour des variables de framework de test (`ut_tst_res`, `ut_tst_det`) pour enregistrer le succès ou l'échec de l'assertion.
Analyse des données

Type : EXTERNE


La macro ne crée ni ne lit de données par elle-même. Elle opère sur deux datasets (`ds_01` et `ds_02`) qui doivent être fournis en tant que paramètres par l'environnement d'appel. L'origine de ces données est donc externe à la macro.

1 Bloc de code
PROC COMPARE
Explication :
Ce bloc définit la macro `ut_assert_dataset_content` avec ses paramètres. Il vérifie d'abord l'état du framework de test avant de continuer. Ensuite, il initialise le cas de test via `%ut_tst_init`. Le cœur de ce bloc est l'appel à `PROC COMPARE` avec l'option `noprint` pour comparer les deux datasets spécifiés (`ds_01` et `ds_02`) sans générer de sortie visible. Le résultat de la comparaison est stocké dans la variable macro automatique `&SYSINFO`.
Copié !
1%macro ut_assert_dataset_content(description=, ds_01=, ds_02=, bmask=1111111100000000, expected_result=PASS);
2/*
3 To be used to assert dataset contents are equals
4 description: description to explain why ds_01 content should be equal to ds_02 content
5 ds_01: name of the first dataset
6 ds_02: name of the second dataset
7*/
8 *-- Exit IF framework state is erroneous --*;
9 %IF &ut_state. %THEN %DO;
10 %return;
11 %END;
12 
13 %ut_tst_init(type=ut_assert_dataset_content, description=&description., expected_result=&expected_result.);
14 
15 PROC COMPARE DATA=&ds_01. compare=&ds_02. noprint;
16 RUN;
2 Bloc de code
Macro
Explication :
Ce bloc interprète le résultat de `PROC COMPARE`. Il convertit d'abord le masque binaire `bmask` en une valeur numérique. Ensuite, il utilise la fonction `%SYSFUNC(BAND())` pour effectuer une opération ET logique bit à bit entre la variable `&SYSINFO` et le masque. Si le résultat est 0, cela signifie qu'aucune des différences jugées importantes (définies par le masque) n'a été détectée, et le test est considéré comme réussi (`PASS`). Sinon, le test échoue (`FAIL`). Enfin, la macro `%ut_log_result` est appelée pour enregistrer le résultat du test.
Copié !
1 *-- Convert the binary mask to numeric --*;
2 %local nmask;
3 %let nmask = %sysfunc(inputn(&bmask., binary16.));
4 
5 *-- Use sysinfo and bmask to identify if any relevant bit is active --*;
6 %local rec;
7 %let res = %sysfunc(band(&sysinfo., &nmask.));
8
9 %IF &res. = 0 %THEN %DO;
10 %let ut_tst_res = PASS;
11 %let ut_tst_det = Datasets &ds_01. and &ds_02. have the same content;
12 %END;
13 %ELSE %DO;
14 %let ut_tst_res = FAIL;
15 %let ut_tst_det = Datasets &ds_01. and &ds_02. have different content;
16 %END;
17 
18 %ut_log_result;
19%mend ut_assert_dataset_content;
L'Astuce Pro
Pour securiser vos tests unitaires de comparaison, l astuce technique reside dans l exploitation fine de la macro-variable automatique &SYSINFO retournee par la PROC COMPARE : en utilisant un masque binaire (bmask) combine a la fonction %SYSFUNC(BAND()), vous pouvez ignorer des differences mineures comme les labels ou formats (bits de poids faible) pour vous concentrer uniquement sur l integrite des donnees ou la structure des colonnes (bits de poids fort), garantissant ainsi que votre assertion ne rejette pas deux tables fonctionnellement identiques mais dont les attributs de presentation divergent.
Ce matériel est fourni "tel quel" par We Are Cas. Il n'y a aucune garantie, expresse ou implicite, quant à la qualité marchande ou à l'adéquation à un usage particulier concernant le matériel ou le code contenu dans les présentes. We Are Cas n'est pas responsable des erreurs dans ce matériel tel qu'il existe maintenant ou existera, et We Are Cas ne fournit pas de support technique pour celui-ci.