方法
你可以訴諸使用反射來調用您的私人測試方法:你有哪些遍歷所有的私有方法中單一的公共NUnit測試方法組裝調用那些測試屬性。這種方法最大的缺點是你一次只能看到一種失敗的測試方法(但也許你可以看看像使用參數化測試來解決這個問題的創意)。
例
Program.fsi
namespace MyNs
module Program =
val visibleMethod: int -> int
Program.fs
namespace MyNs
open NUnit.Framework
module Program =
let implMethod1 x y =
x + y
[<Test>]
let testImpleMethod1() =
Assert.AreEqual(implMethod1 1 1, 2)
let implMethod2 x y z =
x + y + z
[<Test>]
let testImpleMethod2() =
Assert.AreEqual(implMethod2 1 1 1, 3)
let implMethod3 x y z r =
x + y + z + r
[<Test>]
let testImpleMethod3() =
Assert.AreEqual(implMethod3 1 1 1 1, -1)
let implMethod4 x y z r s =
x + y + z + r + s
[<Test>]
let testImpleMethod4() =
Assert.AreEqual(implMethod4 1 1 1 1 1, 5)
let visibleMethod x =
implMethod1 x x
+ implMethod2 x x x
+ implMethod3 x x x x
TestProxy。FS(實施我們的 「辦法」)
module TestProxy
open NUnit.Framework
[<Test>]
let run() =
///we only want static (i.e. let bound functions of a module),
///non-public methods (exclude any public methods, including this method,
///since those will not be skipped by nunit)
let bindingFlags = System.Reflection.BindingFlags.Static ||| System.Reflection.BindingFlags.NonPublic
///returns true if the given obj is of type TestAttribute, the attribute used for marking nunit test methods
let isTestAttr (attr:obj) =
match attr with
| :? NUnit.Framework.TestAttribute -> true
| _ -> false
let assm = System.Reflection.Assembly.GetExecutingAssembly()
let tys = assm.GetTypes()
let mutable count = 0
for ty in tys do
let methods = ty.GetMethods(bindingFlags)
for mi in methods do
let attrs = mi.GetCustomAttributes(false)
if attrs |> Array.exists isTestAttr then
//using stdout w/ flush instead of printf to ensure messages printed to screen in sequence
stdout.Write(sprintf "running test `%s`..." mi.Name)
stdout.Flush()
mi.Invoke(null,null) |> ignore
stdout.WriteLine("passed")
count <- count + 1
stdout.WriteLine(sprintf "All %i tests passed." count)
示例輸出(使用TestDriven.NET)
通知我們永遠不會testImplMethod4,因爲它沒有在testImpleMethod3:
running test `testImpleMethod1`...passed
running test `testImpleMethod2`...passed
running test `testImpleMethod3`...Test 'TestProxy.run' failed: System.Reflection.TargetInvocationException : Exception has been thrown by the target of an invocation.
----> NUnit.Framework.AssertionException : Expected: 4
But was: -1
at System.RuntimeMethodHandle._InvokeMethodFast(IRuntimeMethodInfo method, Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeType typeOwner)
at System.RuntimeMethodHandle.InvokeMethodFast(IRuntimeMethodInfo method, Object target, Object[] arguments, Signature sig, MethodAttributes methodAttributes, RuntimeType typeOwner)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
C:\Users\Stephen\Documents\Visual Studio 2010\Projects\FsOverflow\FsOverflow\TestProxy.fs(29,0): at TestProxy.run()
--AssertionException
C:\Users\Stephen\Documents\Visual Studio 2010\Projects\FsOverflow\FsOverflow\Program.fs(25,0): at MyNs.Program.testImpleMethod3()
0 passed, 1 failed, 4 skipped (see 'Task List'), took 0.41 seconds (NUnit 2.5.10).
您是否嘗試過使用InternalsVisibleTo? http://devlicio.us/blogs/derik_whittaker/archive/2007/04/09/internalsvisibleto-testing-internal-methods-in-net-2-0.aspx –
我認爲我的問題有點不同。我已經可以編譯測試了。但是,如果我不從模塊中導出它們,我無法運行它們。如果我能說出所有的內部函數都可以被NUnit訪問,我想這個屬性會有所幫助。但我不知道該從哪開始,也不知道 - 谷歌。將測試移動到不同的文件後,我顯然可以使用該屬性,但這是一種更糟糕的惡果。我將它們用作可執行文檔,因此它們確實需要接近代碼。非常感謝您的回覆。 – user1002059
如果編譯,它應該運行。除非你碰巧在與實際代碼相同的程序集中進行測試,或者類似的東西。 –