web-dev-qa-db-ja.com

型なしプロジェクトで動的言語の予期しない型をチェックする必要がありますか?

型チェックシステムを使用する静的型付き言語または動的型付き言語では、入力型がコントラクトで指定した型であることを保証できます。

ただし、動的に型付けされた言語では、なし型チェックシステムが導入されているため、他の人が関数を呼び出す方法がわかりません。

これらの状況では、型を検証し、予期しない型が適切に処理される単体テストを記述することは理にかなっていますか?

5
Adam Thompson

タイプを検証し、予期しないタイプが適切に処理される単体テストを記述することは意味がありますか

並べ替え-「単体テスト」を「自動テスト」に置き換えると、答えは「はい」になります。

入力としてオブジェクトBを期待する関数Aがあり、コンポーネントCがAを呼び出す場合、静的に型付けされた言語で、CがBではないもの(またはBの派生物)を渡そうとするとコンパイラーは文句を言います。

動的に型付けされた言語では、渡されたオブジェクトがBの有効な置き換えではない場合、コンパイラエラーは発生しません。このようなエラーは、コードが実行されるまで検出されないままになる可能性があります。このような状況では、Cの自動テスト(Aを使用)は、欠落しているコンパイラー・チェックの代替として実際に機能します。 (そのテストがCの単体テストである場合、またはC&Aの統合テストがシステム内のAとCの内容によって異なる場合がありますが、どのように呼び出すかは重要ではありません)。

すべきこれを行う場合、これらの追加のテストにどれだけの労力を費やす必要があるかは、別の問題です。これは一般的に答えることはできず、大きく依存します

  • システムのサイズと複雑さについて
  • 一般的なシステムのテストプロセス
  • 保守性、進化性、信頼性などの機能以外の要件
  • 生産に陥るエラーの経済的影響

等々。おそらく、問題となっているコンポーネントの実行をカバーする、より大まかな統合テストが他にもあるでしょう。たぶん、ほとんどのバグをキャッチするのに十分な手動のテストプロセスがあるでしょう。部品が生産で故障した場合、多分あなたは余裕があるかもしれません。これが発生した場合、開発チームが指摘され、これを十分に早く修正できるからです。最後に、これは常にトレードオフです。

静的に型付けされた言語を使用している場合でも、テストと本番環境でのエラーの問題に対処する必要があることに注意してください。型の安全性や追加のテストでは、本番環境での失敗の確率を小さくするだけで、ゼロにすることはできません。

6
Doc Brown

この場合、それはあなたが何をしたいかに本当に依存すると思います-両方のオプション(あなたが提案すること/まったく何もしないこと)は私には理にかなっているようです。

動的な型チェックを使用して解釈/コンパイルされる言語で「型を検証する」ことについては、あまり話しません。そのような場合、インタプリタ(コンパイラ)が気にするのは、アクセスするものが存在することです(誰かがコメントで述べたように-ダックタイピング)。

したがって、実行したい入力の検証は、この処理に関係しているはずです-この引数は、私が期待するものに付属していますか?

私がこの選択をするなら、私のコードを使用する人に任せます-そのような言語の要点は、型について心配するべきではないということです!

2
Alex Brisan

このようなチェックは、実行可能なドキュメントとして機能し、デバッグを支援し(予期しない入力が提供された場合に早期に失敗することにより)、テストが非常に簡単です。ほとんどの場合、それらは素晴らしいアイデアです。例えば:

def system_under_test(name):
    assert isinstance(name, str)  # <-- a check!!
    return "Hello, " + name

import pytest

def test_it_works():
    assert system_under_test("World") == "Hello, World"

def test_it_rejects_invalid_input():
    for name in (None, 42, True, object()):
        with pytest.raises(AssertionError):
            system_under_test(name)

そのコードが非常に動的である場合、たとえばダックタイピングを利用する場合など、状況はさらに難しくなります。しかし、解決策は簡単です。それから、型をチェックしないでください。安全対策は完璧である必要はありません。 someの問題を防ぐことができれば、すでに価値があります。

厳密なTDDを使用している場合は、テストで要求されない限り、そのような型チェックを含むコードを記述しないでください。したがって、小さなテスト(無効な入力に対しては本当に簡単です!)を追加するのが賢明なようです。テスト例のみをテストするため、関数がすべての有効な入力を受け入れ、すべての無効な入力を拒否することを保証できないという警告があります。しかし、繰り返しになりますが、部分的な安全対策はどれよりも優れています。 TDDの観点では、必要に応じてテストに例を追加します。上記のテストは、明確な必要なしに複数の例をループするため、すでに過剰です。

2
amon