単体テストでは十分ではありません。 静的型付けが必要です!

修士論文に取り組んでいたとき、無料のライセンスの下でインターネット上で公開することを約束しました。 私は学位を取得しましたが、残念ながら、私は大学の書かれていない規則の1つに出会いました。興味のある質問に多くの時間を費やすと、それがあなたを悩ませます。

最後に、1年後、私はまだそれを公開します。

私の作品全体を知るのが面倒な人(いずれにしても、60ページのテキストは研究にはあまり適していませんが、それでも十分ではありません)のために、この記事の短いバージョンを提供します。 ショートバージョンはいくつかの重要な情報を考慮していないことに注意してください。そのため、フルバージョンについてのみレビューを書くようお願いします。



私の研究では、エラーを検出するために静的型付けは必要ないと考えている動的型付けの支持者の議論に注目しました。



彼らの推論の本質は次のとおりです。

  1. 静的型付けはバグを検出するのに十分ではないため、単体テストが必要です。
  2. テストがあるため、静的型付けは冗長になります。
  3. 静的型付けのため、一部の正しいプログラムはコンパイル段階で警告を生成する場合があります。


私はこれらの声明を何度も聞いたという事実にもかかわらず、私はそれらの確認を見つけることができませんでした。 だから私は見つけることを決めた:ユニットテストは本当に入力ミスを排除するのに役立ちます。 また、別の質問にも興味がありました。開発者は、静的型の言語では表現できない動的型付けで言語構造を使用する頻度です。





私の実験は、ユニットテストで覆われた動的型付け言語でオープンソースプロジェクトを見つけ、それらを静的型付け言語に手動で翻訳することでした。 型チェックによって検出された欠陥の数と、静的言語に直接変換できない動的構造の数を調べたいと思いました。 この実験では、プログラムコードの書き換えはなく、あるプログラミング言語から別のプログラミング言語への行ごとの翻訳があることを強調しておく必要があります。 型チェックで検出されなかった欠陥や、元のプログラムでは発生しなかった他のエラーは考慮しません。



実験を開始する前に、動的および静的タイピングを使用する言語を選択する必要がありました。



動的言語の基準は次のとおりです。

  1. この言語は動的に入力する必要があります。
  2. 言語は単体テストをサポートする必要があります。
  3. この言語の十分な数のオープンソースソリューションが必要です。
  4. 言語は周知であり、十分な数のサポーターが必要です。


Pythonはこれらの基準に最適です。



次に、いくつかの要件を考慮した静的言語を選択する必要がありました。

  1. 言語はPythonと同じプラットフォームで実行する必要があります。
  2. 言語には厳密な類型化が必要です。
  3. 言語は静的型付けの支持者によって尊重されるべきです。


Haskellはこれらの要件をすべて満たしました。



次に、PythonからHaskellにブロードキャストされる4つのランダムなプロジェクトを選択しました。PythonNMEA ToolkitMIDIUtilGrapeFruit 、およびPyFontInfoです。



Python NMEAツールキット


このプロジェクトの放送により、9つのエラーが発生しました。 入力パラメーターのタイプが間違っているためにそのうち3つが発生し、残りの6つはAPIの不適切な使用のために発生しました。 単体テストでカバーされたタイプエラーは1つだけです。 静的型付けを使用すると、プログラムの実行中に現れる1つのエラーが修正されました。 次の理由から、2つの単体テストを排除できます。 それらは型チェックのためだけに役立ちました。 静的な構造に変換できない単一の動的な構造は見つかりませんでした。



MIDIUtil


MIDIUtilブロードキャストにより2つのエラーが発生しました。 それらの1つは、テストを使用して追跡できます。 静的型付けはもう1つを排除します。 MIDIUtilユーティリティは、struct.packおよびstruct.unpackメソッドを使用します。これらのメソッドは、Haskellに直接変換できません。これらのメソッドは、引数のタイプと戻り値を含むフォーマット文字列を使用するためです。

ただし、すべての使用ケースで、書式設定文字列はハードコーディングされているため、Haskellコードは表現力を失うことなく、代わりにハードコーディングされた関数を使用できます。 そのような行がMIDIUtilの構成ファイルに格納されている場合、静的型付けによる言語への翻訳のために、ソリューションのアーキテクチャに真剣に取り組む必要があります。



グレープフルーツ


GrapeFruitからのブロードキャストでは、エラーは明らかになりませんでした。 また、実行中の唯一の間違いは、静的型付けによって排除できます。 静的型付けは、1つのテストを取り除くのに役立つことに注意してください。 静的なデザインに変換できない単一の動的なデザインはありませんでした。



PyFontInfo


PyFontInfoからの翻訳により、6つのタイプエラーが特定されました。 静的型付けを使用すると、2つのランタイムエラーを解決できます。 1つのテストを削除できます。 PyFontInfoもstruct.packとstruct.unpackを使用するため、Haskellに翻訳することはできませんが、この制限は回避できます。



結果


経験上、多くの困難を伴わないすべてのプロジェクトは静的な類型化された言語に翻訳でき、変更は最小限で済むことが示されています。 ユニットテストは静的型付けの適切な代替とは言えないことが判明しました。 実験中に、テストでは検出されなかった17のタイピングエラーが検出されました。 しかし、多くのエラーはまだテストでカバーされていました。



おわりに


実験の結果は、単体テストを静的型付けの代替と見なすことはできず、すべての問題を考慮していないことを示しています。 重要な問題は、型の有能なテストの構築に時間がかかることであり、静的型付けの言語ではこれは自動的に行われます。 動的言語で記述されたプログラムに静的型チェックを使用すると、テストでは検出されない欠陥を特定できます。 同時に、大規模なアーキテクチャの処理を必要としません。

経験から、単体テストを使用して入力エラーをなくすという問題の新しい見方が示されました。 これが誰かに興味を持ち、他のプロジェクトで実験を行うことを願っています。

記事の完全版はこちらで読むことができます



All Articles