我目前正在接受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
答案 0 :(得分:3)
正如评论中所提到的,没有理由编写试图用无效类型的输入调用你的<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<application xmlns="http://ns.adobe.com/air/application/2.5">
<id>author.YourFileName</id>
<versionNumber>1.0.0</versionNumber>
<versionLabel/>
<filename>YourFileName</filename>
<description/>
<!-- To localize the description, use the following format for the description element.<description><text xml:lang="en">English App description goes here</text><text xml:lang="fr">French App description goes here</text><text xml:lang="ja">Japanese App description goes here</text></description>-->
<name>YourFileName</name>
<!-- To localize the name, use the following format for the name element.<name><text xml:lang="en">English App name goes here</text><text xml:lang="fr">French App name goes here</text><text xml:lang="ja">Japanese App name goes here</text></name>-->
<copyright/>
<initialWindow>
<content>YourFileName.swf</content>
<systemChrome>standard</systemChrome>
<transparent>false</transparent>
<visible>true</visible>
<fullScreen>true</fullScreen>
<renderMode>gpu</renderMode>
<autoOrients>true</autoOrients>
</initialWindow>
<icon>
<image72x72>My_Assets/icons/YourFileName_icon_72.png</image72x72>
<image48x48>My_Assets/icons/YourFileName_icon_48.png</image48x48>
<image36x36>My_Assets/icons/YourFileName_icon_36.png</image36x36>
</icon>
<customUpdateUI>false</customUpdateUI>
<allowBrowserInvocation>false</allowBrowserInvocation>
<android>
<manifestAdditions>
<![CDATA[<manifest>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
</manifest>]]>
</manifestAdditions>
</android>
</application>
函数的测试--F#编译器将静态检查这些情况并阻止它们,所以没有人如果它需要一个整数列表,可以用一个字符串列表调用该函数。
如果你有一个非静态类型安全的函数,那么你想要做的事情才会有意义。例如,如果您有sort
在排序之前将所有输入转换为整数。您可以使用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"], []);
])
]
如前所述,这只是从技术方面回答你的问题 - 这是一个非常糟糕的主意。