2017-10-29 35 views
1

私は現在F#のコースを受けています。私は代入に関して書き直した関数のブラックボックステストに取り組んでいます。このテストでは、間違った形式(intが必要な関数に文字列を与える)を入力して関数をテストすることになっています。例外を捕捉して終了する代わりにテストを実行できるようにしたいと思います。これをf#でどのように達成できますか?テストのキャッチ例外

これは私がこれまでにしようとしているものです:

#r "msort.dll" 

let tests = [ 
    ("Sorted lists", [ 
     ([1;2;3;4;5;6;7;8;9;10], [1;2;3;4;5;6;7;8;9;10]); 
     ([5000;6000;7000;8000;9000;10000;11000;12000;13000;14000], [5000;6000;7000;8000;9000;10000;11000;12000;13000;14000]); 
     ([10;9;8;7;6;5;4;3;2;1], [1;2;3;4;5;6;7;8;9;10]); 
     ([14000;13000;12000;11000;10000;9000;8000;7000;6000;5000], [5000;6000;7000;8000;9000;10000;11000;12000;13000;14000]); 
    ]) 
    ("Wrong input formats", [ 
     ([], []); 
     (["hello"], []); 
    ]) 
] 

printfn "Black-box testing of Merge Sort" 
for i = 0 to tests.Length-1 do 
    let (testName, testSet) = tests.[i] 
    printfn "%d. %s" (i+1) testName 
    for j = 0 to testSet.Length - 1 do 
     try 
      let (input, expected) = testSet.[j] 
      let result = (msort.sort input) 
      printfn "test %d - %b" (j+1) (result = expected) 
     with 
      | _ as ex -> printfn "error occured" 

を、私は、文字列を印刷した後、私はワイルドカードで任意の例外をキャッチし、テストを続けることができると考えていた「エラーが発生した」が、プログラムは単純に閉じ例外:

error FS0001: This expression was expected to have type 
    'int'  
but here has type 
    'string'  

私がテストしてい関数は、パターンマッチングを使用するようにリライトマージソートのバージョンです。コメントで述べたようにここでは関数のコードは、それは「msort.dll」

module msort 

let rec merge (xs:int list) (ys:int list): int list = 
    match xs with 
    | [] -> ys     // if xs is empty return ys 
    | xs when ys = [] -> xs  // if ys is empty return xs 
    | _ ->      // if non of the above is true 
     let x = List.head xs 
     let y = List.head ys 
     let xs = List.tail xs 
     let ys = List.tail ys 
     match x with 
     | x when x <= y -> x :: merge xs (y::ys) // if x < y merge x 
     | x when x > y -> y :: merge (x::xs) ys // else merge y 
     | _ -> []        // otherwise something is wrong, return empty array 

let rec sort (xs:int list): int list = 
    let sz = List.length xs 
    if sz < 2 then xs   // if the length of sz is under 2 we cannot split and so we return xs 
    else let n = sz/2 
     let ys = xs.[0..n-1] // ys = the first half of the input array 
     let zs = xs.[n..sz-1] // zs = the second half of the input array 
     in merge (sort ys) (sort zs) // call merge with each half 
+1

これは例外ではなく、コンパイラエラーです。 –

+2

ここにヒントがあります: 'tests'のタイプは何ですか? –

+1

あなたは確かですが、私は言い換えることができます。これらのエラーでコンパイルする方法はありますか?エラーが発生するはずですが、私はこれらのエラーでプログラムを実行できるようにします。テストのタイプはタプルとサブアレイを持つ配列です。 – n0rd

答えて

3

にコンパイルされ、無効の入力を使用してsort関数を呼び出すしようとする書き込みテストのための理由はありませんtype - F#コンパイラはそのようなケースを静的にチェックし、それらをブロックします。したがって、整数のリストが必要な場合は誰も関数を文字列のリストで呼び出すことはできません。

静的に型が安全でない関数があったとしても、何をしようとしているのかは分かりません。たとえば、すべての入力をソートする前に整数に変換するunsafeSortがあるとします。 System.Convertを使用し、キャストする場合は:?>のような関数を定義できます。

これは非常に醜いと安全でないと、あなたは実際にこれを行うべきではありません、それは静的な型でF#を使用しての目的に反していますが、技術的にそれを行うことができますので:

let unsafeSort list = 
    msort.sort [ for v in list -> System.Convert.ChangeType(v, typeof<int>) :?> int ] 
    |> List.map box 

その後、あなたはのためのデータを表すことができ

let tests = [ 
    ("Sorted lists", [ 
     ([box 1;box 3;box 2], [box 1;box 2;box 3]); 
    ]) 
    ("Wrong input formats", [ 
     (["hello"], []); 
    ]) 
] 

そして、もう一つのパスと一つのエラー報告します以下を使用してテストを実行している:

を使用すると、文字列と整数をミックスできるようになるオブジェクトとして、あなたのテスト、

前述のように、これは技術的な側面からの質問に答えることです。これを行うことは非常に悪い考えです。