Est-ce idiomatique que Ruby ajoute une méthode assert () à la classe Ruby's Kernel?

StackOverflow https://stackoverflow.com/questions/147969

  •  02-07-2019
  •  | 
  •  

Question

J'élargis ma compréhension de Ruby en codant un équivalent du xUnit de Kent Beck en Ruby. Python (dans lequel Kent écrit) a une méthode assert () dans le langage qui est largement utilisée. Ruby pas. Je pense qu’il devrait être facile d’ajouter cela, mais est-ce que Kernel est le bon endroit pour le dire?

BTW, Je connais l'existence de divers cadres d'unité dans Ruby - il s'agit d'un exercice pour apprendre les idiomes de Ruby, plutôt que pour "obtenir quelque chose de concret".

Était-ce utile?

La solution

Non, ce n'est pas une pratique exemplaire. La meilleure analogie pour assert () dans Ruby est juste de lever

 raise "This is wrong" unless expr

et vous pouvez implémenter vos propres exceptions si vous souhaitez fournir un traitement plus spécifique des exceptions

Autres conseils

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

    Les frameworks
  • xUnit utilisent des méthodes assert pour vérifier les attentes de vos tests. Ils sont destinés à être utilisés dans votre code de test et non dans le code de votre application.
  • Certains langages tels que C, Java ou Python, incluent une construction assert destinée à être utilisée dans le code de vos programmes, afin de vérifier les hypothèses que vous faites sur leur intégrité. Ces contrôles sont construits à l'intérieur du code lui-même. Ce ne sont pas des utilitaires de test, mais de développement.

J'ai récemment écrit une solid_assert: une petite bibliothèque Ruby implémentant un utilitaire d'assertion Ruby ainsi qu'une un article de mon blog expliquant sa motivation .. Il a laissé vous écrivez 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 pour que assert et invariant soient évalués comme des instructions vides. Cela vous permet d'éviter tout problème de performances en production. Mais notez que les programmeurs pragmatiques déconseillent de les désactiver. Vous ne devriez les désactiver que s’ils affectent réellement la performance.

En ce qui concerne la réponse disant que la méthode idiomatique de Ruby utilise une instruction augmenter normale, je pense qu’elle manque d’expressivité. L'une des règles d'or de la programmation assertive consiste à ne pas utiliser d'assertions pour la gestion normale des exceptions. Ce sont 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.

Vous pouvez être convaincu que l’utilisation d’assertions est une bonne chose car deux livres classiques à lire absolument, comme Le programmeur pragmatique De compagnon à maître et Code complet complet sections à eux et recommander leur utilisation. Il existe également un bel article intitulé Programmation assertée Cela illustre très bien la programmation dynamique et son utilisation (elle est basée sur Java, mais les concepts s’appliquent à n’importe quel langage).

Quelle est la raison pour laquelle vous avez ajouté la méthode assert au module Kernel? Pourquoi ne pas simplement utiliser un autre module appelé Assertions ou quelque chose?

Comme ceci:

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

  # define more assertions here
end

Si vous avez vraiment besoin que vos affirmations soient disponibles partout , procédez comme suit:

class Object
  include Assertions
end

Avertissement: je n'ai pas testé le code, mais je le ferais en principe comme ceci.

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 manière, vous n'aurez aucun impact si vous décidez de ne pas utiliser DEBUG (ou un autre commutateur pratique, j'ai déjà utilisé Kernel.do_assert).

D'après ce que j'ai compris, vous écrivez votre propre suite de tests pour mieux vous familiariser avec Ruby. Donc, si Test :: Unit peut être utile en tant que guide, ce n’est probablement pas ce que vous recherchez (car il a déjà fait le travail).

Cela étant dit, l'affirmation de python est (du moins pour moi) analogue à celle de de C assert (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 arriver".

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

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top