【发布时间】:2017-10-30 04:14:34
【问题描述】:
我目前正在学习 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
【问题讨论】:
-
这不是异常,是编译器错误。
-
这里提示一下:
tests的类型是什么? -
你说的没错,但我换个说法。有没有办法编译这些错误?该错误应该发生,但我希望能够执行带有这些错误的程序。测试的类型是一个包含元组和子数组的数组。
-
您试图对原始列表过于聪明。这是一个编译错误,所以很明显你不能用它编译。并在
["hello"]行出现编译错误。这意味着无论您在程序的其余部分做什么,此列表都不是有效的 F# 代码。您当然可以捕获无效输入,对其进行测试等。您甚至可以使用 xUnit 或 Expecto 等测试库测试是否在无效输入上抛出正确的异常。但首先,将你的清单分成好清单和坏清单。可能你会想要 FsCheck 之类的东西来进行基于属性的测试。 -
@s952163 感谢您的详尽回答。所以我需要能够提前区分有效输入和无效输入,并据此正确处理。而不是将有效输入与无效输入放在一起并尝试一次性解析所有内容。我理解正确吗?
标签: error-handling f#