Historique de la question
La vérification manuelle de la logique métier en SQL (au niveau des procédures stockées, fonctions, triggers) entraîne des erreurs qui ne se manifestent qu'en production. Pendant longtemps, les tests de scénarios SQL ont été informels et non standardisés. Cependant, le développement des technologies CI/CD exige des tests automatisés également pour le code SQL.
Problème
La plupart des développeurs se contentent de tests au niveau de l'application. L'absence de vérification des procédures et fonctions SQL elles-mêmes conduit à des défauts qui ne sont couverts par aucune suite de tests — par exemple, lors de modifications de la logique UDF ou de régressions dans les rapports.
Solution
Dans les workflows des équipes modernes, des tests unitaires et d'intégration sont organisés directement pour le code SQL. Pour le test unitaire, des frameworks tels que tSQLt (SQL Server), utPLSQL (Oracle), pgTAP (PostgreSQL) sont utilisés, et pour le test d'intégration — des environnements distincts pour la montée en charge des bases temporaires, l'application de migrations et la vérification des scénarios métier.
Exemple d'un test unitaire sur pgTAP :
-- Vérification de la séparation des salaires SELECT plan(2); SELECT is( (SELECT calc_salary(1)), 1000, 'Salaire pour l utilisateur 1 correct' ); SELECT isnt( (SELECT calc_salary(2)), 0, 'Le salaire utilisateur 2 n est pas zéro' ); SELECT finish();
Code de test d'intégration pour CI/CD :
psql -U user -d testdb < migrations.sql psql -U user -d testdb < test_data.sql psql -U user -d testdb -c "SELECT * FROM my_procedure_test();"
Caractéristiques clés :
Peut-on se passer de tests automatiques uniquement au niveau de l'application, si les procédures sont grandes ? Non, car les tests UI/API ne garantissent pas la correction de la logique SQL elle-même (par exemple, des conditions incorrectes dans les fonctions stockées ou des violations lors de la mise à jour des données). Les tests unitaires doivent couvrir toutes les ramifications exécutables dans le code SQL lui-même.
Suffit-il de lancer "manuellement" des scripts de test — car il y a peu de changements dans la base ? Ce n'est pas suffisant, même dans de petits projets, des bugs apparaissent après des modifications de la structure ou de la logique. L'automatisation des tests dans le processus CI réduit le facteur humain et prévient les régressions.
Peut-on tester uniquement les procédures "critiques", le reste pouvant être ignoré ? La meilleure approche est de couvrir le maximum de fonctions possible, surtout si à l'avenir le code sera modifié par plusieurs équipes : des calculs non évidents et des cas limites se manifestent souvent dans des branches non standard.
Lors de l'amélioration de la procédure de calcul des réductions, nous avons testé manuellement quelques cas, manquant les principales branches de la logique. En production, les clients ont commencé à recevoir des réductions incorrectes, il a fallu plusieurs jours pour enquêter.
Avantages :
Gain de temps au départ.
Inconvénients :
Pertes dues à la correction manuelle, désagrément lors des améliorations et du refactoring.
Nous avons développé des tests unitaires avec pgTAP pour toutes les UDF et procédures clés, les tests d'intégration sont exécutés via CI à chaque fusion de branche. Les erreurs et régressions sont détectées avant le déploiement.
Avantages :
Stabilité des fonctions, possibilité d'améliorer rapidement la logique métier, bogues minimaux en production.
Inconvénients :
Un investissement en temps est nécessaire pour le démarrage et le maintien de la base de tests.