82

Kent Beck の xUnit に相当するものを Ruby でコーディングすることで、Ruby の理解を深めています。Python (Kent が書いている) には、広く使用されている言語の assert() メソッドがあります。Ruby はそうではありません。これを追加するのは簡単だと思いますが、カーネルはそれを置くのに適切な場所ですか?

ところで、私は Ruby にさまざまな Unit フレームワークが存在することを知っています。これは、「何かを成し遂げる」ためではなく、Ruby のイディオムを学ぶための演習です。

4

5 に答える 5

117

いいえ、ベスト プラクティスではありません。Ruby で assert() に最もよく似ているのは、

 raise "This is wrong" unless expr

より具体的な例外処理を提供したい場合は、独自の例外を実装できます

于 2009-08-11T16:08:15.127 に答える
32

Ruby で assert を使用することは完全に有効だと思います。しかし、あなたは2つの異なることに言及しています:

  • 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。これにより、本番環境でのパフォーマンスの問題を回避できます。ただし、実用的なプログラマーは、それらを非アクティブ化しないことを推奨していることに注意してください。それらが実際にパフォーマンスに影響を与える場合にのみ、それらを無効にする必要があります。

慣用的な Ruby のやり方は通常のステートメントを使用しているという回答についてはraise、表現力に欠けると思います。アサーティブ プログラミングの黄金律の 1 つは、通常の例外処理にアサーションを使用しないことです。それらは2つの完全に異なるものです。この 2 つに同じ構文を使用すると、コードがわかりにくくなると思います。そしてもちろん、それらを無効にする機能は失われます。

The Pragmatic Programmer From Journeyman to MasterCode Completeのような 2 つの必読の古典的な本では、アサーションのセクション全体がアサーションに捧げられ、その使用が推奨されているため、アサーションを使用することは良いことであると確信できます。アサーティブ プログラミングとは何か、いつそれを使用するかを非常によく説明している、アサーションを使用したプログラミングというタイトルの素晴らしい記事もあります (これは Java に基づいていますが、概念はどの言語にも当てはまります)。

于 2011-09-20T07:05:37.670 に答える
15

Kernel モジュールに assert メソッドを追加する理由は何ですか? Assertionsまたは何かと呼ばれる別のモジュールを使用しないのはなぜですか?

このような:

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

  # define more assertions here
end

アサーションをどこでも利用できるようにする必要がある場合は、次のようにします。

class Object
  include Assertions
end

免責事項: 私はコードをテストしませんでしたが、原則として、このようにします。

于 2008-09-29T14:34:07.640 に答える
9

特に慣用句ではありませんが、良い考えだと思います。特に次のようにすると:

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

そうすれば、DEBUG (または他の便利なスイッチ、私は過去に Kernel.do_assert を使用しました) を設定して実行しないことにした場合でも、影響はありません。

于 2010-06-03T13:02:59.133 に答える
5

私の理解では、Rubyに慣れるための方法として、独自のテストスイートを作成しているということです。したがって、Test :: Unitはガイドとして役立つかもしれませんが、おそらくあなたが探しているものではありません(すでに仕事が終わっているため)。

そうは言っても、Pythonのassertは(少なくとも私にとっては)Cのassert(3)に似ています。これは、ユニットテスト用に特別に設計されたものではなく、「これは決して起こらないはず」のケースをキャッチするためのものです。

Rubyの組み込み単体テストが問題をどのように見る傾向があるかというと、個々のテストケースクラスはTestCaseのサブクラスであり、渡されたものの有効性をチェックして記録する「assert」ステートメントが含まれているということです。報告。

于 2008-09-29T21:04:54.500 に答える