Sujets spéciaux

9.3 Sujets spéciaux

Objectifs d'apprentissage

À la fin de cette section, vous serez capable de :

  • Expliquer l'importance des tests en génie logiciel
  • Décrire les types d'outils utilisés par les ingénieurs logiciels
  • Décrire les moyens par lesquels la réutilisation de logiciels est rendue possible
  • Expliquer le rôle de l'éthique en génie logiciel
  • Discuter de l'avenir du génie logiciel

Le rôle d'un ingénieur logiciel est vaste, et les facteurs qui l'impactent sont nombreux. Cependant, quelques domaines méritent d'être approfondis. Ces domaines incluent les tests logiciels, la refactorisation, les patrons de conception, les outils logiciels utilisés dans le développement logiciel, la réutilisation de logiciels, les logiciels libres et open source (FOSS), l'éthique du génie logiciel (software engineering) et les aspects juridiques.

Tests

Le but des tests est de vérifier que le logiciel en développement répond aux exigences définies pour le projet sans erreurs ou effets secondaires non intentionnels. En termes simples, il s'agit de s'assurer que le logiciel fait ce qu'il est censé faire. Grâce à ce processus de confirmation que le logiciel répond aux attentes, tout problème détecté peut être résolu pour garantir l'intégrité du produit.

Les tests devraient avoir lieu à presque toutes les phases d'un projet, chaque phase ayant un objectif de test spécifique. Un axiome des tests est de tester tôt et de tester souvent. Comme on peut le voir dans la Figure 9.17, plus les problèmes sont détectés tôt lors du développement logiciel, moins ils sont coûteux à corriger ou à résoudre. Les problèmes sont généralement découverts à la suite des tests.

Graphique du coût relatif de correction des bogues, basé sur le temps de détection, montrant une augmentation des coûts à partir de 2x aux phases Exigences/architecture, Codage, Tests d'intégration/composants, Tests système/d'acceptation, atteignant 30x en Production/post-publication.
Figure 9.17 Le coût de détection des problèmes augmente tout au long du cycle de vie d'un projet de développement logiciel ; par exemple, plus un bogue est trouvé tard, plus il coûte cher à corriger. (source : Copyright Rice University, OpenStax, sous licence CC BY 4.0)

Niveaux de test

Le logiciel passe par différents niveaux de test pour garantir la qualité :

  • Test unitaire : Les composants logiciels individuels (fonctions ou méthodes) sont testés isolément pour vérifier qu'ils fonctionnent comme prévu.
  • Test d'intégration : Se concentre sur les interfaces entre les composants, s'assurant qu'ils fonctionnent ensemble de manière transparente.
  • Test système : Teste l'ensemble du système logiciel, vérifiant qu'il répond aux exigences globales.

En plus des différents niveaux de test, d'autres approches de test cruciales sont utilisées pour garantir que le logiciel répond aux attentes. Ces approches incluent :

  • Tests d'acceptation : vérifient que le logiciel répond aux attentes et aux exigences définies par le client ou les utilisateurs finaux.
  • Tests d'utilisabilité (Usability) : évaluent la facilité et l'intuitivité d'interaction du logiciel pour les utilisateurs.
  • Tests de stress : évaluent les performances du logiciel sous de lourdes charges ou des conditions défavorables.
  • Tests de performance : évaluent la vitesse, la réactivité et l'extensibilité (scalability) du logiciel dans diverses conditions.
  • Tests de sécurité (security) : identifient et corrigent les vulnérabilités de sécurité pour protéger contre les accès non autorisés ou les violations de données.

Certains tests sont effectués par des développeurs de logiciels, y compris des ingénieurs logiciels qui écrivent du code, mais la majorité des tests sont effectués par des ingénieurs qualité dont l'objectif principal est le test. Les utilisateurs finaux peuvent également participer aux tests d'acceptation ou aux scénarios de tests utilisateurs.

Concepts en pratique

Comment Microsoft teste-t-il Windows avant sa publication ?

Microsoft utilise des millions de testeurs avant de déployer une nouvelle mise à jour de Windows. Ces testeurs font partie du programme Windows Insider et ont accès aux versions préliminaires de Windows. N'importe qui peut s'inscrire à ce programme ; il suffit d'accepter de tester la nouvelle version et de fournir des commentaires à Microsoft. Comme les tests sont effectués sur une version préliminaire du logiciel, les testeurs savent que le logiciel peut être instable et qu'il aura probablement des problèmes. Si vous êtes curieux de connaître les tests – ou si vous souhaitez devenir testeur vous-même – visitez Microsoft Windows Insider ou Apple’s Beta Software Program pour plus d'informations.

Méthodologies de test

Il existe trois méthodologies de test principales, et elles sont classées en fonction des connaissances que le testeur possède (ou doit posséder) pour effectuer les tests. Les trois méthodologies sont :

  • La manière de tester où le testeur connaît le code, afin qu'il puisse vérifier que la structure interne de l'élément testé fonctionne correctement, est appelée test en boîte blanche (white box testing). D'autres noms pour le test en boîte blanche incluent boîte de verre, boîte transparente et test structurel.
  • Les tests basés sur les exigences et la fonctionnalité de ce qui est testé sans avoir besoin de se concentrer sur le code lui-même sont appelés test en boîte noire (black box testing). Le testeur n'a pas besoin d'avoir de connaissances sur le code. D'autres noms pour le test en boîte noire incluent test entrée-sortie, test basé sur les spécifications et test comportemental.
  • L'hybride des tests en boîte blanche et en boîte noire est appelé test boîte grise (gray box testing). La personne qui conçoit le test a une connaissance partielle de la structure du code et comprend la conception prévue du logiciel.

Lors des tests au niveau du système, nous distinguons la vérification et la validation. Tester que la solution logicielle fonctionne sans erreurs est appelé vérification (verification). Dans les organisations dotées de grandes équipes de développement, la vérification est souvent effectuée par une équipe d'assurance qualité (QA). Tester que la solution logicielle est conforme aux exigences et fait ce que l'utilisateur souhaite est appelé validation (validation). La vérification et la validation nécessitent l'exécution du code et peuvent avoir lieu à tous les niveaux de test, la vérification ayant généralement lieu avant la validation.

Les tests sont également distingués par leur objectif en tests fonctionnels et non fonctionnels. Avec les tests fonctionnels, la fonctionnalité est testée. Avec les tests non fonctionnels, des qualités telles que la performance (performance), l'extensibilité et l'utilisabilité sont testées.

Les attributs d'un bon test sont les suivants :

  • Un bon test a une forte probabilité de trouver une erreur ou un problème.
  • Un bon test n'est pas redondant. (Il ne teste pas la même chose qu'un autre test.)
  • Un bon test ne doit être ni trop simple ni trop complexe.

Test unitaire

Un rôle crucial dans le développement logiciel, le processus de test unitaire (unit testing) implique de tester des unités de code individuelles, telles que des méthodes et des fonctions, et il est généralement effectué par les développeurs pendant le développement du logiciel ou lors de mises à jour. Les développeurs de logiciels écrivent des scripts ou du code qui testent la fonctionnalité d'une pièce de code spécifique. Les tests unitaires sont généralement ajoutés à une suite de tests de régression, de sorte qu'ils peuvent être exécutés à nouveau après chaque modification du code source pour vérifier que la modification n'a pas cassé de fonctionnalité existante. Imaginez une fonction qui calcule l'aire d'un rectangle. Un test unitaire vérifierait que la fonction renvoie la bonne aire pour différentes valeurs de largeur et de hauteur.

Le test unitaire offre plusieurs avantages :

  • Détection précoce des bogues : Les tests unitaires aident à identifier les bogues tôt dans le processus de développement, lorsqu'ils sont plus faciles et moins coûteux à corriger.
  • Amélioration de la qualité du code : Le processus d'écriture de tests unitaires encourage les développeurs à écrire un code propre, modulaire et bien documenté.
  • Maintenabilité (Maintainability) : Les tests unitaires servent de documentation vivante, clarifiant le comportement prévu des composants de code et facilitant les modifications futures.

Concepts en pratique

Rester dans sa voie

Dans l'industrie automobile, la plupart des nouvelles voitures incluent désormais un système de détection de voie (LDS). Ce système comprend du code qui vérifie les images vidéo reçues par l'automobile. Le logiciel vérifie si le véhicule franchit l'une des lignes peintes sur la route. Si c'est le cas, il active un système d'avertissement pour en informer le conducteur. Les tests unitaires pour un tel système incluent les éléments suivants :

  • Une ligne appropriée est reconnue.
  • Un avertissement se produit si une ligne semble être franchie.
  • L'avertissement se termine après la période de temps désignée.
  • Lorsque le système LDS est désactivé, l'avertissement n'est pas déclenché.

Les ingénieurs logiciels ainsi que les testeurs effectuent ces tests lorsque le code du système LDS est créé, ainsi qu'à chaque fois que des mises à jour sont apportées au système.

Couverture de code

Un test unitaire approprié améliore la qualité d'un système logiciel et aide à découvrir les bogues tôt. En termes simples, un bogue (bug) logiciel est un problème ou une erreur dans la programmation logicielle. Pour trouver les bogues, il est important de revoir et d'exécuter le code.

La portée d'un test unitaire est généralement mesurée en termes de couverture de code (code coverage), qui est la mesure du pourcentage de code activé ou examiné par le test. Les types courants de couverture de code sont la couverture d'instructions, la couverture de lignes et la couverture de chemins. La mesure du pourcentage d'instructions activées au moins une fois lors de l'exécution de tous les tests est la couverture d'instructions (statement coverage). La mesure du pourcentage de lignes de code source activées qui sont testées est la couverture de lignes (line coverage). La mesure du pourcentage de chemins parcourus dans le code source est la couverture de chemins (path coverage). Comme le montre la Figure 9.18, avec la couverture de chemins, si vous avez deux instructions conditionnelles, l'une après l'autre, il y a généralement quatre chemins à travers ce code :

  1. Les deux conditions sont vraies.
  2. La première condition est vraie et la seconde est fausse.
  3. La première condition est fausse et la seconde est vraie.
  4. Les deux conditions sont fausses.
Illustration du chemin de code de quatre chemins : (i) x et y positifs ; (ii) x positif, y négatif ou nul ; (iii) x négatif ou nul, y positif ; (iv) x et y négatifs ou nuls.
Figure 9.18 Ce diagramme d'activité illustre le fonctionnement de la couverture de chemins avec quatre chemins possibles : (i) x et y positifs, (ii) x positif, y négatif ou nul, (iii) x négatif ou nul, y positif, et (iv) x et y négatifs ou nuls. (source : Copyright Rice University, OpenStax, sous licence CC BY 4.0)

La couverture de chemins est plus exigeante et nécessite généralement plus de tests que la couverture d'instructions ou de lignes, mais les tests sont meilleurs. Vous avez besoin d'un minimum de quatre tests pour atteindre 100 % de couverture de chemins, mais d'un minimum de deux tests pour atteindre le même niveau de couverture d'instructions.

Support pour les tests unitaires

Le test unitaire est si courant que les principaux langages de programmation offrent un certain support pour les tests unitaires automatisés. Un exemple est JUnit, un cadriciel de test unitaire pour le langage de programmation Java, qui est présenté dans la Figure 9.19. JUnit facilite l'écriture et la gestion des tests, et il peut être exécuté rapidement dans certains environnements de développement, généralement en un seul clic. De nombreux autres langages de programmation majeurs ont des cadriciels ou des outils similaires. Il existe également des produits logiciels tiers qui peuvent être utilisés pour aider aux tests unitaires.

Capture d'écran de la fenêtre JUnit avec des flèches vertes pour les tests exécutés.
Figure 9.19 Une fenêtre de test JUnit exemple dans l'environnement de développement intégré (IDE) NetBeans est affichée. Vous pouvez exécuter tous les tests en cliquant sur les flèches vertes. (source : Copyright Rice University, OpenStax, sous licence CC BY 4.0 ; crédit : NetBeans par Sun Microsystems)

Développement piloté par les tests

De nombreuses organisations utilisent le développement piloté par les tests (TDD), qui est un processus où les développeurs écrivent des tests avant d'écrire le code. Cela peut sembler contre-intuitif, mais cela offre plusieurs avantages :

  • Clarifie les exigences : Écrire des tests en premier force les développeurs à réfléchir de manière critique au problème qu'ils essaient de résoudre et au comportement attendu du code. Par exemple, si vous devez écrire du code qui trouve les racines réelles d'une équation quadratique et que vous commencez par des tests unitaires, vous identifierez probablement trois cas qui doivent être résolus séparément : le cas où l'équation a deux racines, le cas où l'équation a une seule racine, et le cas où l'équation n'a pas de racine.
  • Facilite la détection précoce des bogues : Écrire des tests en premier aide à identifier les bogues tôt dans le processus de développement, lorsqu'ils sont plus faciles et moins coûteux à corriger.
  • Entraîne une conception améliorée : L'approche pilotée par les tests peut aider à identifier les cas limites et les scénarios (scenario) qui pourraient être négligés lors du développement traditionnel, conduisant à une conception plus robuste.
  • Entraîne une amélioration de la qualité du code : L'accent mis sur l'écriture d'un code clair et testable conduit à une qualité de code globalement supérieure.

Comme illustré dans la Figure 9.20, dans le développement piloté par les tests, vous écrivez d'abord les tests unitaires. Vous exécutez ensuite les tests, qui devraient échouer car il n'y a pas de fonction entièrement implémentée à tester. Vous exécuterez (et réexécuterez) ensuite les tests au fur et à mesure que vous développez les fonctions. Le développement se poursuit jusqu'à ce que tous les tests unitaires réussissent.

Graphique circulaire : Démarrer : 1. Écrire le test, 2. Le test échoue, 3. Écrire le code, 4. Le test réussit, 5. Refactoriser, 6. Le test réussit, Code terminé.
Figure 9.20 Dans le développement piloté par les tests, le développeur écrit le test avant d'écrire le code. Ainsi, lorsque le test est exécuté pour la première fois, il devrait échouer. (source : Copyright Rice University, OpenStax, sous licence CC BY 4.0)

Voici une description des étapes du processus de développement piloté par les tests :

  1. Écrire un test : Le processus commence par le développeur ou l'équipe de développement qui écrit un test unitaire définissant le comportement attendu d'une fonction ou d'une unité de code spécifique.
  2. Exécuter le test (et le voir échouer) : Exécutez le test. Initialement, le test échouera probablement car la fonction qu'il teste n'existe pas encore ou n'est pas complètement implémentée.
  3. Écrire juste assez de code pour que le test passe : Concentrez-vous sur l'écriture de la quantité minimale de code nécessaire pour que le test passe.
  4. Exécuter le test (et le voir passer) : Lorsque le code passe le test, cela garantit qu'il remplit la fonctionnalité prévue définie dans le test.
  5. Refactoriser (améliorer la structure du code) : Une fois le test passé, prenez du recul et refactorisez le code pour améliorer la lisibilité, la maintenabilité (maintainability) et la structure globale du code sans en modifier la fonctionnalité. Le processus de restructuration du code source sans en modifier la fonctionnalité est appelé refactorisation (refactoring). Nous utilisons généralement la refactorisation pour rendre le code plus lisible. Cela peut être aussi simple que de renommer une variable ou aussi complexe que de décomposer la fonction et de la répartir sur plusieurs modules. Une fois la refactorisation terminée, les tests unitaires doivent être exécutés à nouveau pour s'assurer que le code continue de passer.
  6. Exécuter les tests à nouveau : Après la refactorisation, exécutez tous les tests à nouveau pour vérifier que le code continue de passer et qu'aucun effet secondaire non intentionnel n'a été introduit pendant la refactorisation.

Une fois toutes les étapes terminées, recommencez le cycle : Répétez ce cycle (écrire le test, exécuter le test, écrire le code, refactoriser, exécuter le test) pour chaque unité de fonctionnalité que vous développez.

Test système

Alors que le test unitaire se concentre sur les différentes unités ou parties d'une solution logicielle, le test système (system testing) se concentre sur le produit logiciel complet et entièrement intégré. L'objectif global du test système est de s'assurer que la solution logicielle complète fonctionne globalement comme prévu. Il s'agit généralement d'un style de test en boîte noire qui vise à s'assurer que le logiciel répond à toutes les exigences déterminées et vérifie que tous les scénarios possibles qui pourraient être appliqués à la fonctionnalité du logiciel se déroulent comme prévu. Le test système est généralement effectué par des testeurs plutôt que par les utilisateurs finaux du logiciel, et il implique l'examen des exigences fonctionnelles et des exigences non fonctionnelles (nonfunctional requirement).

Les tests système peuvent être effectués par des testeurs, ou ils peuvent être automatisés. La forme de test système où une personne doit exécuter le système logiciel, fournir toutes les entrées et vérifier manuellement toutes les sorties est appelée test manuel (manual testing). La répétition des tests exige que ces efforts soient répétés par le testeur. La forme de test où un programme ou un code est exécuté qui teste la fonctionnalité d'un système logiciel ou de certaines de ses parties est appelée test automatisé (automated testing). Il permet de répéter les tests sans exiger d'effort répété de la part du testeur. Un exemple d'un tel programme est Selenium. Selenium est une suite d'outils gratuits qui automatise les tests d'applications web. La manière la plus simple d'utiliser Selenium est de le laisser capturer l'interaction entre votre navigateur et l'application web. L'interaction est enregistrée sous forme de script. Vous pouvez ensuite modifier le script, si nécessaire, et le rejouer pour vérifier si l'application web fonctionne toujours. Selenium fournit également des bibliothèques pour de nombreux langages de programmation populaires, y compris Java, C# et Python, qui permettent aux utilisateurs d'écrire des programmes qui effectuent ces tests.

Tests d'acceptation

Également appelé test d'acceptation utilisateur, le test d'acceptation (acceptance testing) est le processus utilisé pour déterminer si la solution logicielle répond aux attentes du client. Ce niveau de test se produit généralement après le test système et est effectué par le client, le commanditaire ou d'autres utilisateurs finaux du logiciel.

Les tests d'acceptation sont des tests formalisés qui peuvent être spécifiés par le client, et ils testent à la fois les exigences fonctionnelles (functional requirement) et non fonctionnelles. Pour tester les exigences fonctionnelles, les tests d'acceptation suivent souvent des scénarios créés lors de l'analyse des exigences. Par exemple, dans un système d'information de bibliothèque, nous pouvons utiliser le scénario « Ajouter un nouveau livre » pour créer un test d'acceptation. Pendant le test d'acceptation, le testeur remplira un formulaire de saisie, le soumettra et vérifiera que le système contient un nouveau livre.

Dans l'industrie automobile, les tests d'acceptation pourraient être effectués par le département qui a demandé les nouvelles fonctionnalités. Ils pourraient également être effectués par des concessionnaires ou des clients qui possèdent ou ont acheté des versions précédentes d'une automobile donnée. Un conducteur pourrait être invité à utiliser les nouvelles fonctionnalités, puis être interrogé pour voir quels problèmes sont survenus.

Tests d'utilisabilité

La méthode de test centrée sur l'utilisateur qui évalue la facilité et l'intuitivité d'utilisation d'un système logiciel est appelée test d'utilisabilité (usability testing). Elle va au-delà de la simple garantie que le logiciel fonctionne correctement et se concentre sur l'interface utilisateur/expérience utilisateur (UI/UX), la partie de la programmation informatique qui concerne la manière dont l'information est présentée à l'utilisateur et comment l'utilisateur peut interagir avec un programme. Les tests d'utilisabilité sont essentiels car un logiciel difficile à utiliser peut frustrer les utilisateurs et entraver son adoption. En identifiant les problèmes d'utilisabilité tôt dans le processus de développement, les développeurs peuvent apporter des améliorations qui conduisent à un produit plus convivial et plus réussi. Les tests d'utilisabilité impliquent généralement le recrutement d'un petit groupe d'utilisateurs représentatifs du public cible. Ces utilisateurs sont invités à effectuer une série de tâches pendant qu'un testeur d'utilisabilité observe leurs actions et enregistre leurs commentaires. Le testeur porte une attention particulière à des domaines tels que :

  • Achèvement des tâches : Les utilisateurs peuvent-ils accomplir les tâches prévues efficacement et sans erreurs ?
  • Facilité d'apprentissage : Est-il facile pour les utilisateurs d'apprendre à utiliser le logiciel ?
  • Satisfaction de l'utilisateur : Les utilisateurs sont-ils satisfaits de l'expérience utilisateur globale ?

Alors que les tests d'acceptation ont généralement lieu vers la fin d'un projet, les tests d'utilisabilité peuvent et devraient avoir lieu beaucoup plus tôt. L'objectif des tests d'utilisabilité est d'améliorer l'expérience utilisateur, et ils mettent généralement l'accent sur les domaines suivants :

  • Interactivité : Les mécanismes d'interaction (par exemple, menus, boutons) sont-ils clairs et cohérents ? Fournissent-ils un retour d'information approprié aux actions de l'utilisateur ?
  • Mise en page : L'information est-elle organisée de manière logique et facile à trouver ? Les utilisateurs peuvent-ils naviguer dans le système de manière intuitive ?
  • Lisibilité : Le texte est-il facile à lire et à comprendre ? Les messages d'erreur sont-ils clairs et exploitables ?
  • Esthétique : L'apparence générale du logiciel est-elle agréable et cohérente ? Les couleurs, les polices et les images contribuent-elles à l'utilisabilité (usability) ?
  • Utilisation de l'affichage : La solution logicielle utilise-t-elle la meilleure taille d'écran et la meilleure résolution d'affichage possibles ?
  • Timing : Les fonctionnalités importantes et autres éléments fonctionnels sont-ils rapidement accessibles ?
  • Support de rétroaction : Une rétroaction utile est-elle fournie aux utilisateurs finaux, et peuvent-ils facilement revenir à leur travail une fois la rétroaction lue ?
  • Personnalisation : L'application s'adresse-t-elle à diverses catégories d'utilisateurs et prend-elle en charge l'inclusion ?
  • Aide : Est-il facile pour les utilisateurs d'accéder à l'aide et à d'autres options de support ?
  • Accessibilité : Le logiciel peut-il être utilisé par des personnes handicapées ? Cela inclut des fonctionnalités telles que les lecteurs d'écran et la navigation au clavier. Notez que les tests d'accessibilité (accessibility testing) sont un sous-ensemble des tests d'utilisabilité qui se concentrent spécifiquement sur les besoins des utilisateurs handicapés. Voici quelques exemples de considérations d'accessibilité :
    • Compatibilité avec les lecteurs d'écran : Les lecteurs d'écran peuvent-ils interpréter le contenu et la fonctionnalité du logiciel avec précision ?
    • Contraste des couleurs : Le logiciel utilise-t-il un contraste de couleurs suffisant pour être utilisable par les personnes malvoyantes ?
    • Navigation au clavier : Toutes les fonctionnalités du logiciel peuvent-elles être accessibles en utilisant uniquement le clavier ?
    • Fonctionnalités de contenu : Le clignotement, le défilement ou la mise à jour automatique du contenu sont-ils évités pour les utilisateurs ayant des difficultés de lecture ?

Pleins feux sur l'industrie

Tests d'utilisabilité et d'acceptation par les constructeurs automobiles

Les tests d'utilisabilité et d'acceptation sont assez différents. Reprenons l'exemple du logiciel des systèmes d'alerte de franchissement de ligne (LDS) intégrés aux automobiles de nos jours. Les tests d'acceptation confirmeraient que le système d'alerte de franchissement de ligne fonctionne comme prévu : L'avertissement s'est-il produit lorsqu'un véhicule a franchi une ligne de voie ? Le logiciel a-t-il reconnu quand le véhicule a quitté la voie ? L'avertissement du système a-t-il commencé et s'est-il terminé dans un délai approprié pour l'utilisateur ? Lorsque le système est désactivé, le logiciel a-t-il ignoré les franchissements de ligne et n'a-t-il pas déclenché les avertissements ?

Avec les tests d'utilisabilité, l'accent est davantage mis sur la question de savoir si le système a répondu aux attentes des utilisateurs qui interagissent avec lui : Le système était-il utilisable ? L'utilisateur a-t-il utilisé la fonctionnalité comme prévu ? L'utilisateur a-t-il réagi de manière appropriée au signal d'avertissement ? Le signal était-il si surprenant qu'il a provoqué un mouvement brusque chez l'utilisateur et un risque d'accident ? L'utilisateur a-t-il simplement désactivé le système parce qu'il le trouvait ennuyeux ? L'objectif des tests d'utilisabilité est de savoir comment la solution est utilisée et si elle a été créée de la manière la plus intuitive.

L'Insurance Institute for Highway Safety a constaté que 49 % des utilisateurs désactivaient le LDS pendant leurs trajets quotidiens. Plus important encore, il a été constaté que 54 % l'activaient s'il utilisait des avertissements tactiles, contre seulement 46 % s'il utilisait une alerte sonore. Du point de vue des tests d'utilisabilité, cela montre qu'il est préférable de se concentrer sur un avertissement tactile plutôt que sonore si l'objectif est d'obtenir la plus grande utilisation. Étant donné qu'il a été démontré que le LDS diminue le risque d'accidents mortels, même avec une faible utilisation, il peut toujours contribuer à sauver des vies.

Outils de génie logiciel

Les développeurs de logiciels utilisent de nombreux outils qui facilitent le développement ; certains d'entre eux sont utilisés quotidiennement tandis que d'autres ne le sont qu'occasionnellement, mais ils jouent tous un rôle important dans le processus de génie logiciel.

Compilateur

Un compilateur est un programme qui convertit le code source en une syntaxe ou un format qu'un ordinateur peut exécuter. Les langages de programmation tels que C et C++ compilent en code machine, qui se compose d'instructions pour un processeur spécifique. D'autres langages de programmation tels que Java compilent en code indépendant de la machine. Par exemple, le code de programme Java est généralement compilé en bytecode Java. Ce code indépendant de la machine est ensuite exécuté sur une machine virtuelle Java.

Débogueur

Un débogueur (debugger) est un programme qui aide à détecter et à corriger les bogues. Il aide généralement à trouver des problèmes dans le code en activant des fonctionnalités telles que la possibilité d'arrêter un programme pendant son exécution afin que les valeurs des variables puissent être affichées et même modifiées. Les débogueurs peuvent également exécuter un programme ligne par ligne pour voir ce que fait chaque ligne de code. Des fonctionnalités plus avancées impliquent l'arrêt d'un programme sur une condition spécifiée et la vérification des interblocages et des fuites de mémoire. La Figure 9.21 montre le débogueur NetBeans arrêté à la ligne 6 d'un programme. Dans la partie inférieure de l'écran, le développeur logiciel peut voir les valeurs des variables actuellement utilisées par le programme.

Capture d'écran d'un outil de débogage de NetBeans.
Figure 9.21 Dans cet outil de débogage de NetBeans, le programme s'est arrêté à la ligne 6, offrant au développeur la possibilité de choisir la prochaine action. La fenêtre inférieure affiche les valeurs des variables actuellement utilisées par le programme. (rendu dans NetBeans par Sun Microsystems ; source : Copyright Rice University, OpenStax, sous licence CC BY 4.0)

Profileur

Un profileur (profiler) est un programme qui effectue une analyse dynamique de programme pouvant être utilisée pour optimiser ou rationaliser le code. Il collecte des données telles que la fréquence et la durée des appels de méthode et les présente au développeur logiciel qui peut les utiliser pour proposer des optimisations de code. Le processus de collecte de données est appelé profilage, et il est généralement effectué lorsque la performance (performance) du système logiciel ne répond pas aux critères spécifiés.

Environnement de développement intégré (IDE)

Les ingénieurs logiciels écrivent généralement du code source dans un IDE tel qu'IntelliJ, Microsoft Visual Studio ou VS Code. Un IDE est une application logicielle qui facilite le développement logiciel en combinant plusieurs outils que les développeurs utilisent, tels qu'un éditeur, un compilateur, un débogueur et un profileur. Certains IDE ne prennent en charge qu'un langage de programmation spécifique, comme IDLE pour Python, et certains prennent en charge plusieurs langages de programmation, comme Microsoft Visual Studio, qui prend en charge C++, C#, Visual Basic et J#.

Les meilleurs IDE offrent des fonctionnalités qui facilitent l'écriture et la maintenance du code source. Ces fonctionnalités peuvent aller de simples fonctionnalités telles que la coloration syntaxique à des fonctionnalités sophistiquées telles que l'analyse statique du code source. La coloration syntaxique affiche différentes parties du code source dans différentes couleurs, ce qui facilite la lecture. La Figure 9.22 montre un IDE mettant en évidence du code Java.

Capture d'écran de code mis en évidence par différentes couleurs dans une fenêtre.
Figure 9.22 La coloration syntaxique est une fonctionnalité des IDE qui aide les développeurs à lire le code. Ici, le code source Java est mis en évidence par l'IDE NetBeans. (rendu dans NetBeans par Sun Microsystems ; source : Copyright Rice University, OpenStax, sous licence CC BY 4.0)

Le coût des IDE peut varier de gratuit à des milliers de dollars. Des IDE tels qu'Eclipse, NetBeans et Microsoft Visual Studio Code sont gratuits. Microsoft Visual Studio et IntelliJ IDEA sont payants, bien qu'il existe des éditions gratuites de chacun. Généralement, le coût d'un IDE est compensé par l'augmentation de productivité qu'un développeur tire de son utilisation.

Système de gestion de versions

Un outil très courant utilisé dans le développement logiciel est un système de gestion de versions (version control system), qui stocke l'historique des modifications du code source et facilite la collaboration de plusieurs développeurs. Le système de gestion de versions le plus populaire aujourd'hui est Git, qui est souvent utilisé avec un hub commun, tel que GitHub ou Bitbucket.

Git stocke le code source du projet écrit par un développeur dans un dépôt qui se trouve généralement sur la machine du développeur. Les développeurs peuvent pousser leur code vers un dépôt de projet à des fins d'intégration. Les principales fonctionnalités de Git sont les suivantes :

  • Il suit les modifications de votre code source.
  • Il permet d'annuler les modifications.
  • Il facilite le développement collaboratif.

GitHub facilite le partage de code entre les développeurs en leur permettant de modifier le code source sur leur propre machine, de valider les modifications dans un dépôt Git sur leur machine, puis de pousser les modifications de leur machine vers GitHub afin que d'autres développeurs puissent y accéder.

De nombreux projets open source sont hébergés sur GitHub, ce qui permet aux gens de télécharger leur code source et de contribuer. La Figure 9.23 montre une page GitHub standard, dans ce cas de la bibliothèque JavaScript appelée le projet jQuery.

Capture d'écran d'une fenêtre GitHub.
Figure 9.23 GitHub est un système de gestion de versions qui facilite le partage de code entre les développeurs. (crédit : GitHub, CC0 1.0)

Système de suivi des bogues

Un autre outil de développement logiciel courant est un système de suivi des bogues (bug tracking system), qui aide au suivi et à la résolution des problèmes logiciels. Le logiciel de suivi des bogues stocke des informations sur les problèmes signalés et leur résolution.

Un flux de travail courant avec le système de suivi des bogues est le suivant : lorsqu'un client ou un testeur signale un bogue, un nouvel enregistrement est créé dans le système de suivi des bogues. Ensuite, le chef de projet ou tout autre membre de l'équipe assigne le bogue à un développeur. Le rapport de bogue doit fournir des instructions sur la façon dont le bogue se manifeste et peut être corrigé afin que le développeur assigné puisse le reproduire et décider comment procéder. Voici une description générale du fonctionnement du suivi des bogues :

  • Si le bogue ne peut pas être reproduit ou s'il ne s'agit pas d'un bogue mais d'une demande de nouvelle fonctionnalité, il sera rejeté.
  • Si le rapport décrit un bogue déjà signalé, il sera marqué comme un doublon.
  • Si la correction est prévue pour une prochaine version, elle sera marquée comme différée.

Lorsque le développeur corrige le bogue, le code doit être retesté pour confirmer que le bogue a bien été résolu. La Figure 9.24 illustre un flux courant de signalement et de suivi des bogues.

Diagramme de suivi des bogues : Nouveau, Assigné, Ouvert (Corrigé, Dupliqué, Rejeté, Différé), Retesté, Vérifié, Fermé. Si rouvert, mène à Assigné.
Figure 9.24 Le système de suivi des problèmes Jira montre un flux de travail courant des systèmes de suivi des bogues. Lorsqu'un bogue est détecté, un nouvel enregistrement est créé. Une fois que le bogue a été assigné et corrigé, et que la correction a été vérifiée, l'enregistrement est fermé. (source : Copyright Rice University, OpenStax, sous licence CC BY 4.0)

La Figure 9.25 montre un outil de suivi des bogues – l'outil de suivi des bogues jQuery – disponible sur GitHub.

Capture d'écran du système de suivi des bogues jQuery sur GitHub.
Figure 9.25 Le système de suivi des bogues jQuery sur GitHub garde une trace du nombre de problèmes en attente (« 86 Open ») et de ceux qui ont été résolus (« 602 Closed »). (crédit : GitHub, CC0 1.0)

Pleins feux sur l'industrie

Bogues non détectés

En janvier 2022, le district scolaire unifié de San Francisco a déployé un nouveau système d'information des employés, qui incluait la paie de plus de 10 000 employés. Malheureusement, l'équipe de développement n'a pas effectué un travail approfondi de test de ce système, et il contenait un certain nombre de bogues lors de son lancement. En conséquence, des centaines d'enseignants et de membres du personnel n'ont pas, même après plusieurs mois, reçu de chèques de paie du système.

Parce que le système était incapable de traiter la paie, des centaines d'employés n'ont pas pu payer leur loyer, leurs factures médicales et d'autres dépenses. Dans ce cas, la livraison d'un système défectueux a nui à des personnes.

Ceci est un exemple où le produit d'un système n'a pas respecté les normes les plus élevées et n'a pas été testé à un niveau qui aurait permis d'éviter un problème qui a directement nui à de nombreux employés qui dépendaient du système. Bien que le directeur de la technologie ait présenté des excuses et assigné 100 % du personnel du projet à la résolution des problèmes, la réalité est – et éthiquement parlant – qu'il aurait fallu allouer plus de temps pour tester le système avant qu'il ne remplace l'ancien système.

Nous pensons généralement à toutes les façons dont la technologie et les systèmes peuvent aider les gens. Il est également important de reconnaître qu'il existe des risques. Les bogues dans les logiciels peuvent avoir un impact significatif sur les personnes affectées. Cela renforce l'importance de tester et de valider un système avant de le publier.

Réutilisation de logiciels

Lors de la construction de logiciels (software), les développeurs utilisent couramment des bibliothèques et des cadriciels, qui se composent de code écrit par d'autres développeurs. Les bibliothèques fournissent généralement des fonctions que vous pouvez appeler dans votre code, et les cadriciels fournissent généralement des squelettes d'applications, qui peuvent appeler votre code. Par exemple, vous pouvez avoir une bibliothèque qui fournit des fonctionnalités de chiffrement et un cadriciel qui facilite le développement d'applications web. Les bibliothèques et les cadriciels sont courants dans le développement logiciel, et il est courant de les combiner. Les bibliothèques peuvent être statiques, liées à votre code au moment de la compilation, ou dynamiques, liées à votre code lors de son exécution. Étant donné que les bibliothèques statiques sont liées au moment de la compilation, vous devez recompiler le programme lorsque la bibliothèque est modifiée. D'autre part, une bibliothèque dynamique est dans un fichier séparé, et elle peut donc évoluer indépendamment de votre code.

Certains langages de programmation, tels que Java, fournissent du code prêt à l'emploi dans le cadre d'une bibliothèque de langage. Ce code peut être invoqué via une interface de programmation d'applications (API) et implique l'implémentation de structures de données communes et d'opérations sur celles-ci. Les applications logicielles peuvent également exploiter des API externes qui permettent aux développeurs d'accéder à des fonctionnalités ou à des données. Par exemple, le service postal des États-Unis (USPS) fournit une API qui peut être utilisée pour obtenir les tarifs d'expédition, suivre les colis, planifier les enlèvements de colis, et plus encore. Il n'est pas nécessaire pour un développeur d'écrire un nouveau code pour cela, mais plutôt de puiser dans l'API USPS.

Il pourrait sembler que nous n'avons plus besoin d'écrire de code car nous pouvons assembler des applications à partir de composants existants, mais, malheureusement, cela ne fonctionne pas de cette façon. L'une des raisons est que nous voulons généralement personnaliser les fonctionnalités, et une autre raison est que même si un composant existant convient parfaitement à un projet, nous ne sommes souvent pas autorisés à l'utiliser pour des raisons légales. Chaque composant est publié sous des conditions légales appelées licences, et si nous voulons l'utiliser, nous devons respecter ces conditions. Par exemple, les composants publiés sous la licence publique générale GNU exigent que le logiciel qui les utilise soit publié sous la même licence, ce qui n'est généralement pas acceptable dans les environnements commerciaux.

La technologie au quotidien

Bibliothèques sur votre ordinateur

La réutilisation de code et l'utilisation de bibliothèques sont extrêmement courantes. En fait, si vous examinez les fichiers sur un ordinateur Microsoft Windows, vous constaterez qu'une pléthore de bibliothèques sont utilisées par le système d'exploitation (operating system) Windows lui-même. Les fichiers qui ont une extension .DLL sont des fichiers de bibliothèque où DLL signifie dynamic-link library.

Sur un ordinateur exécutant Microsoft Windows, effectuez une recherche dans l'Explorateur de fichiers Windows en utilisant "*.dll" pour afficher une liste de bibliothèques de liens dynamiques. Remarquez combien il y en a et les dates de leur dernière mise à jour. De nombreux fichiers du système d'exploitation Windows sont des fichiers DLL qui sont mis à jour à une fréquence différente par rapport au système d'exploitation. Les noms de certains fichiers vous donneront une idée de ce que le code qu'ils contiennent est susceptible de faire. Vous pouvez, bien sûr, tenter une recherche similaire pour un ordinateur fonctionnant sous le système d'exploitation d'Apple.

Motifs

Un motif (pattern) est un concept de haut niveau qui soutient l'idée de réutilisation et fournit des solutions réutilisables à des problèmes souvent rencontrés lors de la construction de logiciels. Les motifs ne sont pas étayés par une théorie ; ils se rapportent à des solutions observées dans la pratique à différents niveaux d'abstraction et qui se sont avérées fructueuses. En général, les motifs sont discutés en termes de leur signification, de leur intention et des avantages de leur utilisation dans de nombreux domaines du génie logiciel. Les motifs sont généralement organisés hiérarchiquement dans des catalogues de motifs à l'aide de modèles de motifs descriptifs. Les langages de motifs peuvent être utilisés pour décrire la compatibilité entre divers motifs et aider à les assembler chaque fois que cela est applicable.

Les ingénieurs logiciels sont susceptibles de rencontrer deux grandes catégories de motifs selon qu'ils conçoivent un modèle d'architecture logicielle (software architecture) ou qu'ils le mappent à une architecture d'implémentation correspondante adaptée à la plateforme ou à l'environnement sur lequel la solution est destinée à être déployée. Les motifs utilisés pour modéliser les architectures logicielles incluent le style architectural, les patrons d'architecture et les patrons de conception, un modèle architectural ou une implémentation de celui-ci.

Comme vous l'avez appris plus tôt dans ce chapitre, un style architectural est une transformation imposée à la conception d'un système entier. L'intention est d'établir une structure pour tous les composants d'un système en développement. Des exemples de styles architecturaux pour les systèmes distribués incluent l'architecture de gestion d'objets (OMA), l'architecture orientée services (SOA), l'architecture multicouche et l'architecture décentralisée pair-à-pair. Notez que plusieurs styles architecturaux peuvent être combinés pour créer un style architectural hybride. Un patron d'architecture fait partie d'une catégorie de motifs qui se concentrent sur l'architecture logicielle. Ils ont tendance à être plus abstraits et axés sur l'amélioration de problèmes tels que le déploiement (deployment), la disponibilité (availability), la maintenabilité (maintainability), la performance (performance), l'extensibilité (scalability), la sécurité (security) et les tests. Un patron de conception (design pattern) est une solution réutilisable à un problème de conception que les ingénieurs logiciels rencontrent de manière répétée lors de l'architecture et de la conception de systèmes logiciels. Par exemple, le patron de conception Singleton suggère comment restreindre le nombre d'instances de classe à une seule. Ce problème se produit couramment dans les systèmes logiciels chaque fois qu'une classe représente une chose ou un concept qui a une seule instance. Un patron de conception plus complexe est Builder, qui permet à un ingénieur logiciel de créer un objet par étapes et est généralement utilisé lorsque la création est un processus complexe.

De plus, un patron de conception impose une transformation à la conception d'une architecture d'un patron d'architecture donné. Par conséquent, les patrons d'architecture et de conception peuvent être utilisés conjointement avec un style architectural pour façonner la structure globale d'un système. Par exemple, le modèle-vue-contrôleur (MVC) est un patron d'architecture typique qui est utilisé pour concevoir l'architecture logicielle d'un système multicouche. Si le système multicouche fournit un tableau de bord, cette fonctionnalité tirera parti d'un patron de conception Singleton pour éviter toute confusion et garantir l'existence d'un seul tableau de bord.

De nombreux patrons de conception sont décrits dans la littérature sur le développement logiciel. Le premier livre collectant des patrons de conception, Design Patterns de Gamma, Helm, Johnson et Vlissides, a été écrit en 1995 et est toujours disponible aujourd'hui. D'autres motifs ont été identifiés et partagés depuis lors. Vous pouvez trouver de nombreuses listes de patrons de conception couramment utilisés en ligne, comme celle disponible sur le site web tutorialspoint.

Chaque patron de conception apporte une solution à un problème dans un contexte particulier. Ainsi, les patrons de conception ne sont pas des solutions universelles car ils s'accompagnent presque toujours d'inconvénients, et c'est le contexte qui détermine si les avantages l'emportent sur les inconvénients, c'est pourquoi il est important non seulement de connaître les patrons de conception, mais aussi de comprendre leurs avantages et leurs inconvénients afin de pouvoir évaluer leurs bénéfices et leurs inconvénients dans un contexte spécifique. Les patrons de conception peuvent être appliqués lors de la conception d'un système logiciel, ou ils peuvent être introduits plus tard dans le processus de refactorisation. Ils sont rarement appliqués sous leur forme pure telle qu'ils sont décrits dans la littérature. La pratique la plus courante est de les adapter au contexte dans lequel ils seront utilisés. Il est également courant que la base de code d'un système logiciel puisse implémenter plusieurs patrons de conception, ce qui contribue à la qualité supérieure du système.

Refactorisation

Comme cela a été dit précédemment, la refactorisation est le processus de restructuration du code source sans en modifier la fonctionnalité. Elle n'est pas spécifique à la réutilisation, bien que la refactorisation puisse impliquer la réutilisation. Typiquement, la refactorisation consiste à effectuer une série de changements élémentaires appelés micro-refactorisations, tels que :

  • Renommer un attribut, ce qui change le nom d'un attribut pour un nouveau qui correspond mieux à son objectif.
  • Renommer une méthode, ce qui change le nom d'une méthode pour un nouveau qui correspond mieux à son objectif.
  • Extraire une classe, ce qui déplace une partie d'une classe existante dans une nouvelle classe.
  • Extraire une méthode, ce qui déplace un fragment de code dans une nouvelle méthode.
  • Inline une méthode, ce qui remplace un appel de méthode par son corps. Ceci n'est généralement utilisé que pour des méthodes très courtes.
  • Déplacer une méthode, ce qui déplace une méthode vers une classe plus appropriée.
  • Déplacer un champ, ce qui déplace un champ vers une classe plus appropriée.
  • Supprimer le code mort, ce qui supprime le code qui ne s'exécute jamais.
  • Remplacer un littéral par une constante symbolique, ce qui remplace une valeur magique par une constante nommée.
  • Modifier les paramètres de méthode, ce qui ajoute ou supprime des paramètres de méthode.
  • Substituer un algorithme, ce qui remplace un algorithme par un autre. Ceci est généralement fait pour améliorer les performances du système logiciel.

Vous pouvez appliquer ces micro-refactorisations manuellement, mais il est plus courant de les effectuer dans un IDE. Les IDE modernes offrent un support pour certaines refactorisations, et vous pouvez souvent appliquer une refactorisation sélectionnée en activant un élément de menu approprié, comme le montre la Figure 9.26.

Capture d'écran de l'IDE NetBeans. La fenêtre ouverte met en évidence Refactoriser, qui ouvre une fenêtre avec Renommer mis en évidence.
Figure 9.26 Dans l'IDE NetBeans, l'action de renommer une méthode se trouve sous l'élément de menu Refactoriser. (rendu dans NetBeans par Sun Microsystems ; source : Copyright Rice University, OpenStax, sous licence CC BY 4.0)

Pour revenir au concept de réutilisation, l'un des avantages de la refactorisation est que les fonctions, les classes et d'autres blocs de code peuvent être extraits d'autres parties du code. Ceux-ci peuvent ensuite être réutilisés en les plaçant dans des bibliothèques, en les incorporant dans un cadriciel pour être utilisés par d'autres développeurs, ou en construisant une interface pour y accéder.

Licences logicielles

Lorsque les ingénieurs logiciels conçoivent et développent des logiciels pour une organisation, ce logiciel et tout son code appartiennent généralement à l'organisation. Cela signifie que le code source et la fonctionnalité ne peuvent pas être utilisés par d'autres sans autorisation. Cette permission est généralement contrôlée par une licence logicielle (software license). Le type de licence peut être déterminé par ceux qui ont créé le logiciel ou commandé sa création. Deux des catégories les plus courantes pour définir la réutilisation de logiciels sont le code source fermé et le code source ouvert. Le logiciel propriétaire, ou à code source fermé (closed-source), est une forme de licence qui interdit l'accès au code source sous-jacent. Ce type de logiciel est généralement développé pour des organisations ou comme logiciel à vendre. Il peut être utilisé pour protéger un logiciel qui pourrait contenir des informations propriétaires ou de la propriété intellectuelle dans le code. Le logiciel libre et open source (FOSS), ou à code source ouvert (open-source), est une forme de licence logicielle qui donne accès au code sous-jacent et permet généralement de réutiliser et de modifier le code.

Il est important de lire les termes de la licence de tout code logiciel utilisé. Il est également important de s'assurer que, si le logiciel doit être partagé, il est clair quelle licence sera appliquée à l'utilisation du logiciel et à son code. Si aucune licence n'est fournie avec le code, le code est généralement protégé par les règles du droit d'auteur.

Logiciel libre et open source (FOSS)

Le logiciel libre (parfois appelé logiciel libre) est un logiciel distribué selon des termes qui offrent aux utilisateurs les quatre libertés suivantes :

  1. la liberté d'exécuter le logiciel pour n'importe quel but
  2. la liberté d'étudier le fonctionnement du logiciel et de le modifier
  3. la liberté de redistribuer le logiciel
  4. la liberté d'améliorer le logiciel et de publier les améliorations au public

La liberté d'étudier le fonctionnement du logiciel et de le modifier, ainsi que la liberté d'améliorer le logiciel, peuvent difficilement être satisfaites sans le code source, et ces libertés impliquent donc plus ou moins que le code source du logiciel doit être disponible.

Libre ici fait référence à la liberté, pas au prix (il peut vous être demandé de payer pour un logiciel libre). Le logiciel distribué gratuitement est appelé freeware, et il est rarement livré avec le code source. Le logiciel open source est un logiciel distribué sous une licence qui accorde aux utilisateurs le droit d'utiliser, d'étudier, de modifier et de distribuer le logiciel et son code source. Cela ne signifie pas que le logiciel doit être gratuit, bien que dans de nombreux cas ce soit le cas. Aujourd'hui, il est courant que les projets open source fournissent leur code source via un dépôt public sur Internet qui permet à quiconque de contribuer.

Les avantages du FOSS sont les suivants :

  • Qualité et fiabilité améliorées : L'implication de la communauté dans les projets open source peut conduire à un logiciel de meilleure qualité et plus fiable grâce à un plus grand nombre d'utilisateurs et de développeurs identifiant et corrigeant les bogues.
  • Coûts de développement réduits : Les logiciels open source peuvent bénéficier des contributions de la communauté, réduisant les coûts de développement pour les entreprises et les organisations.
  • Innovation : L'ouverture et la collaboration peuvent accélérer l'innovation car les développeurs peuvent s'appuyer sur le code open source existant.

Certains projets développés en tant que logiciels libres et/ou open source peuvent être classés comme suit :

  • Systèmes d'exploitation (Operating system)
    • Linux : Un système d'exploitation open source, distribué sous forme de « distributions ». Les distributions sont désignées par des noms tels que Debian, Fedora, Ubuntu, RedHat et SUSE, et elles peuvent être commerciales (payantes) ou communautaires (gratuites). Le noyau Linux est sous licence GNU General Public License, version 2, ce qui en fait un logiciel libre et open source.
    • Android : Un système d'exploitation libre et open source développé par un consortium parrainé par Google. Il est basé sur le noyau Linux et d'autres logiciels open source, et il vise principalement les appareils mobiles à écran tactile, tels que les smartphones et les tablettes. Android est le système d'exploitation le plus courant (pas seulement sur les téléphones mobiles).
  • Outils de développement
    • NetBeans IDE : Un IDE open source qui a commencé comme un projet étudiant avec l'objectif de créer un IDE pour le langage de programmation Java. Il appartient maintenant à l'Apache Software Foundation et prend également en charge d'autres langages de programmation, tels que PHP, C, C++ et JavaScript.
    • Eclipse IDE : Un environnement de développement intégré open source qui a commencé chez IBM et est maintenant géré par la Fondation Eclipse.
    • GNU Compiler Collection (GCC) : Un compilateur libre et open source (ou plus précisément une suite de compilateurs) qui prend en charge divers langages de programmation, plateformes matérielles et systèmes d'exploitation. C'est le compilateur standard inclus dans de nombreuses distributions Linux.
  • Navigateurs web
    • Google Chrome : Un navigateur web gratuit développé par Google. Bien que la majeure partie du code source de Google Chrome provienne de logiciels libres et open source, il est sous licence freeware propriétaire. Il est disponible sur Windows, Linux, Android, macOS et iOS.
    • Mozilla Firefox : Un navigateur web libre et open source développé par la Fondation Mozilla. Il est disponible sur Windows, Linux, macOS et Android.
  • Langages de programmation
    • OpenJDK : Une implémentation libre et open source de la plateforme Java, Standard Edition. De nombreuses autres distributions de la plateforme Java, telles qu'Amazon Corretto, sont basées sur OpenJDK.
    • C# : Un langage de programmation moderne multiplateforme initialement développé par Microsoft. Le langage C# et le compilateur C# actuel (à partir de 2014) de Microsoft sont open source.
    • Python : Un langage de programmation moderne entièrement open source, librement utilisable et distribuable, même à des fins commerciales, ce qui le rend extrêmement populaire auprès des entreprises du monde entier.
  • Serveurs d'applications
    • Payara Server : Un serveur d'applications open source, avec des options de support payantes.

Bien que certains logiciels open source soient entièrement gratuits, les projets FOSS peuvent avoir des modèles d'affaires réussis. Il peut sembler que le développement de logiciels open source n'apporte aucun avantage aux éditeurs de logiciels, mais l'implication de la communauté conduit à une meilleure qualité et une plus grande fiabilité du logiciel, ainsi qu'à une réduction des coûts de développement. De nombreuses entreprises de logiciels qui sont passées au développement open source ont modifié adéquatement leur modèle d'affaires et, au lieu de vendre des logiciels, elles facturent au client la fourniture de services supplémentaires. Par exemple, Payara Server est un serveur d'applications open source pour les applications Jakarta Enterprise Edition. Le serveur est gratuit, mais les entreprises qui utilisent Payara Server pour des applications critiques peuvent payer pour un support, ce qui leur permet de consulter une équipe d'ingénieurs logiciels à tout moment. De plus, elles reçoivent des versions mensuelles avec des corrections de bogues et des alertes de sécurité (security). De nombreuses entreprises qui adoptent le développement open source se concentrent sur la fourniture de services à valeur ajout, tels que le support technique, la formation ou le développement personnalisé, autour du produit open source de base.

Il est important pour les entreprises et les développeurs de prêter attention aux points suivants :

  • Considérations relatives aux licences logicielles : Comprendre les licences logicielles est crucial pour les utilisateurs et les développeurs de logiciels. Bien que de nombreuses personnes acceptent les contrats de licence utilisateur final (CLUF) lors de l'installation de logiciels sur leurs ordinateurs personnels et leurs appareils, il est important que les ingénieurs logiciels comprennent qu'il s'agit d'accords juridiques. En tant que tels, lors de l'utilisation de logiciels pour créer des solutions, il est important de comprendre ce que la licence autorise.
  • Utilisation de logiciels open source : Les développeurs de logiciels doivent être conscients des termes de licence associés à tout FOSS qu'ils utilisent pour garantir la conformité.
  • Distribution de logiciels : De plus, lors de la distribution de logiciels, il est important de s'assurer qu'une licence incluse définit comment vous ou l'organisation propriétaire du logiciel souhaitez qu'il soit utilisé et protégé. Choisissez une licence qui correspond aux objectifs de votre projet et à la manière dont vous souhaitez que votre logiciel soit utilisé et distribué.

Le FOSS est un modèle de développement puissant qui favorise la collaboration, l'innovation et la création de logiciels rentables. Bien que les considérations de sécurité doivent également être prises en compte, les logiciels open source jouent un rôle vital dans l'industrie technologique.

Éthique et aspects juridiques du génie logiciel

Les ingénieurs logiciels passent souvent beaucoup de temps à créer du code et des solutions pour résoudre des problèmes. Bien qu'ils soient ceux qui écrivent le code, cela ne signifie pas que le code ou les connaissances qu'ils ont acquises en écrivant le code leur appartiennent.

Par exemple, si un ingénieur logiciel travaillait pour un constructeur automobile, il pourrait être chargé de concevoir et de créer un produit futuriste qui détecte le mouvement des yeux d'un conducteur pour vérifier qu'il regarde vers l'avant pendant la conduite. Le logiciel pourrait présenter une alerte si l'attention du conducteur s'éloigne de la route pendant une période donnée. Généralement, il serait considéré comme contraire à l'éthique pour ce même développeur d'utiliser ce qu'il a appris en travaillant pour le constructeur automobile pour développer son propre produit logiciel qui utilise le même code pour détecter le mouvement des yeux. Bien que l'ingénieur logiciel ait pu écrire le code, il l'a écrit pour le constructeur automobile, il serait donc contraire à l'éthique d'utiliser le même code dans un produit indépendant sans l'autorisation du constructeur automobile.

Les ingénieurs logiciels doivent respecter un code d'éthique qui guide le travail qu'ils effectuent et les produits qu'ils produisent. Au niveau personnel, l'éthique pour les ingénieurs logiciels implique les principes directeurs suivants :

  • Ne pas utiliser les données ou le code d'autres personnes à des fins lucratives.
  • Ne pas exploiter les informations propriétaires d'autres personnes dans le cadre d'un projet commercial.
  • Ne pas utiliser ou cacher l'utilisation des données ou des programmes d'autres personnes dans le cadre de vos propres projets.
  • Ne pas violer la confidentialité d'autrui.
  • Ne pas obtenir un accès illégal à un système à des fins lucratives.
  • Ne pas créer ou propager de virus informatiques ou de vers.
  • Ne pas créer ou utiliser de programmes qui promeuvent la discrimination ou le harcèlement de quelque nature que ce soit.

L'Association for Computing Machinery (ACM) et l'IEEE-CS established the Committee on Professional Ethics (COPE) ont publié un Code de déontologie et de pratique professionnelle en génie logiciel (Software Engineering Code of Ethics and Professional Practice). Ce code d'éthique stipule que les ingénieurs logiciels doivent s'engager à faire de l'analyse, de la spécification, de la conception, du développement, des tests et de la maintenance (maintenance) de logiciels une profession bénéfique et respectée, conformément à leur engagement envers la santé, la sécurité et le bien-être du public. Le Code définit ensuite huit principes que tous les ingénieurs logiciels sont tenus de suivre pour éventuellement éviter des conséquences juridiques :

  1. La responsabilité doit être assumée pour le travail effectué.
  2. Les actions doivent être dans le meilleur intérêt d'un client ou d'un employeur.
  3. Les produits et les mises à jour doivent être créés d'une manière qui respecte les normes professionnelles les plus élevées.
  4. L'intégrité doit être appliquée dans les actions entreprises.
  5. Une approche éthique de la gestion du développement et des mises à jour logicielles doit être maintenue et promue.
  6. L'intégrité de ce que signifie être un ingénieur logiciel doit être maintenue.
  7. Les ingénieurs logiciels doivent soutenir leurs pairs et collègues de manière équitable.
  8. L'apprentissage doit être un effort continu pour l'amélioration de la propre profession de l'ingénieur logiciel.

Réfléchissez-y

Application des concepts d'éthique

En tant qu'ingénieur logiciel, vous ferez face à l'évolution constante de la technologie et au besoin constant de comprendre une variété de scénarios commerciaux pour construire des solutions. Il est clair que l'on ne peut pas s'attendre à ce que vous sachiez tout.

Considérons deux scénarios hypothétiques : Dans le premier, supposons qu'un développeur, confronté à une tâche qu'il ne savait pas comment accomplir, a passé des jours à éviter le reste de l'équipe pendant qu'il faisait des recherches et lisait des livres pour essayer d'apprendre la nouvelle technologie. Il n'a dit à personne qu'il ne connaissait pas la technologie.

Dans le second, imaginez qu'un développeur était confronté au problème de devoir coder un widget pour que l'équipe l'utilise. Le problème a été partagé en ligne sur des forums de développeurs tels que StackOverflow et CodeProject et le développeur a demandé à d'autres de fournir du code pour faire ce que le widget était censé faire. Bien que le développeur n'ait pas compris ce que le code faisait, il a copié ce qui lui avait été donné et l'a présenté à l'équipe comme le sien sans dire d'où il venait.

Dans les deux situations, comment les concepts d'éthique se sont-ils appliqués ?

L'avenir du génie logiciel

Les gens ont des opinions très différentes sur ce que sera le génie logiciel dans vingt ou trente ans. Un jour, une découverte ou une invention révolutionnaire pourrait changer notre société de manière radicale – ou non. Personne ne peut prédire quand ou quelles percées scientifiques spécifiques se produiront, et les découvertes peuvent façonner notre avenir de manières difficiles à imaginer aujourd'hui. Cependant, sur la base de notre expérience des vingt dernières années ou plus, nous pouvons faire quelques prédictions sur l'état du génie logiciel en 2040.

Évolution de la programmation

Nous pouvons, par exemple, prédire que l'évolution des langages de programmation actuels sera dictée par les changements matériels et que les outils utilisés par les développeurs s'amélioreront. Mais avec l'évolution de l'IA et de l'apprentissage automatique, les développeurs de logiciels deviendront-ils obsolètes ? Dans les circonstances actuelles, la réponse est non. L'IA peut, cependant, aider à certaines tâches de développeur, telles que les tests, le débogage et la refactorisation. Bien que nous puissions nous attendre à ce que des robots intelligents soient membres des équipes de développement, ils ne remplaceront pas entièrement les développeurs de logiciels.

L'avenir du développement logiciel

Discutons maintenant de trois questions sur l'avenir du développement logiciel :

  1. Quels langages de programmation utiliserons-nous ? Nous pouvons nous attendre à ce que les langages de programmation actuels évoluent, voire deviennent obsolètes, d'ici 2040, mais il est difficile d'imaginer que des langages comme Java, Python, C, C# et C++ disparaissent entièrement car il y a tellement de code écrit dans ces langages de programmation.
  2. Pouvons-nous arriver au point où tous les logiciels sont écrits et où nous n'avons plus besoin de développement logiciel ? Absolument pas dans un avenir proche. Nous ne sommes ni à la fin ni au milieu d'une révolution technologique – nous en sommes au début. L'importance des logiciels dans la société va croître, et les systèmes logiciels deviendront plus sophistiqués. Par exemple, avec l'Internet des objets (IoT), nous connecterons des milliers et des milliers d'appareils intelligents à Internet, et ils auront tous besoin de logiciels.
  3. Est-il judicieux d'apprendre la programmation aujourd'hui ? Absolument. Avec l'utilisation accrue d'appareils intelligents et connectés, l'intégration de la technologie est de plus en plus répandue dans presque toutes les facettes de la vie, et la technologie continue d'offrir un avantage aux entreprises pour fonctionner plus rapidement, mieux et plus efficacement que la concurrence. Compte tenu de cela, le développement logiciel deviendra plus important.

De plus, l'électronique (y compris le matériel informatique) et la manière dont la programmation informatique est appliquée continuent d'évoluer. Au début des années 2000, l'informatique mobile et la connectivité Wi-Fi ont changé la façon dont l'informatique se déroulait. Au cours de la dernière décennie, la connectivité a continué d'évoluer, et de nombreux nouveaux types d'appareils intelligents ont nécessité un nouveau code. Au cours des prochaines décennies, les changements au cœur des ordinateurs, tels que la création de coprocesseurs quantiques, ont le potentiel de révolutionner à nouveau le développement logiciel.

En 2021, le Bureau of Labor Statistics des États-Unis a prédit qu'au cours de la prochaine décennie, le nombre d'emplois en génie logiciel aux États-Unis augmenterait de 25 %8. Cela est dû, en partie, au fait que la technologie continue d'infiltrer notre vie quotidienne. Par exemple, de nombreuses chaînes d'épiceries mettent à jour leurs chariots de courses pour inclure des capteurs qui enregistrent tous les articles que vous ajoutez au panier. À mesure que cette automatisation se poursuit et s'étend, elle nécessitera un grand nombre de développeurs de logiciels. La poussée actuelle vers les véhicules autonomes sera réalisée grâce à des capteurs et à un grand nombre d'ingénieurs logiciels créant des centaines de milliers de lignes de code. Il faudra des années de tests, de débogage et de refactorisation avant que les véhicules autonomes ne soient aussi communément acceptés qu'un téléphone portable l'est aujourd'hui. Ce sont les ingénieurs logiciels qui rendront cela possible.