web-dev-qa-db-fra.com

Trouvez le code inutilisé dans une application Rails

Comment savoir quel code est et n'est pas exécuté en production ?

L'application est bien testée, mais il y a beaucoup de tests qui testent le code inutilisé. Par conséquent, ils obtiennent une couverture lors de l'exécution des tests ... J'aimerais refactoriser et nettoyer ce gâchis, cela me fait perdre mon temps. J'ai beaucoup d'emplois de fond, c'est pourquoi j'aimerais que l'environnement de production me guide. En cours d'exécution sur heroku, je peux faire tourner des dynos pour compenser tout impact sur les performances du profileur.

Question connexe Comment puis-je trouver des méthodes inutilisées dans une application Ruby? pas utile.

Bonus: mesures pour montrer à quelle fréquence une ligne de code est exécutée. Je ne sais pas pourquoi je le veux, mais je le fais! :)

65
oma

Dans des circonstances normales, l'approche serait d'utiliser vos données de test pour la couverture du code, mais comme vous dites que certaines parties de votre code sont testées mais ne sont pas utilisées sur l'application de production, vous pouvez faire quelque chose de légèrement différent.

Juste pour plus de clarté: Ne faites pas confiance aux outils automatiques. Ils ne vous montreront que les résultats pour les choses que vous testez activement, rien de plus.

Avec l'avertissement derrière nous, je vous propose d'utiliser un outil de couverture de code (comme rcov ou simplecov pour Ruby 1.9) sur votre application de production et mesurer la des chemins de code réellement utilisés par vos utilisateurs. Bien que ces outils aient été initialement conçus pour mesurer la couverture des tests, vous pouvez également les utiliser pour la couverture de la production

En supposant que pendant la période de test, tous les chemins de code pertinents sont visités, vous pouvez supprimer le reste. Malheureusement, cette hypothèse ne tiendra probablement pas pleinement. Vous devrez donc toujours appliquer vos connaissances de l'application et de son fonctionnement interne lors du retrait de pièces. Ceci est encore plus important lors de la suppression de parties déclaratives (comme les références de modèle) car celles-ci ne sont souvent pas exécutées directement mais uniquement utilisées pour configurer d'autres parties du système.

Une autre approche qui pourrait être combinée avec ce qui précède est d'essayer de refaçonner votre application en fonctionnalités distinctes que vous pouvez activer et désactiver. Ensuite, vous pouvez désactiver les fonctionnalités suspectées d'être inutilisées et vérifier si personne ne se plaint :)

Et pour finir: vous ne trouverez pas d'outil magique pour effectuer votre analyse complète. En effet, aucun outil ne peut savoir si un certain morceau de code est utilisé par des utilisateurs réels ou non. La seule chose que les outils peuvent faire est de créer (plus ou moins) des graphiques d'accessibilité statique, vous indiquant si votre code est appelé d'une manière ou d'une autre à partir d'un certain point. Avec un langage dynamique comme Ruby même cela est assez difficile à réaliser, car l'analyse statique n'apporte pas beaucoup d'informations sur la méta-programmation ou les appels dynamiques qui sont largement utilisés dans un Rails le contexte. Certains outils exécutent donc votre code ou tentent d'obtenir des informations sur la couverture des tests. Mais il n'y a certainement aucun sort magique.

Donc, étant donné la grande complexité interne (la plupart du temps cachée) d'une application Rails, vous ne vous déplacerez pas pour faire la plupart de l'analyse à la main. Le meilleur conseil serait probablement d'essayer de modulariser votre application et de désactiver certains modules pour tester s'ils ne sont pas utilisés. Cela peut être pris en charge par des tests d'intégration appropriés.

34
Holger Just

Vous pouvez peut-être essayer d'utiliser Rails_best_practices pour vérifier les méthodes et la classe inutilisées.

Le voici dans le github: https://github.com/railsbp/Rails_best_practices .

Mettez 'gem "Rails_best_practices"' dans votre Gemfile puis exécutez Rails_best_practices . pour générer le fichier de configuration

21
big-circle

Découvrez le coverband gem, il fait exactement ce que vous cherchez.

15
Dmitry Polushkin

J'ai eu le même problème et après avoir exploré certaines alternatives, j'ai réalisé que j'avais toutes les informations disponibles dès la sortie de la boîte - les fichiers journaux. Notre format de journal est le suivant

Dec 18 03:10:41 ip-xx-xx-xx-xx appname-p[7776]:   Processing by MyController#show as HTML

J'ai donc créé un script simple pour analyser ces informations

zfgrep Processing production.log*.gz |awk '{print $8}' > ~/tmp/action

sort  ~/tmp/action | uniq -c |sort -g -r > ~/tmp/histogram

Ce qui a produit des résultats sur la fréquence d'accès à une action de contrôleur # donnée.

4394886 MyController#index
3237203 MyController#show
1644765 MyController#edit

L'étape suivante consiste à le comparer à la liste de toutes les paires d'actions de contrôleur # dans l'application (en utilisant la sortie des routes de râteau ou peut faire le même script pour la suite de tests)

13
katzmopolitan

Vous avez déjà l'idée de marquer les méthodes suspectes comme privées (ce qui cassera peut-être votre application).

Une petite variation que j'ai faite dans le passé: Ajoutez un petit code pièce à toutes les méthodes suspectes pour le journaliser. Dans mon cas, c'était un popup utilisateur "Vous avez appelé une fonction obsolète - si vous en avez vraiment besoin, veuillez contacter le service informatique". Après un an, nous avions un bon aperçu de ce qui était vraiment utilisé (c'était une application métier et là où les fonctions n'étaient nécessaires qu'une fois par an).

Dans votre cas, vous ne devez enregistrer que l'utilisation. Tout ce qui n'est pas enregistré après une période raisonnable n'est pas utilisé.

4
knut

Je ne suis pas très familier avec Ruby et RoR, mais ce que je suggère une supposition folle:

  • ajouter :after_filter méthode qui enregistre le nom de la méthode appelée précédente (récupérez-la de la pile d'appels) dans un fichier
  • déployer cela en production
  • attendre un moment
  • supprimez toutes les méthodes qui ne sont pas dans le journal.

p.s. probablement une solution avec Alt + F7 dans NetBeans ou RubyMine est bien meilleure :)

4
alex.b

Métaprogrammation

Objet # method_missing

passer outre Object#method_missing. À l'intérieur, connectez l'appel Classe et méthode, de manière asynchrone, à un magasin de données. Appelez ensuite manuellement la méthode d'origine avec les arguments appropriés, en fonction des arguments passés à method_missing.

Arborescence d'objets

Comparez ensuite les données du magasin de données au contenu de l'arborescence d'objets de l'application.

avertissement: cela nécessitera sûrement des performances et des ressources importantes. De plus, il faudra un peu de bricolage pour que cela fonctionne, mais théoriquement, cela devrait fonctionner. Je laisserai cela comme un exercice à l'affiche originale à mettre en œuvre it.;)

3
Patrick Klingemann

Avez-vous essayé de créer une suite de tests en utilisant quelque chose comme sahi vous pouvez alors enregistrer tous vos journaux utilisateur en utilisant ceci et lier ces tests à rcov ou quelque chose de similaire.

Vous devez vous assurer que vous avez tous les journaux utilisateur, mais après cela, vous pouvez regarder ce que rcov recrache et au moins commencer à éliminer les éléments qui ne sont évidemment jamais couverts.

1
krystan honour

Ce n'est pas une approche très proactive, mais j'ai souvent utilisé les résultats provenant de New Relic pour voir si quelque chose que je soupçonnais d'être inutilisé avait été appelé en production à tout moment au cours du dernier mois. Les applications sur lesquelles j'ai utilisé cela étaient assez petites cependant, et c'est assez cher pour les applications plus grandes.

Je ne l'ai jamais utilisé moi-même, mais cet article sur le laser gem semble parler de la résolution de votre problème exact.

1
Chris

marquer les méthodes suspectes comme privées. Si cela ne casse pas le code, vérifiez si les méthodes sont utilisées à l'intérieur de la classe. alors vous pouvez supprimer des choses

0
Dirk de Kok

Ce n'est pas la solution parfaite, mais par exemple dans NetBeans, vous pouvez trouver les utilisations des méthodes en faisant un clic droit dessus (ou appuyez sur Alt + F7).
Donc, si la méthode n'est pas utilisée, vous la verrez.

0
beornborn