2012-01-27 10 views
5

Me gustaría informar sobre ellos antes de que se ejecuten, y tengo la opción de ejecutar pruebas individuales a través de scripts de shell sin administrar categorías. Tenemos un código no administrado que puede dejar el proceso en mal estado y, a veces, nos complace ejecutar cada prueba individualmente por cada ejecución de nunit-console.¿Puede nunit-console enumerar todos los nombres de prueba en un accesorio de prueba?

+0

'nunit-consola MyAssembly.dll/labels' mostrará todas las pruebas, ya que correr, pero estoy en lo cierto al pensar que lo que desea es conseguir que enumere de antemano y luego solicite al usuario (o agréguelos a un archivo '/ runlist =')? ¿Y cuál es la razón fundamental para no querer usar categorías? – ClickRick

+0

Los queremos con anticipación, correcto. La clave aquí fue que queríamos ejecutarlos uno a la vez, es decir, ejecutar nunit-console una y otra vez, una vez por prueba. Cambiamos los componentes de manera que ya no necesitamos hacer esto, pero todavía estoy sorprendido de no ver una respuesta al respecto. –

+0

Si esto todavía era un problema para ti, estaría tentado de utilizar su clase EventListener (ver http://imistaken.blogspot.co.uk/2009/03/nunit-extensions-adding-logic-at-run .html para ver un ejemplo) para ver si puede obtener la lista de esa manera, pero eso dependería de poder suprimir la ejecución real de las pruebas en ese punto, y eso es algo que no sabría sin probarlo. – ClickRick

Respuesta

0

nunit-console todavía no parece ser compatible con esta opción. Sin embargo, es bastante sencillo obtener una lista de los casos de prueba usando la reflexión. En un nivel muy básico, desea una lista de todos los public métodos de cualquier public class con los atributos apropiados [Test]/[TestFixture]. Dependiendo de cómo estén estructuradas sus pruebas, es posible que deba realizar un filtrado adicional, como eliminar las pruebas marcadas con los atributos [Ignore] o considerar los métodos de prueba en las clases base.

En un nivel básico, el código sería algo como esto:

// Load the assembly containing your fixtures 
Assembly a = Assembly.LoadFrom(assemblyName); 

// Foreach public class that is a TestFixture and not Ignored 
foreach (var c in a.GetTypes() 
        .Where(x=>x.IsPublic 
        && (x.GetCustomAttributes(typeof(NUnit.Framework.TestFixtureAttribute)).Count() > 0) 
        && (x.GetCustomAttributes(typeof(NUnit.Framework.IgnoreAttribute)).Count() ==0))) 
{ 
    // For each public method that is a Test and not Ignored 
    foreach (var m in c.GetMethods() 
         .Where(x=>x.IsPublic 
         && (x.GetCustomAttributes(typeof(NUnit.Framework.TestAttribute)).Count() > 0) 
         && (x.GetCustomAttributes(typeof(NUnit.Framework.IgnoreAttribute)).Count() ==0))) 
    { 
     // Print out the test name 
     Console.WriteLine("{0}.{1}", c.ToString(), m.Name); 
     // Alternately, print out the command line to run test case using nunit-console 
     //Console.WriteLine("nunit-console /run:{0}.{1} {2}", c.ToString(), m.Name, assemblyName); 
    } 
} 

Es obvio que sería capaz de simplificar esto un poco si sólo quería los métodos de ensayo a partir de un determinado TestFixture.

Como se ha dicho en los comentarios, esto se vuelve un poco más complicado si necesita prestar atención a otros atributos de NUnit, como TestCase y TestCaseSource. Modifiqué el código a continuación para respaldar algunas de las funciones de estos atributos.

static void PrintTestNames(string assemblyName) { 
    Assembly assembly = Assembly.LoadFrom(assemblyName); 

    foreach (var fixture in assembly.GetTypes().Where(x => x.IsPublic 
             && (x.GetCustomAttributes(typeof(TestFixtureAttribute)).Count() > 0) 
             && (x.GetCustomAttributes(typeof(IgnoreAttribute)).Count() == 0))) { 
     foreach(var method in fixture.GetMethods().Where(x=>x.IsPublic 
      && (x.GetCustomAttributes(typeof(IgnoreAttribute)).Count() == 0) 
      && ((x.GetCustomAttributes(typeof(TestAttribute)).Count() > 0) 
       || (x.GetCustomAttributes(typeof(TestCaseAttribute)).Count() > 0) 
       || (x.GetCustomAttributes(typeof(TestCaseSourceAttribute)).Count() > 0)) 
      )) { 
      var testAttributes = method.GetCustomAttributes(typeof(TestAttribute)) as IEnumerable<TestAttribute>; 
      var caseAttributes = method.GetCustomAttributes(typeof(TestCaseAttribute)) as IEnumerable<TestCaseAttribute>; 
      var caseSourceAttributes = method.GetCustomAttributes(typeof(TestCaseSourceAttribute)) as IEnumerable<TestCaseSourceAttribute>; 

      if (caseAttributes.Count() > 0) { 
       foreach(var testCase in caseAttributes) { 
        if (!string.IsNullOrEmpty(testCase.TestName)) { 
         PrintTestName(fixture.ToString(), testCase.TestName); 
        } 
        else { 
         string arguments = ExtractArguments(testCase.Arguments); 
         PrintTestName(fixture.ToString(), method.Name + arguments); 
        } 
       } 
      } 
      else if (caseSourceAttributes.Count() > 0) { 
       foreach (var testCase in caseSourceAttributes) { 
        var sourceName = testCase.SourceName; 
        if (!string.IsNullOrEmpty(sourceName)) { 
         var staticMember = fixture.GetField(sourceName, BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public); 
         var instanceMember = fixture.GetField(sourceName, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); 
         var staticMethodMember = fixture.GetMethod(sourceName, BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public); 
         var instanceMethodMember = fixture.GetMethod(sourceName, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); 
         var staticPropMember = fixture.GetProperty(sourceName, BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public); 
         var instancePropMember = fixture.GetProperty(sourceName, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); 


         IEnumerable memberValues; 

         if (null != staticMember) { 
          memberValues = staticMember.GetValue(null) as IEnumerable; 
         } 
         else if (null != instanceMember) { 
          var instance = Activator.CreateInstance(fixture); 
          memberValues = instanceMember.GetValue(instance) as IEnumerable; 
         } else if(null != staticMethodMember) { 
          memberValues = staticMethodMember.Invoke(null,new object [0]) as IEnumerable; 
         } 
         else if (null != instanceMethodMember) { 
          var instance = Activator.CreateInstance(fixture); 
          memberValues = instanceMethodMember.Invoke(instance, new object[0]) as IEnumerable; 
         } 
         else if (null != staticPropMember) { 
          memberValues = staticPropMember.GetValue(null) as IEnumerable; 
         } 
         else if (null != instancePropMember) { 
          var instance = Activator.CreateInstance(fixture); 
          memberValues = instancePropMember.GetValue(instance) as IEnumerable; 
         } 
         else { 
          Console.WriteLine("*** Ooops...Looks like I don't know how to get {0} for fixture {1}", sourceName, fixture.ToString()); 
          continue; 
         } 

         foreach (var memberValue in memberValues) { 
          if (null != memberValue as IEnumerable) { 
           PrintTestName(fixture.ToString(), method.Name + ExtractArguments(memberValue as IEnumerable)); 
          } 
          else { 
           PrintTestName(fixture.ToString(), method.Name + "(" + memberValue.ToString() + ")"); 
          } 
         } 
        } else { 
         Console.WriteLine("*** Ooops...Looks like I don't know how to handle test {0} for fixture {1}", method.Name, fixture.ToString()); 
        } 
       } 
      } 
      else { 
       PrintTestName(fixture.ToString(), method.Name); 
      } 
     } 
    } 
} 

static string ExtractArguments(IEnumerable arguments) { 
    string caseArgs = "("; 
    bool first = true; 
    foreach (var arg in arguments) { 
     if (first) first = false; 
     else caseArgs += ","; 
     caseArgs += Convert.ToString(arg); 
    } 
    return caseArgs + ")"; 
} 

static void PrintTestName(string fixture, string testName) { 
    Console.WriteLine("{0}.{1}", fixture, testName); 
    //Console.WriteLine("nunit-console /run:{0}.{1} {2}", fixture, testName, assemblyName); 
} 

Si se mira a través del código anterior, se puede notar que he manejado funcionalidad donde el TestCaseSource para las pruebas es una cadena con el nombre del/método/campo de la propiedad. También notará que aunque hay más código, sigue siendo un código bastante sencillo, por lo que podría extenderse fácilmente si estuviera usando una versión alternativa de TestCaseSource, o si hay otros atributos de NUnit que está utilizando que yo no han atendido

También sería bastante fácil agregar un contador a lo anterior para que tenga un nivel de comodidad con el que se imprimió la misma cantidad de pruebas que el número de pruebas que ejecutaría nunit-console.

+0

Esto obtendría lo básico, pero si usa algunos de los atributos más avanzados que pueden generar automáticamente pruebas de diferentes entradas, ¡entonces no tiene suerte! –

+0

@SebastianGood He agregado soporte para TestCase + algunas permutaciones de TestCaseSource a las anteriores. Extender el código para manejar otras opciones de TestCaseSource (u otros atributos que no he encontrado) debería ser sencillo si está utilizando otras alternativas, sin embargo lo dejaré como * ejercicio para el lector *. – forsvarir

+0

También debe tener en cuenta los casos en que las clases de prueba heredan de clases base (abstractas) con estos atributos. Entonces el recuento debe ajustarse para ejecutar los mismos métodos de prueba varias veces, – WebDancer

Cuestiones relacionadas