94 votes

Est-il idiomatique en Ruby d'ajouter une méthode assert( ) à la classe Kernel de Ruby ?

Je développe ma compréhension de Ruby en codant un équivalent de xUnit de Kent Beck en Ruby. Python (langue dans laquelle Kent écrit) a une méthode assert() dans le langage qui est largement utilisée. Ruby n'en a pas. Je pense qu'il devrait être facile de l'ajouter mais est-ce que Kernel est le bon endroit pour le faire ?

BTW, Je connais l'existence des différents frameworks Unit en Ruby - il s'agit d'un exercice pour apprendre les idiomes Ruby, plutôt que pour "faire quelque chose".

136voto

Julik Points 3226

Non, ce n'est pas une bonne pratique. La meilleure analogie avec assert() en Ruby est d'augmenter la valeur de

 raise "This is wrong" unless expr

et vous pouvez implémenter vos propres exceptions si vous souhaitez prévoir une gestion plus spécifique des exceptions

38voto

jmanrubia Points 515

Je pense qu'il est tout à fait valable d'utiliser des assertions en Ruby. Mais vous mentionnez deux choses différentes :

  • Les frameworks xUnit utilisent assert des méthodes pour vérifier les attentes en matière de tests. Elles sont destinées à être utilisées dans votre code de test, et non dans votre code d'application.
  • Certains langages, comme le C, le Java ou le Python, comprennent une fonction assert destiné à être utilisé à l'intérieur du code de vos programmes, pour vérifier les hypothèses que vous faites sur leur intégrité. Ces vérifications sont intégrées au code lui-même. Il ne s'agit pas d'un utilitaire de test, mais d'un utilitaire de développement.

J'ai récemment écrit solid_assert : une petite bibliothèque Ruby implémentant un utilitaire d'assertion Ruby et aussi un billet sur mon blog expliquant sa motivation . Il permet d'écrire des expressions sous la forme :

assert some_string != "some value"
assert clients.empty?, "Isn't the clients list empty?"

invariant "Lists with different sizes?" do
    one_variable = calculate_some_value
    other_variable = calculate_some_other_value
    one_variable > other_variable
end    

Et ils peuvent être désactivés, donc assert y invariant sont évaluées comme des déclarations vides. Cela vous permet d'éviter les problèmes de performance en production. Mais notez que Le programmeur pragmatique : du compagnon au maître recommande de ne pas les désactiver. Vous ne devez les désactiver que s'ils affectent réellement les performances.

En ce qui concerne la réponse disant que la façon idiomatique de Ruby est d'utiliser un fichier normal raise Je pense qu'il manque d'expressivité. L'une des règles d'or de la programmation assertive est de ne pas utiliser les assertions pour la gestion normale des exceptions. Il s'agit de deux choses complètement différentes. Si vous utilisez la même syntaxe pour les deux, je pense que votre code sera plus obscur. Et bien sûr, vous perdez la possibilité de les désactiver.

Certains ouvrages très réputés consacrent des sections entières aux assertions et recommandent leur utilisation :

Programmation avec assertions est un article qui illustre bien ce qu'est la programmation assertive. quand l'utiliser (il est basé sur Java, mais les concepts s'appliquent à n'importe quel langage). langage).

15voto

Christoph Schiessl Points 3672

Pourquoi ajouter la méthode assert au module Kernel ? Pourquoi ne pas utiliser un autre module appelé Assertions ou quelque chose comme ça ?

Comme ceci :

module Assertions
  def assert(param)
    # do something with param
  end

  # define more assertions here
end

Si vous avez vraiment besoin que vos assertions soient disponibles partout faire quelque chose comme ça :

class Object
  include Assertions
end

Avertissement : je n'ai pas testé le code, mais en principe, je procéderais de la manière suivante.

10voto

regularfry Points 2203

Ce n'est pas particulièrement idiomatique, mais je pense que c'est une bonne idée. Surtout si c'est fait comme ça :

def assert(msg=nil)
    if DEBUG
        raise msg || "Assertion failed!" unless yield
    end
end

De cette façon, il n'y a pas d'impact si vous décidez de ne pas exécuter avec DEBUG (ou un autre commutateur pratique, j'ai utilisé Kernel.do_assert dans le passé).

5voto

Atiaxi Points 1349

Si j'ai bien compris, vous écrivez votre propre suite de tests pour vous familiariser avec Ruby. Donc, bien que Test::Unit puisse être utile comme guide, ce n'est probablement pas ce que vous recherchez (parce qu'il a déjà fait le travail).

Cela dit, la fonction assert de python est (pour moi, du moins), plus analogue à la fonction assert du langage C. affirmer(3) . Il n'est pas spécifiquement conçu pour les tests unitaires, mais plutôt pour détecter les cas où "cela ne devrait jamais se produire".

La façon dont les tests unitaires intégrés à Ruby ont tendance à considérer le problème est que chaque classe de cas de test est une sous-classe de TestCase et cela inclut une déclaration "assert" qui vérifie la validité de ce qui lui a été transmis et l'enregistre en vue d'un rapport.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X