Это идиоматический Ruby, чтобы добавить метод assert () в класс ядра Ruby?



я расширяю свое понимание Ruby, кодируя эквивалент xUnit Кента Бека в Ruby. Python (который пишет кент) имеет метод assert () на языке, который широко используется. Руби-нет. Я думаю, что это должно быть легко добавить, но является ли ядро правильным местом для его размещения?



кстати, Я знаю о существовании различных структур единиц в Ruby - Это упражнение, чтобы узнать Ruby идиомы, а не "получить что-то сделано".

541   5  

5 ответов:

нет, это не лучшая практика. Лучшая аналогия для утверждения () в Ruby-это просто повышение

 raise "This is wrong" unless expr

и вы можете реализовать свои собственные исключения, если вы хотите обеспечить более конкретную обработку исключений

Я думаю, что это совершенно справедливо использовать утверждает в Ruby. Но вы упомянули две разные вещи:

  • в xUnit фреймворков использовать assert методы проверки ваших ожиданий тестов. Они предназначены для использования в тестовом коде, а не в коде приложения.
  • некоторые языки, такие как C, Java или Python, включают assert конструкция предназначена для использования внутри кода ваших программ, чтобы проверить предположения, которые вы делаете об их целостности. Эта проверка строятся внутри самого кода. Они не являются утилитой времени тестирования, но временем разработки.

Я недавно написал solid_assert: небольшая библиотека Ruby, реализующая утилиту утверждения Ruby и сообщение в моем блоге, объясняющее его мотивацию.. Это позволит вам писать выражения в виде:

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    

и их можно деактивировать так assert и invariant получить оценивается как пустые операторы. Это позволит вам избежать любой производительности проблема в производстве. Но заметьте, что Прагматичные Программисты рекомендуем их отключить. Вы должны отключить их только в том случае, если они действительно влияют на производительность.

что касается ответа, говорящего, что идиоматический рубиновый способ использует нормальный raise заявление, я думаю, что ему не хватает выразительности. Одно из золотых правил ассертивного программирования-не использовать утверждения для обычной обработки исключений. Это две совершенно разные вещи. Если вы используете тот же синтаксис для двух из них, я думаю, что код будет более темным. И, конечно же, вы теряете возможность деактивировать их.

вы можете быть уверены, что использование утверждений-это хорошо, потому что два обязательных чтения классических книг, таких как прагматичный программист от подмастерья до мастера и Код посвятите им целые разделы и рекомендуйте их использование. Есть также хорошая статья под названием Программирование с утверждениями это очень хорошо иллюстрирует, что такое ассертивное программирование и когда его использовать (он основан на Java, но понятия применимы к любому языку).

какова ваша причина для добавления метода assert в модуль ядра? Почему бы просто не использовать другой модуль под названием Assertions или что-то?

такой:

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

  # define more assertions here
end

Если вам действительно нужно, чтобы ваши утверждения были доступны везде сделать что-то вроде этого:

class Object
  include Assertions
end

отказ от ответственности: я не тестировал код, но в принципе я бы сделал это так.

Это не особенно идиоматично, но я думаю, что это хорошая идея. Особенно если сделать так:

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

таким образом, нет никакого влияния, если вы решите не работать с DEBUG (или каким-либо другим удобным переключателем, я использовал Kernel.do_assert в прошлом).

Я понимаю, что вы пишете свой собственный набор тестов, чтобы лучше познакомиться с Ruby. Поэтому, хотя Test:: Unit может быть полезен в качестве руководства, это, вероятно, не то, что вы ищете (потому что это уже сделано).

тем не менее, утверждение python (по крайней мере, для меня) более аналогично C assert(3). Он специально не предназначен для модульных тестов, а скорее для того, чтобы поймать случаи, когда "этого никогда не должно произойти".

Как Рубин встроенные модульные тесты, как правило, рассматривают проблему, так как каждый отдельный класс тестового набора является подклассом TestCase, и это включает в себя оператор" assert", который проверяет действительность того, что было передано ему, и записывает его для отчетности.

Comments

    Ничего не найдено.