Ordre D'Exécution Du Test NUnit
par défaut nunit tests exécutés par ordre alphabétique. Personne ne sait de toute façon de définir l'ordre d'exécution? Un attribut existe pour cela?
15 réponses
vos tests unitaires devraient chacun pouvoir fonctionner de manière indépendante et autonome. S'ils satisfont à ce critère, l'ordre n'a pas d'importance.
il y a des occasions cependant où vous voudrez exécuter certains tests en premier. Un exemple typique est une situation D'Intégration Continue où certains tests sont plus longs que d'autres. Nous utilisons l'attribut category afin de pouvoir exécuter les tests qui utilisent mocking avant les tests qui utilisent la base de données.
c'est-à-dire mettez ceci au début de vos tests rapides
[Category("QuickTests")]
lorsque vous avez des tests qui dépendent de certaines conditions environnementales, considérez les attributs TestFixtureSetUp et Testfixtureardown , qui vous permettent de noter les méthodes à exécuter avant et après vos tests.
je tiens simplement à souligner que, bien que la plupart des répondants aient présumé qu'il s'agissait de tests unitaires, la question ne précisait pas qu'ils l'étaient.
nUnit est un excellent outil qui peut être utilisé pour une variété de situations de test. Je peux voir des raisons appropriées pour vouloir contrôler l'ordre de test.
dans ces situations, j'ai dû recourir à l'incorporation d'un ordre de passage dans le nom du test. Ce serait génial de pouvoir spécifier un ordre d'exécution en utilisant un attribut.
NUnit 3.2.0 a ajouté un OrderAttribute
, voir:
https://github.com/nunit/docs/wiki/Order-Attribute
exemple:
public class MyFixture
{
[Test, Order(1)]
public void TestA() { ... }
[Test, Order(2)]
public void TestB() { ... }
[Test]
public void TestC() { ... }
}
vouloir que les tests s'exécutent dans un ordre précis ne signifie pas que les tests dépendent les uns des autres - je travaille actuellement sur un projet TDD, et étant un bon TDDer, j'ai tout ridiculisé/entaillé, mais cela le rendrait plus lisible si je pouvais spécifier l'ordre dans lequel les résultats des tests sont affiché - thématiquement au lieu de l'ordre alphabétique. Jusqu'à présent, la seule chose à laquelle je peux penser est de préparer a_ b_ c_ à des classes, des espaces de noms et des méthodes. (Pas nice) je pense qu'un attribut [TestOrderAttribute] serait agréable - pas strictement suivi par le cadre, mais un indice pour que nous puissions atteindre ce
que les essais dépendent ou non de l'ordre... certains d'entre nous veulent tout contrôler, d'une manière ordonnée.
Les tests unitairessont généralement créés par ordre de complexité. Alors, pourquoi ne devraient-ils pas aussi être exécutés par ordre de complexité, ou de l'ordre dans lequel ils ont été créés?
Personnellement, j'aime voir les tests s'exécutent dans l'ordre dans lequel je les ai créées. En TDD, chaque test successif va naturellement être plus complexe, et de prendre plus de temps à s'exécuter. Je préférerais que le test le plus simple échoue d'abord, car ce sera un meilleur indicateur quant à la cause de la défaillance.
Mais, je vois aussi l'avantage de les exécuter dans un ordre aléatoire, surtout si vous voulez tester vos tests n'ont pas de dépendances sur d'autres tests. Que diriez-vous d'ajouter une option pour tester les coureurs à "exécuter des Tests au hasard Jusqu'à L'arrêt"?
je teste avec du sélénium sur un site Web assez complexe et toute la série de tests peut durer plus d'une demi-heure, et je ne suis pas encore près de couvrir l'ensemble de l'application. Si je dois m'assurer que tous les formulaires précédents sont remplis correctement pour chaque test, cela ajoute beaucoup de temps, pas seulement une petite quantité de temps, à l'ensemble du test. S'il y a trop de frais pour faire les tests, les gens ne les feront pas aussi souvent qu'ils le devraient.
donc, j'ai mis ils dans l'ordre et dépendent des tests précédents pour avoir des boîtes de texte et tels complétés. J'utilise Affirmer.Ignore () lorsque les conditions préalables ne sont pas valides, mais je dois les faire fonctionner dans l'ordre.
j'aime beaucoup la réponse précédente.
Je l'ai un peu changé pour pouvoir utiliser un attribut pour définir la gamme d'ordre:
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);
}
}
}
}
}
}
je sais que c'est un post relativement ancien, mais voici une autre façon de garder votre test dans l'ordre sans rendre les noms de test maladroits. En utilisant L'attribut TestCaseSource et en ayant l'objet que vous réussissez dans have a delegate (Action), vous pouvez totalement non seulement contrôler l'ordre mais aussi nommer le test ce qu'il est.
cela fonctionne parce que, selon la documentation, les éléments de la collection retournés à partir de la source de test s'exécuteront toujours dans l'ordre où ils sont répertoriés.
voici une démo d'une présentation que je donne demain:
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");
}
}
}
}
je travaille avec Selenium WebDriver des cas de test D'interface utilisateur de bout en bout écrits en C#, qui sont exécutés en utilisant le cadre NUnit. (Pas d'unité d'affaires)
ces tests D'UI dépendent certainement de l'ordre d'exécution, car d'autres tests doivent ajouter certaines données comme condition préalable. (Il n'est pas possible de faire les étapes dans chaque test)
maintenant, après avoir ajouté le 10ème test case, je vois que NUnit veut courir dans cet ordre: Test_1 Test_10 Test_2 Test_3 ..
donc je suppose que je dois trop alphabétiser les noms de cas de test pour le moment, mais il serait bon d'avoir cette petite caractéristique de contrôle de l'ordre d'exécution ajoutée à NUnit.
habituellement, le test unitaire devrait être indépendant, mais si vous le devez, alors vous pouvez nommer vos méthodes dans l'ordre alphabétique ex:
[Test]
public void Add_Users(){}
[Test]
public void Add_UsersB(){}
[Test]
public void Process_Users(){}
"151920920 ou vous pouvez le faire..
private void Add_Users(){}
private void Add_UsersB(){}
[Test]
public void Process_Users()
{
Add_Users();
Add_UsersB();
// more code
}
il y a de très bonnes raisons d'utiliser un mécanisme de commande de Test. La plupart de mes propres tests utilisent de bonnes pratiques telles que la configuration/démontage. D'autres nécessitent des quantités énormes de configuration de données, qui peuvent ensuite être utilisés pour tester une gamme de fonctionnalités. Jusqu'à présent, j'ai utilisé de grands tests pour gérer ces tests d'intégration (Webdriver de sélénium). Cependant, je pense que le post suggéré ci-dessus sur https://github.com/nunit/docs/wiki/Order-Attribute a beaucoup de mérite. Voici un exemple pourquoi commander serait extrêmement précieux:
- utiliser un Webdriver au sélénium pour effectuer un test afin de télécharger un rapport
- L'état du rapport (téléchargeable ou non) est mis en cache pour 10 minutes
- C'est-à-dire, avant chaque test, je dois réinitialiser l'état du rapport et puis attendre jusqu'à 10 minutes avant de confirmer que l'État a changé, et puis vérifier le reportez les téléchargements correctement.
- en raison de leur complexité, les rapports ne peuvent pas être produits de façon pratique ou en temps opportun au moyen de moqueries ou de tout autre mécanisme du cadre d'essai.
ce délai d'attente de 10 minutes ralentit la suite de tests. Lorsque vous multipliez des retards de mise en cache similaires à travers une multitude de tests, cela prend beaucoup de temps. La commande de tests pourrait permettre de configurer les données en tant que" Test " dès le début du test. suite, avec des tests s'appuyant sur le buste cache à exécuter vers la fin de l'exécution du test.
cette question est vraiment vieille maintenant, mais pour les gens qui peuvent atteindre cela de la recherche, j'ai pris les excellentes réponses de l'utilisateur 3275462 et PvtVandals / Rico et les ai ajoutés à un dépôt GitHub avec certaines de mes propres mises à jour. J'ai également créé un billet de blog associé avec quelques informations supplémentaires que vous pouvez consulter pour plus d'informations.
J'espère que c'est utile pour vous tous. Aussi, j'aime souvent utiliser l'attribut Category pour différencier mes tests d'intégration ou autres tests de bout en bout de mes tests unitaires actuels. D'autres ont souligné que les tests unitaires ne devraient pas avoir de dépendance d'ordre, mais d'autres types de tests le font souvent, ce qui fournit une bonne façon d'exécuter seulement la catégorie de tests que vous voulez et aussi de commander ces tests de bout en bout.
je suis surpris que la communauté NUnit n'ait rien trouvé, alors je suis allé créer quelque chose comme ça moi-même.
je suis en train de le développement d'un open-source de la bibliothèque qui vous permet de commander vos tests avec NUnit. Vous pouvez commander des fixtures de test et commander des "spécifications de test ordonnées".
La bibliothèque offre les fonctionnalités suivantes:
- Construire des complexes de test de la commande hiérarchies
- sauter les essais suivants si un essai dans l'ordre échoue
- commandez vos méthodes de test par dépendance au lieu de l'ordre entier
- supporte l'utilisation côte à côte avec des tests non ordonnés. Les tests non ordonnés sont exécutés en premier.
la Bibliothèque est en fait inspirée de la façon dont MSTest teste la commande avec des fichiers .orderedtest
. Veuillez consulter un exemple ci-dessous.
[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
}
vous ne devez pas dépendre de l'ordre dans lequel le cadre de test choisit les tests pour l'exécution. Les essais doivent être isolés et indépendants. En ce sens, ils ne devraient pas dépendre d'un autre test qui leur ouvre la voie ou qui nettoie après eux. Ils doivent également produire le même résultat quel que soit l'ordre d'exécution des essais (pour un instantané donné du SUT)
j'ai un peu cherché sur Google. Comme d'habitude, certaines personnes ont eu recours à la astuces sournoises (au lieu de résoudre le problème sous-jacent de testabilité/conception
- nommer les tests par ordre alphabétique de sorte que les tests apparaissent dans l'ordre où ils doivent être exécutés. Cependant NUnit peut choisir de changer ce comportement avec une version ultérieure et ensuite vos tests seront dévoilés. Mieux vaut vérifier les binaires NUnit actuels pour le contrôle Source.
- VS (à mon humble avis encourageant le mauvais comportement avec leurs "outils agile") a quelque chose appelé "tests ordonnés" dans leur cadre de tests MS. Je n'ai pas perdu de temps à lire, mais il semble être destinée au même public
Voir aussi: caractéristiques d'un bon essai
" Si vous utilisez [TestCase]
, l'argument TestName
fournit un nom pour le test.
si non spécifié, un nom est généré basé sur le nom de la méthode et les arguments fournis.
vous pouvez contrôler l'ordre d'exécution du test comme indiqué ci-dessous:
[Test]
[TestCase("value1", TestName = "ExpressionTest_1")]
[TestCase("value2", TestName = "ExpressionTest_2")]
[TestCase("value3", TestName = "ExpressionTest_3")]
public void ExpressionTest(string v)
{
//do your stuff
}
ici j'ai utilisé le suffixe de méthode "ExpressionTest"
avec un nombre.
vous pouvez utiliser n'importe quels noms par ordre alphabétique voir Attribut TestCase