2012-03-12 16 views
17

¿Cómo obtener el nombre de la prueba de unidad de la prueba dentro de la unidad?¿Cómo obtener el nombre del método de prueba de la unidad en tiempo de ejecución dentro de la prueba unitaria?

Tengo el siguiente método dentro de una clase BaseTestFixture:

public string GetCallerMethodName() 
{ 
    var stackTrace = new StackTrace(); 
    StackFrame stackFrame = stackTrace.GetFrame(1); 
    MethodBase methodBase = stackFrame.GetMethod(); 
    return methodBase.Name; 
} 

Mi clase de dispositivo de pruebas hereda de la base de uno:

[TestFixture] 
public class WhenRegisteringUser : BaseTestFixture 
{ 
} 

y tengo la prueba del sistema a continuación:

[Test] 
public void ShouldRegisterThenVerifyEmailThenSignInSuccessfully_WithValidUsersAndSites() 
{ 
    string testMethodName = this.GetCallerMethodName(); 
    // 
} 

Cuando ejecuto esto desde Visual Studio, devuelve el nombre de mi método de prueba como se esperaba.

Cuando esto se ejecuta por TeamCity, en su lugar se devuelve _InvokeMethodFast() que parece ser un método que TeamCity genera en tiempo de ejecución para su propio uso.

Entonces, ¿cómo podría obtener el nombre del método de prueba en tiempo de ejecución?

+0

¿Está compilado en modo de lanzamiento incluso cuando se inicia desde VS? –

+1

¿Obtiene la información de conjunto para cada método llamado en la pila? Tal vez podrías subir la pila buscando tu ensamblaje de prueba. –

+0

Una stacktrace ayudaría, para ver si el nombre del método real aparece más arriba en la pila de llamadas. –

Respuesta

17

Si está utilizando NUnit 2.5.7/2.6 puede utilizar el TestContext class:

[Test] 
public void ShouldRegisterThenVerifyEmailThenSignInSuccessfully() 
{ 
    string testMethodName = TestContext.CurrentContext.Test.Name; 
} 
+1

Característica agradable :) –

+1

MSTest también expone esta información en su TestContext también – bryanbcook

+0

Ahora funciona bien desde TeamCity, pero cuando lo ejecuto localmente desde Visual Studio, arroja una excepción que indica que un objeto no se ha inicializado. Entonces, ¿cómo hacer que funcione desde Visual Studio? –

7

Si no está utilizando NUnit puede recorrer a la pila y encontrar el método de ensayo:

foreach(var stackFrame in stackTrace.GetFrames()) { 
    MethodBase methodBase = stackFrame.GetMethod(); 
    Object[] attributes = methodBase.GetCustomAttributes(typeof(TestAttribute), false); 
    if (attributes.Length >= 1) { 
    return methodBase.Name; 
    } 
} 
return "Not called from a test method"; 
+0

¿Sabes si esto solo funciona en MSTest? ¿O funcionará tanto en NUnit como en MSTest? – Yoiku

+0

Debería cambiar la anotación para que sea la anotación correcta para el marco de prueba. Sin embargo, como señala la respuesta aceptada, NUnit tiene un TestContext que es una mejor solución. –

+0

Gracias por la respuesta, estaba preguntando porque estoy tratando de construir un FW y no quiero restringirme a NUnit o MSTest. Así que creo que lo que haré es pasar la pila de abajo hacia arriba hasta que encuentre un método cuyo espacio de nombres no sea de Microsoft o System. Lo he intentado y obtuve buenos resultados con MSTest y llamé al FW desde un programa de línea de comando (obtuve el método principal). – Yoiku

5

Gracias chicos; He utilizado un enfoque combinado de modo que ahora trabaja en todos los ambientes:

public string GetTestMethodName() 
{ 
    try 
    { 
     // for when it runs via TeamCity 
     return TestContext.CurrentContext.Test.Name; 
    } 
    catch 
    { 
     // for when it runs via Visual Studio locally 
     var stackTrace = new StackTrace(); 
     foreach (var stackFrame in stackTrace.GetFrames()) 
     { 
      MethodBase methodBase = stackFrame.GetMethod(); 
      Object[] attributes = methodBase.GetCustomAttributes(
             typeof(TestAttribute), false); 
      if (attributes.Length >= 1) 
      { 
       return methodBase.Name; 
      } 
     } 
     return "Not called from a test method"; 
    } 
} 
+0

, tenga en cuenta que en las compilaciones de Release esto a veces no funciona; el método de prueba puede estar inline y no podrá ver el TestAttribute – imaximchuk

0

Si no está utilizando Nunit o cualquier otra herramienta de terceros. no obtendrá TestAttribute.

Así que puede hacer esto para obtener el nombre del Método de prueba. Use TestMethodAttribute insted de TestAttribute.

public string GetTestMethodName() 
    { 
      // for when it runs via Visual Studio locally 
      var stackTrace = new StackTrace(); 
      foreach (var stackFrame in stackTrace.GetFrames()) 
      { 
       MethodBase methodBase = stackFrame.GetMethod(); 
       Object[] attributes = methodBase.GetCustomAttributes(typeof(TestMethodAttribute), false); 
       if (attributes.Length >= 1) 
       { 
        return methodBase.Name; 
       } 
      } 
      return "Not called from a test method"; 
    } 
11

Cuando se utiliza Visual Studio para ejecutar las pruebas si se agrega un TestContext property en su clase de prueba se puede obtener esta información fácilmente.

[TestClass] 
public class MyTestClass 
{ 
    public TestContext TestContext { get; set; } 

    [TestInitialize] 
    public void setup() 
    { 
     logger.Info(" SETUP " + TestContext.TestName); 
     // .... // 
    } 
} 
Cuestiones relacionadas