Illustration de l'article

L’utilisation du BDD dans un logiciel DO-178C

Écrit par MousS'

Introduction

Dans le cadre du projet de recherche CAP 2018, nous avons été amenés à développer le logiciel d’un contrôleur de vol pour drone en conformité avec le standard aéronautique DO-178C. Le processus de développement logiciel mis en place par l’équipe a intégré plusieurs pratiques provenant du BDD : le Behaviour-Driven Development. Cet article constitue un retour d’expérience qui explique les raisons pour lesquelles ces pratiques ont été mises en place et comment elles nous ont aidé à répondre à un certains nombre de problématiques. Nous présentons donc ici la solution vers laquelle l’équipe a finalement aboutie, qui a conciliée l’approche BDD avec la réalisation d’un logiciel soumis à de fortes contraintes de développement. Nous abordons également l’outil XReq supportant le BDD que nous avons développé et utilisé, et les raisons qui nous ont amené à créer et à faire évoluer notre propre outil plutôt que d’en utiliser un déjà existant.

Contexte du projet

Le retour d’expérience abordé dans cet article s’appuie sur le projet de recherche et développement CAP 2018 concernant la réalisation d’un contrôleur de vol pour drone en conformité avec le standard aéronautique DO 178C DAL A (le niveau le plus critique) : PULSAR. Le processus de développement mis en place par l’équipe est un processus itératif incrémental qui intègre plusieurs pratiques issues du BDD. L’objectif de l’équipe lors de la mise en place de ce processus était d’allier :

  • l’efficacité de l’itératif incrémental qui permet une détection des erreurs liées au développement au plus tôt,
  • la rigueur du standard aéronautique ayant pour but de cibler un logiciel fiable et ne contenant pas de défaut à terminaison.

Le standard DO-178C pour un niveau DAL A, requiert de produire plusieurs types de données. La liste qui suit n’est pas exhaustive mais identifie les données auxquelles nous nous intéressons dans cet article et leur périmètre dans le cadre de notre projet :

  • Les HLR (High Level Requirement) : Exigences de haut niveau, il s’agit d’exigences dont le périmètre est celui du logiciel dans son ensemble.
  • Les LLR (Low Level Requirement) : Exigences de bas niveau, il s’agit d’exigences dont le périmètre correspond à celui d’une brique logicielle.
  • Le code
  • Les HLT (High Level Test) : Tests de haut niveau, qui ont pour but de vérifier que le comportement du logiciel est conforme aux HLR (tests boîte noire)
  • Les LLT (Low Level Test) : Tests de bas niveau, qui ont pour but de vérifier que le code est conforme aux LLR (tests boîte blanche)

Dans un processus traditionnel en cycle V (modèle en cascade) ces données sont représentées de la manière suivante :

Cycle en V

Dans ce type de cycle, on va développer les données par types : d’abord toutes les exigences, puis le code et enfin les tests. La détection d’un défaut par les tests (HLT ou LLT) se fait en fin de cycle. Il peut donc s’écouler un temps relativement long entre la production des données et la détection puis la correction d’un problème dans les exigences (HLR ou LLR) ou le code.

Un processus de développement itératif incrémental préconise de développer l’intégralité d’une fonctionnalité, et donc toutes les données qui s’y rapportent, avant de passer à la fonctionnalité suivante. Dans ce type de processus, la durée des cycles dépend de la fonctionnalité à implémenter ce qui la rend beaucoup plus courte que dans un cycle en V. La détection d’un défaut par les tests se fait donc de manière beaucoup plus rapide. On pourrait schématiser de manière simpliste le processus itératif incrémental comme étant une succession de petits cycles en V qui s’enchaînent.

Cycle itératif incrémental

Le BDD : Behaviour-Driven Development

Le Behavior-Driven Development consiste à identifier de manière exhaustive l’ensemble des comportements du logiciel attendus en amont de tout développement. L’expression de ces comportements se fait dans un langage naturel compréhensible par tous de manière à pouvoir impliquer toutes personnes participant au projet, développeurs ou non. Les données ainsi générées servent de scénario de tests permettant de valider que les comportements du logiciel développé à postériori, répond bien aux attentes énoncées. Dans certains cas, ces données peuvent également faire office de spécifications ou d’expressions de besoins, pouvant aller jusqu’à obtenir des exigences exécutables.

L’influence du BDD sur notre processus de développement logiciel

Dans le cadre de notre projet, tirer crédit de l’expression des comportements à la fois en terme d’exigences et de tests semblait compliqué pour pouvoir satisfaire tous les objectifs demandés par le standard aéronautique. C’est pourquoi, nous avons maintenu les exigences d’une part, et utilisé d’autre part les scénario comportementaux en tant que tests.

L’impact lié au BDD sur notre processus de développement itératif incrémental s’est fait sur les deux niveaux d’exigences HLR et LLR, et a eu les répercussions suivantes sur le cycle de production des données :

  • A haut niveau (HLR / HLT) : Pour une fonctionnalité, on exprime l’ensemble des besoins relatifs à la fonctionnalité en spécifiant les HLR. On identifie en parallèle les comportements du logiciel attendus sur un ensemble de jeux de tests exhaustifs exprimés au travers des cas de tests et des procédures de tests qui constituent les HLT. Au cours de cette étape, les incohérences entre ces deux types de données tels que les trous de spécifications ou les ambiguïtés sont corrigés. Une fois ces deux types de données finalisées, elles sont vérifiées. Cette vérification est requise par le standard aéronautique et a pour but de s’assurer que les objectifs DO-178C ont bien été atteints de manière à avoir un niveau de confiance élevé sur le fait que les données ne contiennent plus de défaut. Si ce n’est pas le cas, les données sont corrigées avant de pouvoir passer à l’étape suivante.
  • A bas niveau (LLR / LLT) : Pour chaque brique logicielle impliquée dans la réalisation de la fonctionnalité, on exprime les besoins que doit remplir la brique qui entre en oeuvre dans la fonctionnalité au travers des LLR. On identifie en parallèle les comportements attendus de cette brique logicielle sur un ensemble de jeux de tests exhaustifs exprimés au travers des cas de tests et des procédures de tests qui constituent les LLT. Une fois ces données finalisées, elles sont vérifiées et les défauts sont corrigés avant de pouvoir passer à la phase de codage.

Le processus de développement logiciel mis en place peut donc être représenté de la manière suivante :

Cycle PULSAR

Raisons et motivations liées à l’utilisation du BDD

Lors de la mise en place de notre processus de développement logiciel, l’équipe a été confronté à plusieurs problématiques. Certaines d’entre elles ont pu être résolues au travers de pratiques provenant du BDD.

Une des principales raisons était une volonté de l’équipe d’avoir des données vérifiées ne contenant plus de défaut avant d’avancer dans les étapes du développement. En effet, plus un défaut est détecté tard plus son impact est important car le nombre de données sur lesquelles il se répercute augmente au fil des développements. Cela implique :

  • La vérification des HLR et des HLT avant l’écriture des LLR et des LLT,
  • La vérification des LLR et des LLT avant l’écriture du code.

De cette manière on garantit la maturité des entrants de chaque type de données avant leur production. La vérification des exigences HLR et LLR passe par l’atteinte d’un certain nombre d’objectifs du standard DO-178C, dont certains sont assurés par l’écriture des données de tests correspondantes (HLT et LLT). L’approche BDD est donc plutôt adaptée pour répondre à cette problématique et permet de vérifier les points suivants :

  • La testabilité : si le besoin exprimé dans l’exigence est testable alors on doit être en mesure de pouvoir observer des comportements du logiciel relatif à ce besoin. L’écriture des cas de tests et des procédures de tests (aussi bien HLT que LLT) met en évidence cette testabilité.
  • La précision et la cohérence des exigences : un problème de précision ou de cohérence peut se traduire par une ambiguïté sur le comportement attendu du logiciel. L’écriture des jeux de tests permet de détecter un défaut de cette nature et donc de corriger l’exigence en conséquence pour lever les ambiguïtés.
  • La couverture de l’exigence par les tests : Cet objectif a pour but de vérifier que l’intégralité des besoins exprimés dans les exigences soient couverts par des tests. L’écriture des jeux de tests en parallèle de l’écriture des exigences permet de faire l’analyse de cette couverture au plus tôt et d’identifier rapidement certains problèmes tels qu’un trou de spécification.

Une autre raison importante était une autre volonté de l’équipe de garantir la mise en place de tests cohérents des besoins exprimés dans les exigences (de même granularité). C’est à dire, des tests ne vérifiant que ce qui est exprimé au travers des exigences, quelle que soit la manière dont les exigences sont implémentées. Cela signifie :

  • Des HLT complètements indépendants de ce qui est exprimé dans les LLR,
  • Des LLT complètements indépendants de l’implémentation du code.

En écrivant les scénarios de tests avant toute implémentation comme le préconise le BDD, on répond à notre problématique, car il est difficile de se faire influencer par une donnée si celle-ci n’existe pas. Dans un processus en cycle en V, comme les tests sont produits en fin de cycle de développement, il est possible de se retrouver avec des tests vérifiant à la fois les besoins exprimés dans les exigences et la manière dont celles-ci sont implémentées.

Par exemple, si on considère une exigence spécifiant que sous certaines conditions une LED verte doit s’éclairer pendant 3 secondes, l’opération de contrôle effectuée au moment du test devrait être du type “la LED verte s’éclaire pendant 3 secondes”. Si le code développé s’appuie sur une boucle d’exécution de période 100 millisecondes, et qu’on écrit le test ensuite, on peut facilement être amené à remplacer l’opération de contrôle par “la LED verte s’éclaire pendant 30 cycles”. Par la suite, si l’implémentation du code est modifiée et que la période de la boucle d’exécution est changée, cette deuxième opération de contrôle devra être corrigée alors que le besoin exprimé dans l’exigence n’aura pas changé.

Une autre raison qui nous a amené à aller vers une approche BDD, est la mise en application du TDD (Test Driven Development). En effet, le TDD est une pratique importante pour l’équipe et nous voulions que le processus mis en place nous permette d’aller naturellement vers cette méthode de développement. En produisant les cas de tests avant toute implémentation du code, on amorce naturellement le développement piloté par les tests.

Enfin, la dernière raison qui nous a motivé dans l’approche BDD est la capacité à exprimer des tests sous forme de scénario formalisé dans un langage naturel. En effet, les personnes constituants l’équipe ne sont pas nécessairement des développeurs, tout particulièrement en ce qui concerne l’écriture des exigences. L’écriture de scénarios de tests directement exécutables dans un langage compréhensible par tous ouvre la possibilité à n’importe quel membre de l’équipe de produire les données de tests. Cela évite un effort de traduction des cas de tests dans un format interprétable par le logiciel. De plus, lorsque les exigences et les tests correspondants sont exprimés dans un langage identique il est plus facile de vérifier la cohérence des deux et donc l’atteinte des objectifs mentionnés plus haut.

L’outil XReq

Présentation

L’interprétation et l’exécution des scénarios de tests définis au travers des analyses comportementales se fait grâce à des outils spécifiques qui supportent le BDD et qui permettent de rendre ces scénarios directement exécutables. Dans le cadre du projet, nous en avons créé un adapté à nos contraintes : XReq. Cet outil permet de gérer des scénarios de tests écrit dans une syntaxe inspirée du langage Gherkin. Cette syntaxe s’articule autour de 3 principaux mots clefs :

  • Given : Décrit les mises en condition du logiciel, tels que le positionnement des entrées ou d’actions préalables à l’exécution de la fonctionnalité logicielle à tester.
  • When : Lance les actions permettant la mise en oeuvre de la fonctionnalité qu’on souhaite tester.
  • Then : Permet de vérifier l’état de sortie du logiciel suite aux actions effectués (When) dans les conditions définies au préalable (Given).

Les fonctions remplis par XReq sont :

  • Analyser la syntaxe utilisée dans les scénarios et vérifier sa conformité avec la syntaxe Gherkin.
  • Pour chacune des lignes du scénario, générer un prototype de fonction (si aucun n’a encore été défini) qui devra être complété par l’utilisateur pour assurer l’interface avec le logiciel à tester. Ces fonctions sont appelées step_definition. Un comportement par défaut est défini qui fera échouer le test, rendant le scénario exécutable même si l’utilisateur n’a pas encore interfacé la fonction avec le logiciel à tester.
  • Générer l’exécutable mettant en oeuvre le ou les scénarios de tests (les séquencements des step_definition).

Pourquoi développer un outil spécifique?

Il existe plusieurs outils supportant le BDD aujourd’hui, mais au moment où le projet à démarré le choix était plus restreint et les outils moins évolués. Nous voulions également en créer un, qui serait adapté aux logiciels soumis à de fortes contraintes de développement (aéronautique, médical, etc.). Il y a donc plusieurs raisons et besoins qui nous ont amenés à développer XReq :

  1. La qualification de l’outil : Les outils utilisés dans le développement de logiciels conformes au standard DO-178C peuvent être soumis à une qualification (standard DO-330). Il fallait donc que l’équipe ait la maîtrise sur toutes les données constituant l’outil utilisé pour pouvoir répondre aux contraintes liées à cette qualification.
  2. Le couplage au langage Ada 2012 : En plus de pouvoir gérer des langages de programmation courant comme le langage C, nous avions besoin d’un outil compatible avec l’Ada 2012 qui est le langage de prédilection de l’équipe et celui qui a été choisi pour produire le code source du projet. Ce langage est fortement typé et supporte la programmation par contrat. Ces deux aspects permettent de prévenir l’introduction d’un certains nombre de défauts dans le code, ce qui en fait un langage particulièrement adapté au développement de ce type de logiciels.
  3. L’extension de la syntaxe Gherkin : Les mots clefs “Test Case Template” et “Test Case Data“ ont été ajoutés pour adapter l’outil à la terminologie du standard aéronautique. Ils sont les équivalents de “Scenario Outline” et “Examples”, qui sont égalements supportés par l’outil, et permettent de gérer plusieurs cas de test s’exécutant selon un même scénario. Le scénario est défini au travers du “Test Case Template” qui fait référence à des données exprimées dans un tableau “Test Case Data”. Chaque colonne représentant une donnée, et chaque ligne un jeu de données. Cela permet de produire plusieurs cas de tests pour une même procédure de test.
  4. L’implémentation des mécanismes de Setup et Teardown : Ces mécanismes courant, utilisés dans beaucoup de frameworks de tests ont été également implémentés dans XReq. Ils permettent d’exécuter des opérations en début et fin de tests. Ces opérations sont purement logicielles (le redémarrage du logiciel par exemple) et n’apparaissent pas dans les scénarios. C’est à l’utilisateur de les définir.
  5. La séparation de l’analyse syntaxique de la génération de code : XReq offre la possibilité d’effectuer l’analyse syntaxique et la génération de code (source et exécutable) de manière indépendante. Cette fonctionnalité permet de vérifier que les scénarios écrits sont corrects sans regénérer, et donc sans modifier le moindre fichier de code. Cette fonctionnalité s’avère intéressante tout particulièrement pendant les phases de mises au point des scénarios.

Conclusion

Le processus de développement mis en place a été éprouvé pendant deux ans et demi par l’équipe et a confirmé son efficacité jusqu’à la livraison de la première version de PULSAR. L’aboutissement du projet a conduit à l’émergence de la société Hionos, filliale de Sogilis spécialisée dans le développement de solutions logicielles pour drone. Le processus défini au cours de la réalisation du projet constitue aujourd’hui le socle des développements logiciels effectués par la société, et est retravaillé continuellement dans un soucis récurrent d’amélioration. De son côté, XReq est devenu un outil incontournable dans l’élaboration des données de tests en conformité avec ce processus. Les méthodes de travail et pratiques mis en place au cours de ce projet ont suscité l’intérêt de plusieurs acteurs majeurs du secteur aéronautique et d’institutions gouvernementales avec qui des partenariats se sont engagés. Le processus utilisé au cours de ce projet a pu mettre en évidence l’applicabilité du BDD au domaine aéronautique pour lequel le développement logiciel est fortement contraint, mais doit pouvoir également s’adapter à d’autres secteurs d’activités tels que le médical (IEC 62304) ou au ferroviaire (EN 50128 / IEC 62279).

Exemple de test XReq :

Exemple XReq

XReq en action :

XReq

Illustration de l'article
comments powered by Disqus