De forma predeterminada, las pruebas nunit se ejecutan alfabéticamente. ¿Alguien sabe de alguna forma de establecer la orden de ejecución? ¿Existe un atributo para esto?
De forma predeterminada, las pruebas nunit se ejecutan alfabéticamente. ¿Alguien sabe de alguna forma de establecer la orden de ejecución? ¿Existe un atributo para esto?
Respuestas:
Las pruebas unitarias deben poder ejecutarse de forma independiente y autónoma. Si cumplen este criterio, el orden no importa.
Sin embargo, hay ocasiones en las que querrá ejecutar ciertas pruebas primero. Un ejemplo típico es una situación de integración continua donde algunas pruebas duran más que otras. Usamos el atributo de categoría para poder ejecutar las pruebas que usan burlarse antes de las pruebas que usan la base de datos.
es decir, ponga esto al comienzo de sus pruebas rápidas
[Category("QuickTests")]
Cuando tenga pruebas que dependan de ciertas condiciones ambientales, considere los atributos TestFixtureSetUp y TestFixtureTearDown , que le permiten marcar métodos para ejecutar antes y después de sus pruebas.
Solo quiero señalar que, si bien la mayoría de los que respondieron asumieron que se trataba de pruebas unitarias, la pregunta no especificó que lo fueran.
nUnit es una gran herramienta que se puede utilizar para una variedad de situaciones de prueba. Puedo ver las razones apropiadas para querer controlar el orden de prueba.
En esas situaciones he tenido que recurrir a incorporar una orden de ejecución en el nombre de la prueba. Sería fantástico poder especificar el orden de ejecución mediante un atributo.
001_first_test
002_second_test
y así sucesivamente?
NUnit 3.2.0 agregó un OrderAttribute
, ver:
https://github.com/nunit/docs/wiki/Order-Attribute
Ejemplo:
public class MyFixture
{
[Test, Order(1)]
public void TestA() { ... }
[Test, Order(2)]
public void TestB() { ... }
[Test]
public void TestC() { ... }
}
Querer que las pruebas se ejecuten en un orden específico no significa que las pruebas sean dependientes entre sí; estoy trabajando en un proyecto TDD en este momento y, siendo un buen TDDer, me he burlado / eliminado de todo, pero haría sería más legible si pudiera especificar el orden en que se muestran los resultados de las pruebas , temáticamente en lugar de alfabéticamente. Hasta ahora, lo único que se me ocurre es anteponer a_ b_ c_ a las clases, las clases, los espacios de nombres y los métodos. (No es bueno) Creo que un atributo [TestOrderAttribute] sería bueno, no seguido estrictamente por el marco, sino una pista para que podamos lograr esto
Independientemente de si las pruebas dependen del orden o no ... algunos de nosotros solo queremos controlar todo, de manera ordenada.
Las pruebas unitarias generalmente se crean en orden de complejidad. Entonces, ¿por qué no deberían ejecutarse también en orden de complejidad o en el orden en que fueron creados?
Personalmente, me gusta ver las pruebas ejecutadas en el orden en que las creé. En TDD, cada prueba sucesiva naturalmente será más compleja y llevará más tiempo ejecutarla. Preferiría ver que la prueba más simple falla primero, ya que será un mejor indicador de la causa de la falla.
Pero también puedo ver el beneficio de ejecutarlos en orden aleatorio, especialmente si desea probar que sus pruebas no tienen dependencias de otras pruebas. ¿Qué le parece agregar una opción para probar a los corredores a "Ejecutar pruebas al azar hasta que se detenga"?
Estoy probando con Selenium en un sitio web bastante complejo y todo el conjunto de pruebas puede ejecutarse durante más de media hora, y aún no estoy cerca de cubrir toda la aplicación. Si tengo que asegurarme de que todos los formularios anteriores se completen correctamente para cada prueba, esto agrega una gran cantidad de tiempo, no solo una pequeña cantidad de tiempo, a la prueba general. Si hay demasiada sobrecarga para ejecutar las pruebas, las personas no las ejecutarán con la frecuencia que deberían.
Entonces, los pongo en orden y dependo de pruebas anteriores para tener cuadros de texto y demás completados. Utilizo Assert.Ignore () cuando las condiciones previas no son válidas, pero necesito que se ejecuten en orden.
Realmente me gusta la respuesta anterior.
Lo cambié un poco para poder usar un atributo para establecer el rango de orden:
namespace SmiMobile.Web.Selenium.Tests
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using NUnit.Framework;
public class OrderedTestAttribute : Attribute
{
public int Order { get; set; }
public OrderedTestAttribute(int order)
{
Order = order;
}
}
public class TestStructure
{
public Action Test;
}
class Int
{
public int I;
}
[TestFixture]
public class ControllingTestOrder
{
private static readonly Int MyInt = new Int();
[TestFixtureSetUp]
public void SetUp()
{
MyInt.I = 0;
}
[OrderedTest(0)]
public void Test0()
{
Console.WriteLine("This is test zero");
Assert.That(MyInt.I, Is.EqualTo(0));
}
[OrderedTest(2)]
public void ATest0()
{
Console.WriteLine("This is test two");
MyInt.I++; Assert.That(MyInt.I, Is.EqualTo(2));
}
[OrderedTest(1)]
public void BTest0()
{
Console.WriteLine("This is test one");
MyInt.I++; Assert.That(MyInt.I, Is.EqualTo(1));
}
[OrderedTest(3)]
public void AAA()
{
Console.WriteLine("This is test three");
MyInt.I++; Assert.That(MyInt.I, Is.EqualTo(3));
}
[TestCaseSource(sourceName: "TestSource")]
public void MyTest(TestStructure test)
{
test.Test();
}
public IEnumerable<TestCaseData> TestSource
{
get
{
var assembly =Assembly.GetExecutingAssembly();
Dictionary<int, List<MethodInfo>> methods = assembly
.GetTypes()
.SelectMany(x => x.GetMethods())
.Where(y => y.GetCustomAttributes().OfType<OrderedTestAttribute>().Any())
.GroupBy(z => z.GetCustomAttribute<OrderedTestAttribute>().Order)
.ToDictionary(gdc => gdc.Key, gdc => gdc.ToList());
foreach (var order in methods.Keys.OrderBy(x => x))
{
foreach (var methodInfo in methods[order])
{
MethodInfo info = methodInfo;
yield return new TestCaseData(
new TestStructure
{
Test = () =>
{
object classInstance = Activator.CreateInstance(info.DeclaringType, null);
info.Invoke(classInstance, null);
}
}).SetName(methodInfo.Name);
}
}
}
}
}
}
OrderedTest
ya no es compatible con NUnit 3.
Sé que esta es una publicación relativamente antigua, pero aquí hay otra forma de mantener su prueba en orden SIN hacer que los nombres de la prueba sean incómodos. Al usar el atributo TestCaseSource y hacer que el objeto que pasa tenga un delegado (Acción), no solo puede controlar totalmente el orden, sino también nombrar la prueba como es.
Esto funciona porque, de acuerdo con la documentación, los elementos de la colección devueltos desde la fuente de prueba siempre se ejecutarán en el orden en que se enumeran.
Aquí hay una demostración de una presentación que daré mañana:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
namespace NUnitTest
{
public class TestStructure
{
public Action Test;
}
class Int
{
public int I;
}
[TestFixture]
public class ControllingTestOrder
{
private static readonly Int MyInt= new Int();
[TestFixtureSetUp]
public void SetUp()
{
MyInt.I = 0;
}
[TestCaseSource(sourceName: "TestSource")]
public void MyTest(TestStructure test)
{
test.Test();
}
public IEnumerable<TestCaseData> TestSource
{
get
{
yield return new TestCaseData(
new TestStructure
{
Test = () =>
{
Console.WriteLine("This is test one");
MyInt.I++; Assert.That(MyInt.I, Is.EqualTo(1));
}
}).SetName(@"Test One");
yield return new TestCaseData(
new TestStructure
{
Test = () =>
{
Console.WriteLine("This is test two");
MyInt.I++; Assert.That(MyInt.I, Is.EqualTo(2));
}
}).SetName(@"Test Two");
yield return new TestCaseData(
new TestStructure
{
Test = () =>
{
Console.WriteLine("This is test three");
MyInt.I++; Assert.That(MyInt.I, Is.EqualTo(3));
}
}).SetName(@"Test Three");
}
}
}
}
TestCaseSource
como una forma de ejecutar pruebas ordenadas es un golpe de genialidad. Bien hecho. He adoptado este enfoque junto con el siguiente y agregué algunas modificaciones adicionales para que sea más fácil de usar. Vea los enlaces en mi respuesta para obtener información adicional, ¡pero la idea subyacente proviene de esta gran respuesta!
TestCaseSource
debe ser estática, lo que impide el uso de patrones. Gorrón.
TestCaseSource
debe ser un objeto estático en NUnit 3, o las pruebas no se ejecutarán. Y no puede crear objetos dinámicos dentro de un objeto estático. Por eso no funcionará en el v. 3.
Estoy trabajando con casos de prueba de IU de extremo a extremo de Selenium WebDriver escritos en C #, que se ejecutan usando el marco NUnit. (No casos unitarios como tales)
Estas pruebas de IU ciertamente dependen del orden de ejecución, ya que otras pruebas deben agregar algunos datos como condición previa. (No es factible seguir los pasos en todas las pruebas)
Ahora, después de agregar el décimo caso de prueba, veo que NUnit quiere ejecutarse en este orden: Test_1 Test_10 Test_2 Test_3 ..
Así que supongo que también tengo que alfabetizar los nombres de los casos de prueba por ahora, pero sería bueno tener esta pequeña característica de controlar el orden de ejecución agregada a NUnit.
Por lo general, la prueba unitaria debe ser independiente, pero si debe hacerlo, puede nombrar sus métodos en orden alfabético, por ejemplo:
[Test]
public void Add_Users(){}
[Test]
public void Add_UsersB(){}
[Test]
public void Process_Users(){}
o puedes hacerlo ..
private void Add_Users(){}
private void Add_UsersB(){}
[Test]
public void Process_Users()
{
Add_Users();
Add_UsersB();
// more code
}
a_
b_
t1_
, en su t2_
lugar , o confiando en caracteres finales fáciles de perder
Hay muy buenas razones para utilizar un mecanismo de pedido de prueba. La mayoría de mis propias pruebas utilizan buenas prácticas, como configuración / desmontaje. Otros requieren una gran cantidad de configuración de datos, que luego se pueden usar para probar una variedad de funciones. Hasta ahora, he usado pruebas grandes para manejar estas pruebas de integración (Selenium Webdriver). Sin embargo, creo que la publicación sugerida anteriormente en https://github.com/nunit/docs/wiki/Order-Attribute tiene mucho mérito. Aquí hay un ejemplo de por qué ordenar sería extremadamente valioso:
Este tiempo de espera de 10 minutos ralentiza el conjunto de pruebas. Cuando multiplica retrasos de almacenamiento en caché similares en una multitud de pruebas, consume mucho tiempo. Solicitar pruebas podría permitir que la configuración de datos se realice como una "Prueba" justo al comienzo de la serie de pruebas, con pruebas que dependan de la caché para que se ejecuten hacia el final de la ejecución de la prueba.
Esta pregunta es realmente antigua ahora, pero para las personas que pueden llegar a esto mediante la búsqueda, tomé las excelentes respuestas de user3275462 y PvtVandals / Rico y las agregué a un repositorio de GitHub junto con algunas de mis propias actualizaciones. También creé una publicación de blog asociada con información adicional que puede consultar para obtener más información.
Espero que esto sea útil para todos ustedes. Además, a menudo me gusta usar el atributo Categoría para diferenciar mis pruebas de integración u otras pruebas de un extremo a otro de mis pruebas unitarias reales. Otros han señalado que las pruebas unitarias no deben tener una dependencia de orden, pero otros tipos de pruebas a menudo sí, por lo que esto proporciona una buena manera de ejecutar solo la categoría de pruebas que desea y también ordenar esas pruebas de un extremo a otro.
Me sorprende que la comunidad NUnit no haya encontrado nada, así que fui a crear algo como esto yo mismo.
Actualmente estoy desarrollando una biblioteca de código abierto que le permite ordenar sus pruebas con NUnit. Puede pedir accesorios de prueba y pedir "especificaciones de prueba ordenadas" por igual.
La biblioteca ofrece las siguientes características:
La biblioteca está realmente inspirada en cómo MSTest prueba los pedidos con .orderedtest
archivos. Mire un ejemplo a continuación.
[OrderedTestFixture]
public sealed class MyOrderedTestFixture : TestOrderingSpecification {
protected override void DefineTestOrdering() {
TestFixture<Fixture1>();
OrderedTestSpecification<MyOtherOrderedTestFixture>();
TestFixture<Fixture2>();
TestFixture<Fixture3>();
}
protected override bool ContinueOnError => false; // Or true, if you want to continue even if a child test fails
}
Si está utilizando [TestCase]
, el argumento TestName
proporciona un nombre para la prueba.
Si no se especifica, se genera un nombre basado en el nombre del método y los argumentos proporcionados.
Puede controlar el orden de ejecución de la prueba como se indica a continuación:
[Test]
[TestCase("value1", TestName = "ExpressionTest_1")]
[TestCase("value2", TestName = "ExpressionTest_2")]
[TestCase("value3", TestName = "ExpressionTest_3")]
public void ExpressionTest(string v)
{
//do your stuff
}
Aquí utilicé el "ExpressionTest"
sufijo del nombre del método con un número.
Puede utilizar cualquier nombre ordenado alfabéticamente, consulte el atributo TestCase
No debe depender del orden en el que el marco de pruebas selecciona las pruebas para su ejecución. Las pruebas deben ser aisladas e independientes. En el sentido de que no deben depender de que otra prueba les prepare el escenario o limpie después de ellos. También deben producir el mismo resultado independientemente del orden de ejecución de las pruebas (para una instantánea determinada del IVU)
Busqué un poco en Google. Como de costumbre, algunas personas han recurrido a trucos furtivos (en lugar de resolver el problema subyacente de capacidad de prueba / diseño
Ver también: características de una buena prueba
En caso de usar TestCaseSource
la clave es el override string ToString
método, cómo funciona:
Suponga que tiene la clase TestCase
public class TestCase
{
public string Name { get; set; }
public int Input { get; set; }
public int Expected { get; set; }
}
Y una lista de TestCases:
private static IEnumerable<TestCase> TestSource()
{
return new List<TestCase>
{
new TestCase()
{
Name = "Test 1",
Input = 2,
Expected = 4
},
new TestCase()
{
Name = "Test 2",
Input = 4,
Expected = 16
},
new TestCase()
{
Name = "Test 3",
Input = 10,
Expected = 100
}
};
}
Ahora usémoslo con un método de prueba y veamos qué sucede:
[TestCaseSource(nameof(TestSource))]
public void MethodXTest(TestCase testCase)
{
var x = Power(testCase.Input);
x.ShouldBe(testCase.Expected);
}
Esto no se probará en orden y la salida será así:
Entonces, si agregamos override string ToString
a nuestra clase como:
public class TestCase
{
public string Name { get; set; }
public int Input { get; set; }
public int Expected { get; set; }
public override string ToString()
{
return Name;
}
}
El resultado cambiará y obtendremos el orden y el nombre de la prueba como:
Nota: