Enfoque
Se podría recurrir al uso de la reflexión para invocar sus métodos de prueba privados: usted tendría un único método público de prueba NUnit los bucles que sobre todos los métodos privados en el montaje de la invocación de los que tienen el atributo de prueba. El gran inconveniente de este enfoque es que solo puedes ver un método de prueba fallido a la vez (pero tal vez podrías buscar algo creativo como usar pruebas parametrizadas para solucionarlo).
Ejemplo
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 (aplicación de nuestra "estrategia")
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)
Ejemplo de salida (usando TestDriven.NET)
Aviso nunca llegamos a testImplMethod4 puesto que falla en 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).
¿Ha intentado utilizar InternalsVisibleTo? http://devlicio.us/blogs/derik_whittaker/archive/2007/04/09/internalsvisibleto-testing-internal-methods-in-net-2-0.aspx –
Creo que mi problema es un poco diferente. Ya puedo compilar las pruebas muy bien. Sin embargo, no puedo ejecutarlos si no los exporto desde el módulo. Supongo que el atributo me ayudaría si pudiera decir que NUnit tiene acceso a todos los internos. Pero no tengo idea de dónde comenzar con eso, y tampoco, parece, lo hace Google. Obviamente podría usar el atributo después de mover las pruebas a un archivo diferente, pero ese es un mal peor. Los uso como documentación ejecutable, por lo que realmente deben estar cerca del código. Muchas gracias por la respuesta. – user1002059
Si se compila, debería ejecutarse. A menos que tenga las pruebas en el mismo ensamblaje que el código real, o algo así. –