F#開発と単体テスト?


107

私はF#を使い始めました。これは私の最初の関数型言語です。私はC#で準独占的に作業しており、F#でコードの記述方法を再考する方法をたくさん楽しんでいます。私が少し混乱していると思う1つの側面は、コードを書くプロセスの変更です。私はC#で何年もTDDを使用してきましたが、自分がどこにいるのかを知るための単体テストがあると本当に感謝しています。

これまでのところ、F#での私のプロセスは、いくつかの関数を記述し、それらが機能することを「合理的に」確認できるまで対話型コンソールで遊んで、調整して組み合わせることでした。これはオイラープロジェクトのような小規模な問題ではうまく機能しますが、そのように大きなものを構築することは想像できません。

人々はどのようにユニットテストに取り組み、F#プログラムのテストスイートを構築しますか?TDDに相当するものはありますか?ご意見やご感想をお寄せください。


1
Expert-fsharp.com/CodeSamples/Forms/…は、F#でNUnitを使用する簡単な例を示しています。
itowlson、2010年


関連:stackoverflow.com/questions/5667372/…(このページの回答セット内にあるため、引用符を外すと脚注/コメントよりもはるかに多くなります)
Ruben Bartelink 2013年

これらの回答に欠けているものの1つは、F#の型推論に関連するFoq、AutoFixture.AutoFoq、およびAutoFixture.xUnitの適切な例です。試飲者についてはtrelford.com/blog/post/test5.aspxtrelford.com/blog/post/fstestlang.aspxを参照してください。いつかここで適切な回答をここに書きます
Ruben Bartelink 2013年

回答:


77

テスト駆動型の開発者は、F#などの関数型言語に慣れ親しんでいる必要があります。確定的に反復可能な結果を​​提供する小さな関数は、単体テストに完全に適しています。F#言語には、テストの作成を容易にする機能もあります。たとえば、オブジェクト式を見てみましょう。入力としてインターフェース型をとる関数の偽物を非常に簡単に書くことができます。

どちらかと言えば、F#はファーストクラスのオブジェクト指向言語であり、C#でTDDを実行するときに使用するのと同じツールとトリックを使用できます。F#で作成された、またはF#専用のテストツールもあります。

Matthew Podwysockiは、関数型言語でのユニットテストに関する素晴らしいシリーズを執筆しました。ボブおじさんもここで刺激的な記事を書いた。


9
Unquote:code.google.com/p/unquoteと呼ばれるF#固有の単体テストライブラリも開発しました(積極的に開発しています)。F#引用を使用して、静的にチェックされたプレーンなF#ブール式としてテストアサーションを記述し、素晴らしいテスト失敗メッセージを自動的に生成できます。xUnit.netとNUnitの両方を特別にサポートすることで、設定不要で動作し、通常、例外ベースのユニットテストフレームワークをサポートします。FSIセッション内でも機能し、インタラクティブなテストから正式なテストスイートへのシームレスな移行を可能にします。
Stephen Swensen、2011

ありますPexがそれは少し難しい完全に理解するのだが、あまりにも。
Benjol 2013年

1
ボブおじさんのリンクは死んでいるようだ
Aage

22

私はNUnitを使用していますが、読みにくく、書くのが面倒ではありません。

open NUnit.Framework

[<TestFixture>]
type myFixture() = class

    [<Test>]
    member self.myTest() =
       //test code

end

私のコードはF#と他の.Net言語が混在しているため、ユニットテストを基本的に同じ方法で、F#とC#の両方で同様の構文で記述しているのが気に入っています。


4
ここで他の応答を読んだ後、私はFSUnitを試してみましたが、それは素晴らしいことだと思います。(NUnitと同様に)TestDriven.Netでうまく機能し、自己文書化テストを書くための流動的なスタイルを奨励し、Rayが述べているように、「F#言語のほうが慣れています」。21行のコードでは悪くありません!(およびレイアウト/命名の推奨事項のカップル)。2つの簡単なメモ:1.プリコンパイルされたFSUnit DLLが機能しませんでした。ソース(FsUnit.NUnit-0.9.0.fs)からビルドすると、問題が修正されました。2. TestDriven.Netは、に見えるTextFixture名を認識しません`like this`。ダブルティック形式を使用したテスト名が認識されます。
David Glaubman、2010年

15

F#の自動テストツールであるFsCheckを見てください。基本的にはHaskellのQuickCheckの移植版です。これにより、関数またはメソッドが満たすべきプロパティの形式でプログラムの仕様を提供し、ランダムに生成された多数のケースでプロパティが保持するFsCheckテストを提供できます。

FsCheck CodePlexページ

FsCheck作成者ページ


はい、私はFsCheckがNUnitなどの従来の単体テストフレームワークよりもはるかに多く提供していると思います
Robert

11

dglaubmanが示唆するように、NUnitを使用できます。xUnit.netはまた、このためのサポートを提供してうまく機能TestDriven.net。コードはNUnitテストに似ていますが、テストを包含タイプにラップする必要がありません。

#light

// Supply a module name here not a combination of module and namespace, otherwise
// F# cannot resolve individual tests nfrom the UI.
module NBody.DomainModel.FSharp.Tests

open System
open Xunit

open Internal

[<Fact>]
let CreateOctantBoundaryReordersMinMax() =
    let Max = VectorFloat(1.0, 1.0, 1.0)
    let Min = VectorFloat(-1.0, -1.0, -1.0)

    let result = OctantBoundary.create Min Max

    Assert.Equal(Min, result.Min)     
    Assert.Equal(Max, result.Max) 

1.9.1の時点で、Xunitの新しいオーバーロードが私のF#に大混乱を引き起こしているようです。
リックMinerich

@RickMinerich私のコードにも同じことが起こっています。正しいオーバーロードが選択されるように、明示的な型注釈を追加しただけです。ただし、これにより、残念ながらコードにノイズ追加されます。
Erik Schierboom 2013年

11

これは非常に興味深い質問だと思います。これまでの私の考えはただの考えですので、彼らが何であるかについて考えてください。

自動化されたテストスイートのセーフティネットは価値が高すぎて手放せないと思いますが、インタラクティブコンソールは魅力的かもしれないので、これまでと同じように単体テストを書き続けるつもりです。

.NETの主な長所の1つは、クロス言語機能です。すぐにF#の製品コードを書くつもりですが、私の計画では、C#で単体テストを記述して、新しい言語の使い方を簡単に理解できるようにする予定です。このようにして、F#で記述したものがC#(および他の.NET言語)と互換性があるかどうかもテストできます。

このアプローチでは、F#コードで内部的にしか使用できないが、パブリックAPIの一部として公開できないF#の特定の機能があることを理解していますが、今日受け入れるのと同じように、特定のものがあることを受け入れますC#を使用するuintと、CLSに準拠していない(など)を表現できるため、それらの使用は控えます。


2
あなたの計画はどうでしたか?f#コードをc#コードでテストするのは簡単でしたか?私はf#の学習を始めました。私の計画は私のプロジェクトの一部をf#で書くことですが、同じ考えがあります。f#のc#でも単体テストを書くことです。
Peter Porfy 2012

@更新をマークしますか?また、F#でTDDを使用してフローに入るのに苦労しています。
スコットニムロッド

1
@ScottNimrodかなり更新されました。私のPluralsightコースの 4つは F#でのテストまたはTDDに関するものです。私のLanyrdプロファイルには会議の講演の無料録音がたくさんあります。最後に、私のブログがあります。
Mark Seemann、2015

3
@ScottNimrodマークのPSコースの完全なセットを見るのに十分な時間をかけたり、お金を払ったりすることはお勧めできません。最高の効率ですべてをまとめることができます。特定のニーズに当てはまる場合と当てはまらない場合がありますが、「F#の機能的アーキテクチャ」も多くの点をつなぐため、十分に検討する必要があります。
Ruben Bartelink

7

FSUnitを見ることができます。まだ使用していませんが、試してみる価値はあります。F#で(ネイティブ)NUnitの例を使用するよりも確かに優れています。


1
ShdNx、なぜNUnitを反対するのですか?Don SymeのF#ブックはテスト用のNUnitを示しており、C#でのNUnitの使用と非常によく似ています。FSUnit DSLはクールに見えますが、NUnit(Mathiasは「長年TDDを使用してきた」)に既に慣れている人にとって、N#をF#で使用することはC#またはVBを使用するよりも問題があるという経験ですか?
itowlson 2010年

私はitowlsonのコメントを2番目にして質問します。間違いなくF#のNUnitはかなり奇妙に見えますが、それ以外に、何か他のものを使用することをお勧めする特定の問題を知っていますか?
Mathias

1
「かなり奇妙に見える」ことは、通常、より良いものを見つけるための説得力のある理由だと思います。奇妙に見えることは読みにくいことを意味し、読みにくいことはバグを意味します。(「奇妙に見える」は「新しくて見慣れない」と完全に異なると想定しています-見慣れないものは馴染みがあり、奇数は変わったままになります。)
James Moore

1
正直に言うと(私の応答で述べたように)、まだFSUnitを使用していませんが、F#でNUnitを使用するのは非常に困難であることを読みました。そうでない場合は申し訳ありません。
ShdNx

4
明確にするために、FsUnitを使用する場合は、TestFixturesとTestメンバーが引き続き存在します。ないのは標準のAssert.X呼び出しです。FsUnitは、NUnitのこの部分のラッパーを提供するだけで、F#言語でより快適になります。
レイバーナガス

1

パーティーには少し遅れましたが、マティアスをF#に迎えて(決して遅くないよりはましです;))、Expectoを気に入っていただけるようにお願いします。

Expectoには、次のような機能があります。

  • F#構文全体、値としてテスト。プレーンなF#を記述してテストを生成する
  • 組み込みのExpectモジュール、またはアサーションにはUnquoteなどの外部ライブラリを使用します
  • デフォルトの並行テスト
  • HopacコードまたはAsyncコードをテストします。Expectoは全体的に非同期です
  • Logary Facadeを介したプラグ可能なログとメトリック。ビルドシステム用のアダプターを簡単に作成するか、テストの実行時間のInfluxDB + Grafanaダッシュボードを構築するためのタイミングメカニズムを使用する
  • BenchmarkDotNetの組み込みサポート
  • FsCheckのサポートを組み込みます。生成された/ランダムなデータでテストを構築したり、オブジェクト/アクターの状態空間の不変モデルを構築したりすることが容易になります

-

open Expecto

let tests =
  test "A simple test" {
    let subject = "Hello World"
    Expect.equal subject "Hello World" "The strings should equal"
  }

[<EntryPoint>]
let main args =
  runTestsWithArgs defaultConfig args tests

https://github.com/haf/expecto/

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.