4

単体テスト/テスト駆動開発のアイデア全体を調べ始めましたが、考えれば考えるほど、静的型チェックと同様の役割を果たしているように思えます。どちらの手法も、プログラム内の特定の種類のエラーに対するコンパイル時の迅速な応答チェックを提供します。ただし、私が間違っている場合は訂正してください。ただし、完全にカバーされた単体テスト スイートは、静的型チェックでテストされるすべてのものをテストし、次にいくつかをテストするようです。別の言い方をすれば、静的型チェックは、プログラムが正しいことを「証明」する方法の一部にすぎませんが、単体テストでは、必要なだけ (ある程度まで) 「証明」できます。

では、単体テストも使用している場合、静的型チェックを備えた言語を使用する理由はありますか? ここで似たような質問がありましたが、もう少し詳しく説明したいと思います。単体テストに対する静的型チェックの具体的な利点は何ですか? コンパイラの最適化やインテリセンスなどの問題がいくつか思い浮かびますが、これらの問題に対する他の解決策はありますか? 私が考えていない他の利点/欠点はありますか?

4

10 に答える 10

11

ソフトウェアの品質に関して不変の事実が 1 つあります。

コンパイルできない場合は出荷できません

このルールでは、静的に型付けされた言語が動的に型付けされた言語に勝ちます。

はい、このルールは不変ではありません。Web アプリはコンパイルせずに出荷できます (私は、コンパイルされなかった多くのテスト Web アプリをデプロイしました)。しかし、根本的に正しいのは

エラーを発見するのが早ければ早いほど、修正コストが安くなります

静的に型付けされた言語は、ソフトウェア開発サイクルの可能な限り早い段階で実際のエラーが発生するのを防ぎます。動的言語はそうではありません。単体テストは、超人的なレベルまで徹底している場合は、静的型付け言語の代わりになる可能性があります。

しかし、なぜわざわざ?コンパイラの形でエラーチェックシステム全体を書いている信じられないほど賢い人がたくさんいます。エラーがすぐに発生することを懸念している場合は、静的に型付けされた言語を使用してください。

この投稿を動的言語のバッシングと見なさないでください。私は毎日動的言語を使用し、それらを愛しています。それらは信じられないほど表現力と柔軟性があり、信じられないほど魅力的なプログラムを可能にします.sしかし、初期のエラー報告の場合、静的に型付けされた言語に負けます.

于 2009-01-06T04:30:50.207 に答える
6

適度な規模のプロジェクトの場合、単体テストだけではすべての状況を説明することはできません。

したがって、私の答えは「いいえ」です。すべての状況を説明できたとしても、そもそも動的言語を使用する目的全体を無効にしてしまいます。

タイプ セーフなプログラムを作成する場合は、タイプ セーフな言語を使用することをお勧めします。

于 2009-01-06T04:27:48.560 に答える
5

自動化された単体テストは動的型付き言語にとって重要になると思いますが、適用するコンテキストで静的型チェックを置き換えるという意味ではありません。実際、動的型付けを使用している人の中には、型の安全性を定期的にチェックするという煩わしさを望まないという理由で、実際に動的型付けを使用している人もいるかもしれません。

静的型付き言語に対する動的型付き言語の利点は、テストをはるかに超えており、型の安全性は 1 つの側面にすぎません。動的型付け言語と静的型付け言語のプログラミング スタイルと設計の違いも大きく異なります。

さらに、タイプ セーフを強制するように精力的に記述された単体テストは、結局、ソフトウェアを動的に型付けするべきではないこと、または適用される設計を動的な言語ではなく静的に型付けされた言語で記述する必要があることを意味します。

于 2009-01-06T04:29:34.063 に答える
3

マニフェストタイピング(私はあなたが意味すると思います)は仕様の形式です、それは例を提供するだけなので、ユニットテストははるかに弱いです。重要な違いは、仕様はどのような場合でも保持しなければならないことを宣言しているのに対し、テストは例のみをカバーしていることです。テストがすべての境界条件をカバーしていることを確認することはできません。

人々はまた、ドキュメントとして宣言された型の価値を忘れがちです。たとえば、Javaメソッドがを返す場合、List<String>私は自分が何を取得するかを即座に知ることができ、ドキュメント、テストケース、さらにはメソッドコード自体を読む必要はありません。パラメータについても同様です。型が宣言されている場合、メソッドが何を期待するかがわかります。

ローカル変数の型を宣言する値は、適切に記述されたコードでは変数の存在範囲を小さくする必要があるため、はるかに低くなります。ただし、静的型付けは引き続き使用できます。型を宣言する代わりに、コンパイラーに推測させます。ScalaC#のような言語でも、これを行うことができます。

一部のスタイルのテストは仕様に近づきます。たとえば、QuickCheckまたはScalaバリアントのScalaCheckは、仕様に基づいてテストを生成し、重要な境界を推測しようとします。

于 2009-01-06T06:08:51.117 に答える
3

コード カバレッジが 100% であっても、アプリケーションを完全にテストしたことにはなりません。次のコードを検討してください。

if (qty > 3)
{
    applyShippingDiscount();
}
else
{
    chargeFullAmountForShipping();
}

qty = 1 と qty = 4 の値を入れれば、100% のコード カバレッジを得ることができます。

ここで、私のビジネス条件が「... 3 つ以上のアイテムを注文した場合、送料に割引を適用する..」であると想像してください。次に、境界で機能するテストを作成する必要があります。したがって、qty が 2、3、および 4 のテストを設計します。まだ 100% のカバレッジがありますが、さらに重要なことに、ロジックにバグが見つかりました。

これが、コード カバレッジだけに焦点を当てることで私が抱えている問題です。せいぜい、開発者がビジネス ルールに基づいていくつかの初期テストを作成する状況になると思います。次に、カバレッジ数を増やすために、新しいテスト ケースを設計するときにコードを参照します。

于 2009-01-06T04:42:59.590 に答える
2

いいえ。

しかし、それは最も重要な質問ではありません。最も重要な質問は、それができないことは重要ですか?

静的型チェックの目的を検討してください。コードの欠陥(バグ)のクラスを回避することです。ただし、これは、すべてのコード欠陥のより大きなドメインのコンテキストで検討する必要があります。最も重要なのは、狭いスライバーに沿った比較ではなく、コード品質の深さと幅、正しいコードの記述のしやすさなどを比較することです。チームがより高い品質を生み出すことを可能にする開発スタイル/プロセスを考え出すことができれば静的型チェックなしでより効率的にコーディングすれば、それだけの価値があります。これは、静的型チェックがキャッチする穴がテストにある場合にも当てはまります。

于 2009-01-06T05:30:41.507 に答える
2

別の言い方をすれば、静的に型付けされた言語を使用していない場合、そのコードで「実際の」ことを行う予定がある場合は、非常に徹底的な単体テストを行う必要があります。

とはいえ、静的型付け (または明示的型付け) には、単体テストよりもいくつかの大きな利点があるため、一般的には静的型付けを好みます。より理解しやすい API を作成し、アプリケーションの「スケルトン」 (つまり、各モジュールまたはコードのセクションへのエントリ ポイント) を、動的型付け言語でははるかに難しい方法ですばやく表示できるようにします。

要約すると、私の意見では、堅牢で徹底的な単体テストを考えると、動的型付け言語と静的型付け言語のどちらを選択するかは、ほとんどが好みの問題です。どちらかを好む人もいます。他の人は他の人を好みます。仕事に適したツールを使用してください。しかし、これはそれらが同一であることを意味するものではありません.静的に型付けされた言語は常に特定の方法で優位にあり、動的に型付けされた言語は常に特定の異なる方法で優位に立っています. 単体テストは、動的型付け言語の欠点を最小限に抑えるのに大いに役立ちますが、それらを完全になくすことはできません。

于 2009-01-06T04:47:55.290 に答える
1

徹底的にやればできると思います。しかし、なぜわざわざ?静的型が正しいことを言語が既にチェックしている場合、それらをテストしても意味がありません (無料で入手できるため)。

また、IDE で静的型付き言語を使用している場合、IDE は、コンパイルしてテストする前であっても、エラーと警告を表示できます。同じことができる自動化されたユニットテストアプリケーションがあるかどうかはわかりません。

于 2009-01-06T04:23:00.330 に答える
0

動的な遅延バインディング言語のすべての利点を考えると、それが単体テストによって提供される価値の 1 つだと思います。慎重かつ意図的にコーディングする必要がありますが、それはあらゆる種類のコーディングの第 1 の要件です。明確で単純なテストを記述できることは、設計と実装の明確さと単純さを証明するのに役立ちます。また、後でコードを見る人に役立つ手がかりも提供します。しかし、不一致の型を検出するためにそれを当てにするとは思いません。しかし、実際には、型チェックが実際に多くの実際のエラーをキャッチしているとは思いません。そもそも明確で単純なコーディングスタイルを持っている場合、これは実際のコードで発生するタイプのエラーではありません。

JavaScript の場合、jsLint はほとんどすべての型チェックの問題を検出できると思います。主に、露出を減らすために別のコーディング スタイルを提案することによって。

于 2009-01-06T04:28:37.170 に答える
0

型チェックは、システム内のコンポーネント間の契約を強制するのに役立ちます。単体テスト (名前が示すように) は、コンポーネントの内部ロジックを検証します。

コードの 1 つの単位については、単体テストによって静的型チェックが不要になる可能性があると思います。しかし、複雑なシステムでは、自動化されたテストでは、システムのさまざまなコンポーネントが相互作用するさまざまな方法をすべて検証することはできません。このため、インターフェイス(ある意味では、コンポーネント間の一種の「契約」) の使用は、潜在的なエラーを減らすための便利なツールになります。また、インターフェイスにはコンパイル時の型チェックが必要です。

私は動的言語でのプログラミングを本当に楽しんでいるので、動的型付けを非難しているわけではありません。これは最近私に起こった問題です。残念ながら、大規模で複雑なシステムに動的言語を使用した経験はまったくありません。そのため、この問題が現実のものなのか、単に理論上のものなのか、他の人から聞いてみたいと思います。

于 2009-11-13T06:46:16.287 に答える