# Régression logicielle

Une régression logicielle est un type de bug dans lequel une fonctionnalité qui fonctionnait auparavant cesse de fonctionner. Cela peut se produire après la modification du code source du logiciel, notamment l'ajout de nouvelles fonctionnalités et de corrections de bugs. La régression peut aussi se produire à la suite d'une modification de l'environnement d'exécution du logiciel, comme une mise à jour du système d'exploitation, des dépendances, ou simplement un changement de configuration.
Une régression des performances d'un logiciel est une situation dans laquelle le logiciel fonctionne toujours correctement, mais s'exécute plus lentement ou utilise plus de ressources qu'auparavant.

## Typologie

Différents types de régressions logicielles ont été identifiés dans la pratique, notamment les suivants :
* Locale – une modification introduit un nouveau bug dans le composant modifié.
* Distante – une modification dans une partie du logiciel casse un autre composant.
* Révélation (unmasking) – une modification révèle un bug déjà existant qui n’avait aucun effet auparavant.
Les régressions sont souvent causées par corrections "hotfix" incluses dans des patches. Une méthode pour éviter ce problème consiste à effectuer des tests de régression à l'aide d'un plan de test préalablement conçu. Des tests automatisés et des cas de test bien rédigés peuvent réduire le risque de régression.

## Prévention et détection

Plusieurs techniques ont été proposées pour éviter l'introduction de régressions dans les logiciels à différents stades de développement.

### Avant la publication

Afin d'éviter que l'utilisateur final ne subisse des régressions après la sortie du logiciel, les développeurs exécutent régulièrement des tests de régression après l'introduction de modifications dans le logiciel. Ces tests peuvent inclure des tests unitaires pour détecter les régressions locales ainsi que des tests d'intégration pour détecter les régressions distantes. Les tests de régression exploitent souvent les cas de test existants pour le développement, cependant il est souvent nécessaire de sélectionner un sous-ensemble représentatif, en utilisant la priorisation des cas de tests.
Pour détecter les régressions de performance, des tests de performance sont exécutés régulièrement afin de surveiller les temps de réponse et l'utilisation des ressources (mémoire, bande passante, charge CPU) du logiciel après les modifications. Contrairement aux tests de régression fonctionnelle, les résultats des tests de performance sont sujets à une variance, c'est-à-dire que les résultats peuvent différer d'un test à l'autre en raison de la variation des mesures. Par conséquent, il faut décider si un changement de la mesure est significatif et constitue réellement une régression. Des approches de tests statistiques et de détection de ruptures sont parfois utilisées pour faciliter cette décision.

### Avant le commit

Étant donné que la localisation de la cause d'une régression logicielle peut être coûteuse$^,$ il existe également des méthodes qui tentent d'empêcher la validation des régressions dans le dépôt de code en premier lieu. Par exemple, les hooks Git permettent aux développeurs d'exécuter des scripts de test avant que les modifications de code (commits) ne soient validées ou transmises au dépôt. Des outils d'analyse statique comme lint sont également souvent ajoutés aux hooks de validation pour garantir un style de code cohérent, minimisant ainsi les problèmes stylistiques qui peuvent accentuer le risque de régressions.

## Localisation des régressions

De nombreuses techniques utilisées pour trouver la cause première des bogues logiciels de non-régression peuvent également être utilisées pour déboguer les régressions logicielles, notamment le débogage par point d'arrêt, le débogage par affichage et le découpage (slicing). Les techniques décrites ci-dessous sont souvent utilisées spécifiquement pour trouver la cause des régressions logicielles.

### Régression fonctionnelle

Une technique courante utilisée est la localisation par dichotomie, qui prend en entrée à la fois un commit bogué et un commit précédent fonctionnel, et tente de trouver la cause initiale en effectuant une recherche dichotomique sur les commits intermédiaires. Les systèmes de gestion de versions tels que Git et Mercurial fournissent des moyens intégrés pour effectuer une telle recherche$^,$.
D'autres options incluent l'association directe du résultat d'un test de régression aux modifications de code, la définition de points d'arrêt de divergence, ou une analyse du flot de contrôle, qui identifie les cas de test - y compris ceux qui échouent - pertinents pour un ensemble de modifications de code.

### Régressions de performance

Le profilage mesure les performances et les ressources utilisées par différentes parties d'un programme et fournit des données utiles au débogage des problèmes de performances. Dans le contexte des régressions de performances, les développeurs comparent souvent les piles d'éxécution (ou arbres d'appel) générés par les profileurs à la fois pour la version boguée et pour la version précédemment fonctionnelle. Des mécanismes existent pour automatiser cette comparaison. Les outils développeurs (devtools) des navigateurs offrent généralement la possibilité d'enregistrer ces profils de performances$^,$.
La journalisation (logging) facilite également la localisation des régressions de performances et, à l'instar des arbres d'appels, les développeurs peuvent comparer les journaux de performances de plusieurs versions du même logiciel. Il existe un compromis lors du paramétrage d'un log de performance, car un journal plus détaillé permet d'atteindre une granularité plus fine, tandis qu'un journal moins détaillé réduira la surcharge lors de l'exécution du programme.
D'autres méthodes incluent l'écriture de tests unitaires sensibles aux performances et le classement des sous-systèmes en fonction des écarts des mesures de performances. La recherche dichotomique peut également être réutilisée pour les régressions de performances en définissant une valeur seuil de mesure d'exécution (durée par exemple).

## Voir également

* Érosion des logiciels