Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Ocasionalmente, você pode querer que os testes de unidade sejam executados em uma ordem específica. Idealmente, a ordem em que os testes de unidade são executados não importa, e é recomendado evitar a ordenação dos testes de unidade. Independentemente disso, pode haver necessidade de fazê-lo. Nesse caso, este artigo demonstra como ordenar execuções de teste.
Nota
A ordenação de testes e a paralelização de testes são preocupações separadas. Especificar uma ordem de execução determina a sequência em que os testes começam, mas se a paralelização estiver ativada, múltiplos testes podem ainda ser executados em simultâneo. Para garantir que os testes correm um de cada vez na ordem especificada, deve também desativar a paralelização.
Se preferir navegar pelo código-fonte, consulte o repositório de exemplos order .NET Core unit tests.
Gorjeta
Para além das capacidades de encomenda descritas neste artigo, considere criar playlists personalizadas com Visual Studio como alternativa.
Ordenar alfabeticamente
Nota
O MSTest executa testes sequencialmente dentro de uma classe por defeito. Se configurares paralelismo usando a <Parallelize> definição num .runsettings ficheiro, os testes entre classes podem correr em simultâneo, e a ordenação afeta apenas a sequência dentro de cada classe.
O MSTest descobre testes na mesma ordem em que são definidos na classe de teste.
Ao ser executado através do Test Explorer (no Visual Studio ou no Visual Studio Code), os testes são ordenados alfabéticamente com base no nome do teste.
Quando executados fora do Test Explorer, os testes são executados na ordem em que são definidos na classe de teste.
Nota
Um teste nomeado Test14 será executado antes Test2 , mesmo que o número 2 seja menor que 14. Isso ocorre porque a ordenação de nomes de teste usa o nome de texto do teste.
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace MSTest.Project;
[TestClass]
public class ByAlphabeticalOrder
{
public static bool Test1Called;
public static bool Test2Called;
public static bool Test3Called;
[TestMethod]
public void Test2()
{
Test2Called = true;
Assert.IsTrue(Test1Called);
Assert.IsFalse(Test3Called);
}
[TestMethod]
public void Test1()
{
Test1Called = true;
Assert.IsFalse(Test2Called);
Assert.IsFalse(Test3Called);
}
[TestMethod]
public void Test3()
{
Test3Called = true;
Assert.IsTrue(Test1Called);
Assert.IsTrue(Test2Called);
}
}
A partir do MSTest 3.6, uma nova opção runsettings permite executar testes por nomes de teste nos Test Explorers e na linha de comando. Para habilitar esse recurso, adicione a OrderTestsByNameInClass configuração ao arquivo runsettings:
<?xml version="1.0" encoding="utf-8"?>
<RunSettings>
<MSTest>
<OrderTestsByNameInClass>true</OrderTestsByNameInClass>
</MSTest>
</RunSettings>
A estrutura de teste xUnit permite mais granularidade e controle da ordem de execução do teste. Você implementa as ITestCaseOrderer interfaces e ITestCollectionOrderer para controlar a ordem dos casos de teste para uma classe ou coleções de teste.
Nota
A xUnit executa classes de teste em paralelo por defeito. Os testes dentro de uma única classe são sempre executados sequencialmente, controlando ITestCaseOrderer assim a sequência dentro dessa classe. Para desativar o paralelismo em todas as classes, aplique [assembly: CollectionBehavior(DisableTestParallelization = true)] ao nível de assembly, por exemplo, em AssemblyInfo.cs ou em qualquer ficheiro fonte do seu projeto de teste.
Ordenar casos de teste alfabeticamente
Para ordenar casos de teste pelo nome do método, implemente o ITestCaseOrderer e forneça um mecanismo de ordenação.
using Xunit.Abstractions;
using Xunit.Sdk;
namespace XUnit.Project.Orderers;
public class AlphabeticalOrderer : ITestCaseOrderer
{
public IEnumerable<TTestCase> OrderTestCases<TTestCase>(
IEnumerable<TTestCase> testCases) where TTestCase : ITestCase =>
testCases.OrderBy(testCase => testCase.TestMethod.Method.Name);
}
Em seguida, em uma classe de teste, você define a ordem do caso de teste com o TestCaseOrdererAttribute.
using Xunit;
namespace XUnit.Project;
[TestCaseOrderer(
ordererTypeName: "XUnit.Project.Orderers.AlphabeticalOrderer",
ordererAssemblyName: "XUnit.Project")]
public class ByAlphabeticalOrder
{
public static bool Test1Called;
public static bool Test2Called;
public static bool Test3Called;
[Fact]
public void Test1()
{
Test1Called = true;
Assert.False(Test2Called);
Assert.False(Test3Called);
}
[Fact]
public void Test2()
{
Test2Called = true;
Assert.True(Test1Called);
Assert.False(Test3Called);
}
[Fact]
public void Test3()
{
Test3Called = true;
Assert.True(Test1Called);
Assert.True(Test2Called);
}
}
Ordenar por coleção por ordem alfabética
Para ordenar coleções de teste por seu nome de exibição, implemente o ITestCollectionOrderer e forneça um mecanismo de ordenação.
using Xunit;
using Xunit.Abstractions;
namespace XUnit.Project.Orderers;
public class DisplayNameOrderer : ITestCollectionOrderer
{
public IEnumerable<ITestCollection> OrderTestCollections(
IEnumerable<ITestCollection> testCollections) =>
testCollections.OrderBy(collection => collection.DisplayName);
}
Como as coleções de teste são potencialmente executadas em paralelo, você deve desabilitar explicitamente a paralelização de teste das coleções com o CollectionBehaviorAttribute. Em seguida, especifique a implementação para o TestCollectionOrdererAttribute.
using Xunit;
// Need to turn off test parallelization so we can validate the run order
[assembly: CollectionBehavior(DisableTestParallelization = true)]
[assembly: TestCollectionOrderer(
ordererTypeName: "XUnit.Project.Orderers.DisplayNameOrderer",
ordererAssemblyName: "XUnit.Project")]
namespace XUnit.Project;
[Collection("Xzy Test Collection")]
public class TestsInCollection1
{
public static bool Collection1Run;
[Fact]
public static void Test()
{
Assert.True(TestsInCollection2.Collection2Run); // Abc
Assert.True(TestsInCollection3.Collection3Run); // Mno
Assert.False(TestsInCollection1.Collection1Run); // Xyz
Collection1Run = true;
}
}
[Collection("Abc Test Collection")]
public class TestsInCollection2
{
public static bool Collection2Run;
[Fact]
public static void Test()
{
Assert.False(TestsInCollection2.Collection2Run); // Abc
Assert.False(TestsInCollection3.Collection3Run); // Mno
Assert.False(TestsInCollection1.Collection1Run); // Xyz
Collection2Run = true;
}
}
[Collection("Mno Test Collection")]
public class TestsInCollection3
{
public static bool Collection3Run;
[Fact]
public static void Test()
{
Assert.True(TestsInCollection2.Collection2Run); // Abc
Assert.False(TestsInCollection3.Collection3Run); // Mno
Assert.False(TestsInCollection1.Collection1Run); // Xyz
Collection3Run = true;
}
}
Ordenar por atributo personalizado
Para ordenar testes xUnit com atributos personalizados, primeiro você precisa de um atributo no qual confiar. Defina a TestPriorityAttribute da seguinte forma:
namespace XUnit.Project.Attributes;
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public class TestPriorityAttribute : Attribute
{
public int Priority { get; private set; }
public TestPriorityAttribute(int priority) => Priority = priority;
}
Em seguida, considere a seguinte PriorityOrderer implementação da interface ITestCaseOrderer.
using Xunit.Abstractions;
using Xunit.Sdk;
using XUnit.Project.Attributes;
namespace XUnit.Project.Orderers;
public class PriorityOrderer : ITestCaseOrderer
{
public IEnumerable<TTestCase> OrderTestCases<TTestCase>(
IEnumerable<TTestCase> testCases) where TTestCase : ITestCase
{
string assemblyName = typeof(TestPriorityAttribute).AssemblyQualifiedName!;
var sortedMethods = new SortedDictionary<int, List<TTestCase>>();
foreach (TTestCase testCase in testCases)
{
int priority = testCase.TestMethod.Method
.GetCustomAttributes(assemblyName)
.FirstOrDefault()
?.GetNamedArgument<int>(nameof(TestPriorityAttribute.Priority)) ?? 0;
GetOrCreate(sortedMethods, priority).Add(testCase);
}
foreach (TTestCase testCase in
sortedMethods.Keys.SelectMany(
priority => sortedMethods[priority].OrderBy(
testCase => testCase.TestMethod.Method.Name)))
{
yield return testCase;
}
}
private static TValue GetOrCreate<TKey, TValue>(
IDictionary<TKey, TValue> dictionary, TKey key)
where TKey : struct
where TValue : new() =>
dictionary.TryGetValue(key, out TValue? result)
? result
: (dictionary[key] = new TValue());
}
Em seguida, em uma classe de teste, você define a ordem do caso de teste com o TestCaseOrdererAttribute para o PriorityOrderer.
using Xunit;
using XUnit.Project.Attributes;
namespace XUnit.Project;
[TestCaseOrderer(
ordererTypeName: "XUnit.Project.Orderers.PriorityOrderer",
ordererAssemblyName: "XUnit.Project")]
public class ByPriorityOrder
{
public static bool Test1Called;
public static bool Test2ACalled;
public static bool Test2BCalled;
public static bool Test3Called;
[Fact, TestPriority(5)]
public void Test3()
{
Test3Called = true;
Assert.True(Test1Called);
Assert.True(Test2ACalled);
Assert.True(Test2BCalled);
}
[Fact, TestPriority(0)]
public void Test2B()
{
Test2BCalled = true;
Assert.True(Test1Called);
Assert.True(Test2ACalled);
Assert.False(Test3Called);
}
[Fact]
public void Test2A()
{
Test2ACalled = true;
Assert.True(Test1Called);
Assert.False(Test2BCalled);
Assert.False(Test3Called);
}
[Fact, TestPriority(-5)]
public void Test1()
{
Test1Called = true;
Assert.False(Test2ACalled);
Assert.False(Test2BCalled);
Assert.False(Test3Called);
}
}
Ordenar por prioridade
Nota
O NUnit executa testes sequencialmente dentro de um único thread por defeito. A menos que tenhas aplicado [Parallelizable] atributos, o [Order] atributo por si só é suficiente para garantir a execução serial na sequência especificada.
Para ordenar testes explicitamente, o NUnit fornece um componente OrderAttribute. Os testes com este atributo são iniciados antes dos testes sem. O valor de prioridade é usado para determinar a sequência de execução dos testes de unidade.
using NUnit.Framework;
namespace NUnit.Project;
public class ByOrder
{
public static bool Test1Called;
public static bool Test2ACalled;
public static bool Test2BCalled;
public static bool Test3Called;
[Test, Order(5)]
public void Test1()
{
Test1Called = true;
Assert.That(Test2ACalled, Is.False);
Assert.That(Test2BCalled, Is.True);
Assert.That(Test3Called, Is.True);
}
[Test, Order(0)]
public void Test2B()
{
Test2BCalled = true;
Assert.That(Test1Called, Is.False);
Assert.That(Test2ACalled, Is.False);
Assert.That(Test3Called, Is.True);
}
[Test]
public void Test2A()
{
Test2ACalled = true;
Assert.That(Test1Called, Is.True);
Assert.That(Test2BCalled, Is.True);
Assert.That(Test3Called, Is.True);
}
[Test, Order(-5)]
public void Test3()
{
Test3Called = true;
Assert.That(Test1Called, Is.False);
Assert.That(Test2ACalled, Is.False);
Assert.That(Test2BCalled, Is.False);
}
}