Ordem de execução de teste NUnit

110

Por padrão, os testes de unidade são executados em ordem alfabética. Alguém conhece alguma forma de definir a ordem de execução? Existe um atributo para isso?

Riain McAtamney
fonte
7
Por que você quer fazer isso? Parece que você depende da ordem de execução, o que é ruim. Você precisa reconsiderar por que deseja isso. Os testes de unidade devem ser executados isoladamente e totalmente independentes dos outros. Parece que você está criando candidatos para os Testes Erráticos de cheiro de teste .
RichardOD
Parece uma duplicata, mas você pode ver minha resposta aqui
Johnno Nolan
12
@RichardOD - deve! = Deve. E realmente não é um evento que deveria, porque na verdade quase todos os testes de integração são executados em ordem - pergunte à sua equipe de QA se eles randomizam a ordem de seus testes.
tymtam de
4
Atualmente, tenho alguns testes cuja ordem parece importar, embora não devesse. Pessoalmente, gostaria de encontrar uma forma de randomizar a ordem do teste especificamente para me ajudar a garantir que meus testes NÃO DEFERAM de alguma forma dependentes da ordem. Claro, o que eu REALMENTE gostaria seria um executor de teste que executasse todos os meus testes em ordem aleatória até encontrar um problema, ou eu digo para. Se eu fizesse isso durante a noite e tudo ainda estivesse verde pela manhã, poderia ter certeza de que eliminei o último dos efeitos colaterais indesejados.
Mel
1
esta questão seria tornada mais relevante se a questão fosse atualizada para especificar que estamos falando sobre testes de integração aqui ... Todos nós conhecemos as regras sobre testes de unidade, pelo menos se você leu os padrões de teste XUnit e seguiu o Tio Bob etc. você faz .. mas frameworks como o NUnit também são realmente úteis para colocar testes de integração em funcionamento e rapidamente também .. e você definitivamente não quer que eles sejam aleatórios, especialmente quando uma configuração cara de banco de dados está envolvida ..
nrjohnstone

Respostas:

51

Cada um dos seus testes de unidade deve ser executado de forma independente e autônoma. Se eles satisfizerem esse critério, a ordem não importa.

No entanto, há ocasiões em que você desejará executar determinados testes primeiro. Um exemplo típico é uma situação de integração contínua em que alguns testes demoram mais tempo do que outros. Usamos o atributo category para que possamos rodar os testes que usam mocking antes dos testes que usam o banco de dados.

ou seja, coloque isso no início de seus testes rápidos

[Category("QuickTests")]

Onde houver testes que dependem de certas condições ambientais, considere os atributos TestFixtureSetUp e TestFixtureTearDown , que permitem marcar métodos a serem executados antes e depois dos testes.

NeedHack
fonte
2
@Chris, eu tendo a não usar esses atributos, este é um post interessante do blog - jamesnewkirk.typepad.com/posts/2007/09/why-you-should-.html . Bom ponto sobre os testes de categoria, no entanto.
RichardOD
29
Outro exemplo de testes dependentes de pedido é quando você deseja usar sua estrutura nunit para executar um teste de integração ...
Byron Ross
1
@ByronRoss: Eu tendo a tornar os testes maiores quando faço isso, e me apóio nos testes de unidade existentes tanto quanto possível para que possa escrever menos testes. Então, cada execução completa pode falhar separadamente. Também tento projetar meus dados de forma que possam viver separadamente dos dados existentes, em vez de depender dos dados existentes.
Merlyn Morgan-Graham
1
Se você não executar seus testes em ordem aleatória, como poderá verificar se eles realmente funcionam quando executados fora de ordem? O que você está dizendo é análogo a dizer "Se o seu software não tem bugs, o teste é desnecessário".
jforberg
@jforberg: Se você tiver uma falha que ocorre aleatoriamente, como você diz quando a corrigiu?
NeedHack
175

Só quero salientar que, embora a maioria dos respondentes presumisse que eram testes de unidade, a pergunta não especificou que sim.

nUnit é uma ótima ferramenta que pode ser usada em uma variedade de situações de teste. Posso ver as razões apropriadas para querer controlar o pedido de teste.

Nessas situações, tive que recorrer à incorporação de uma ordem de execução no nome do teste. Seria ótimo poder especificar a ordem de execução usando um atributo.

Les
fonte
Quer dizer que você chamou seus testes, por exemplo, 001_first_test 002_second_teste assim por diante?
ashes999
Sim, isso mesmo, embora eu normalmente use um padrão que me permite inserir testes facilmente se necessário, então talvez 010_first_test, 020_second_test, etc.
Les
83
Obrigado pela única resposta sensata aqui. Esta é uma pergunta específica, mas respostas vagas e pedantes estão sendo votadas positivamente. Sim, todos nós sabemos o que devem ser os testes de unidade, mas essa não é a questão.
Egor Pavlikhin
1
Você não deve confiar que a ordem de execução seja alfabética. Muitos executores de teste executam seus testes simultaneamente em muitos threads ou processos e não necessariamente em ordem alfabética. Por exemplo, o NCrunch prioriza os testes com base no código que você altera (testes impactados), depois se eles falharam da última vez e se eles são executados de forma rápida ou lenta. Se você quiser uma ordem definida , simplesmente crie um meta-runner para esses testes e exclua-os das execuções regulares.
Abel de
3
Outro bom motivo para especificar a ordem é detectar determinados problemas primeiro, antes de continuar com o restante do conjunto de testes. em outras palavras, se meu teste para criar um usuário falhar, não preciso que tudo mais seja executado antes de descobrir esse resultado. Em meu outro teste, provavelmente zombei do usuário, mas é importante para mim que este seja o primeiro teste a falhar - especialmente quando o conjunto de testes é grande.
Bron Davies
125

NUnit 3.2.0 adicionado e OrderAttribute, consulte:

https://github.com/nunit/docs/wiki/Order-Attribute

Exemplo:

public class MyFixture
{
    [Test, Order(1)]
    public void TestA() { ... }


    [Test, Order(2)]
    public void TestB() { ... }

    [Test]
    public void TestC() { ... }
}
Răzvan Flavius ​​Panda
fonte
5
Obrigado, direto ao ponto o que eu estava procurando - e sem discussão, por que é bom ou ruim :)
aknoepfel 01 de
1
E então eles o transformam em um número inteiro, em vez de decimal, então se for necessário inserir teste, todos os testes devem ser renumerados.
epitka
Você sempre pode começar com números muito grandes, como milhões ou algo assim, se quiser introduzir itens do meio dessa forma - apenas mais digitação. Imo deve haver uma maneira mais fácil de ordenar as coisas do que usar números para prioridade, como uma árvore de dependência de método, mas cada um tem suas próprias desvantagens / vantagens.
Răzvan Flavius ​​Panda
9
Boa resposta, mas cuidado, os testes de estados de documentação não esperam que os testes anteriores terminem.
ROX de
Curiosamente, na minha experiência, se adicionarmos os atributos Teste e Pedido separadamente, não há garantia de ordenação dos testes.
EM
22

Querer que os testes sejam executados em uma ordem específica não significa que os testes sejam dependentes uns dos outros - estou trabalhando em um projeto TDD no momento e, sendo um bom TDDer, simulei / fiz stub de tudo, mas faria seria mais legível se eu pudesse especificar a ordem em que os resultados dos testes são exibidos - tematicamente em vez de alfabeticamente. Até agora, a única coisa que posso pensar é adicionar a_ b_ c_ às classes para classes, namespaces e métodos. (Não é legal) Acho que um atributo [TestOrderAttribute] seria bom - não seguido estritamente pela estrutura, mas uma dica para que possamos conseguir isso

William
fonte
10

Independentemente de os testes serem ou não dependentes da ordem ... alguns de nós apenas querem controlar tudo, de maneira ordenada.

Os testes de unidade geralmente são criados em ordem de complexidade. Então, por que eles também não deveriam ser executados em ordem de complexidade ou na ordem em que foram criados?

Pessoalmente, gosto de ver os testes executados na ordem em que os criei. No TDD, cada teste sucessivo naturalmente será mais complexo e levará mais tempo para ser executado. Eu preferiria ver o teste mais simples falhar primeiro, pois será um indicador melhor da causa da falha.

Mas, também posso ver a vantagem de executá-los em ordem aleatória, especialmente se você quiser testar se seus testes não têm nenhuma dependência de outros testes. Que tal adicionar uma opção para testar os corredores para "Executar testes aleatoriamente até parar"?

Mont Pierce
fonte
9

Estou testando com Selenium em um site bastante complexo e todo o conjunto de testes pode ser executado por mais de meia hora, e não estou perto de cobrir todo o aplicativo ainda. Se eu tiver que ter certeza de que todos os formulários anteriores foram preenchidos corretamente para cada teste, isso adicionará muito tempo, não apenas uma pequena quantidade de tempo, ao teste geral. Se houver muita sobrecarga para executar os testes, as pessoas não os executarão com a frequência que deveriam.

Então, eu os coloco em ordem e dependo de testes anteriores para ter caixas de texto e tal preenchidas. Eu uso Assert.Ignore () quando as pré-condições não são válidas, mas preciso executá-las em ordem.

Anthony Biagioli
fonte
1
Totalmente. Estou no mesmo barco aqui.
Sleeper Smith
Eu também! Exatamente por que cheguei a essa questão!
Niklas Wulff
@NiklasRingdahl se você estiver usando o Visual Studio com nunit, dump nunit e usar testes de MS. então você pode utilizar o arquivo de teste ordenado do Visual Studio para organizar os casos de teste na ordem em que você deseja que eles sejam executados
Rahul Lodha
@RahulLodha Obrigado! Eu vou olhar para isso.
Niklas Wulff
9

Eu realmente gosto da resposta anterior.

Mudei um pouco para poder usar um atributo para definir o intervalo do pedido:

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);
                    }
                }

            }
        }
    }
}
PvtVandals
fonte
Eu acho que essa abordagem é ótima. No entanto, observe que o código de reflexão irá puxar todos os métodos com o atributo, então se você estiver tentando executar um dispositivo de teste específico, você pode se surpreender ao descobrir que ele executa mais do que você pensava. Você pode modificar facilmente a consulta LINQ se este não for o comportamento desejado. Veja os links em minha resposta para mais informações.
Chrispy
OrderedTestnão é mais compatível com NUnit 3.
Conrad
7

Eu sei que esta é uma postagem relativamente antiga, mas aqui está outra maneira de manter seu teste em ordem SEM tornar os nomes dos testes estranhos. Usando o atributo TestCaseSource e tendo o objeto que você passa tem um delegado (Action), você pode controlar totalmente não apenas o pedido, mas também nomear o teste como ele é.

Isso funciona porque, de acordo com a documentação, os itens da coleção retornados da fonte de teste serão executados sempre na ordem em que estão listados.

Aqui está uma demonstração de uma apresentação que farei amanhã:

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");
            }
        }
    }
}
Dave Bush
fonte
Eu uso esse padrão para testes de integração paralelos que seriam muito demorados para serem executados linearmente. Todos os testes são de um tipo, então eu uso um Action <T in>, e cada Action tem uma chave que diz o que significa "ShouldBeFoo". Desta forma, o que o teste faz será visível no nome do teste e o TestCaseSource pode ser filtrado para que diferentes tipos de testes sejam agrupados. Ironicamente, não me importo com a ordem de execução, mas concordo que funcionaria.
Novaterata,
Usar o TestCaseSourcecomo uma forma de executar testes ordenados é um golpe de gênio. Bem feito. Eu peguei essa abordagem junto com a abaixo e adicionei algumas modificações adicionais para torná-la mais fácil de usar. Veja os links em minha resposta para obter informações adicionais, mas a ideia subjacente vem desta ótima resposta!
Chrispy
Infelizmente, com o NUnit 3, a fonte de TestCaseSourcedeve ser estática, o que impede o uso de padrão. Vadio.
Conrad
@Conrad. Não vejo que diferença faz o método estático ou não. O teste ainda retorna em ordem de qualquer maneira.
Dave Bush
Não é o método que precisa ser estático - a fonte (variável ou propriedade) de TestCaseSourcedeve ser um objeto estático no NUnit 3, ou os testes não serão executados. E você não pode criar objetos dinâmicos dentro de um objeto estático. É por isso que não funcionará no v. 3.
Conrad
5

Estou trabalhando com casos de teste de IU de ponta a ponta do Selenium WebDriver escritos em C #, que são executados usando a estrutura NUnit. (Não são casos unitários como tal)

Esses testes de IU certamente dependem da ordem de execução, pois outro teste precisa adicionar alguns dados como uma pré-condição. (Não é viável fazer as etapas em todos os testes)

Agora, após adicionar o 10º caso de teste, vejo que o NUnit deseja ser executado nesta ordem: Test_1 Test_10 Test_2 Test_3 ..

Portanto, acho que devo colocar em ordem alfabética os nomes dos casos de teste por enquanto, mas seria bom ter esse pequeno recurso de controle da ordem de execução adicionado ao NUnit.

Hexa
fonte
9
Discordo de Arran: os testes de IU são inerentemente sequências de pequenos passos. Cada etapa deve ser um teste (Motivo - se falhar, preciso saber qual etapa). As sequências podem ser independentes, mas dentro de uma sequência, a ordem é importante e a parada em caso de falha é necessária.
Zasz
3

Normalmente, o Teste de Unidade deve ser independente, mas se for necessário, você pode nomear seus métodos em ordem alfabética, por exemplo:

[Test]
public void Add_Users(){}

[Test]
public void Add_UsersB(){}

[Test]
public void Process_Users(){}

ou você pode fazer ..

        private void Add_Users(){}

        private void Add_UsersB(){}

        [Test]
        public void Process_Users()
        {
           Add_Users();
           Add_UsersB();
           // more code
        }
Sebastian castaldi
fonte
2
Exceto que agora os nomes devem ser colocados em ordem alfabética, o que é uma solução terrível. :(
@ user166390 - não, não é horrível. Funciona e depende do comportamento documentado do NUnit.
tymtam de
➕1 bom o suficiente para mim, muito mais fácil se você começar seus testes com a_ b_ t1_, em t2_vez ou contando com personagens
rastreadores
3

Existem boas razões para utilizar um mecanismo de pedido de teste. A maioria dos meus próprios testes usa boas práticas, como configuração / desmontagem. Outros requerem uma grande quantidade de configuração de dados, que podem ser usados ​​para testar uma variedade de recursos. Até agora, usei grandes testes para lidar com esses testes de integração (Selenium Webdriver). No entanto, acho que a postagem sugerida acima em https://github.com/nunit/docs/wiki/Order-Attribute tem muito mérito. Aqui está um exemplo de porque o pedido seria extremamente valioso:

  • Usando Selenium Webdriver para executar um teste para baixar um relatório
  • O estado do relatório (seja para download ou não) é armazenado em cache por 10 minutos
  • Isso significa que, antes de cada teste, preciso redefinir o estado do relatório e esperar até 10 minutos antes de confirmar que o estado foi alterado e, em seguida, verificar se o relatório foi baixado corretamente.
  • Os relatórios não podem ser gerados de forma prática / oportuna por meio de simulação ou qualquer outro mecanismo dentro da estrutura de teste devido à sua complexidade.

Esse tempo de espera de 10 minutos retarda o conjunto de testes. Quando você multiplica atrasos de armazenamento em cache semelhantes em uma infinidade de testes, isso consome muito tempo. Os testes de pedido podem permitir que a configuração dos dados seja feita como um "Teste" logo no início do conjunto de testes, com os testes contando com o cache para ser executado no final da execução do teste.

user2986256
fonte
2

Esta pergunta é muito antiga agora, mas para as pessoas que podem chegar a isso pesquisando, peguei as excelentes respostas do user3275462 e do PvtVandals / Rico e as adicionei a um repositório GitHub junto com algumas de minhas próprias atualizações. Também criei uma postagem de blog associada com algumas informações adicionais que você pode consultar para obter mais informações.

Espero que isso seja útil para todos vocês. Além disso, geralmente gosto de usar o atributo Categoria para diferenciar meus testes de integração ou outros testes ponta a ponta de meus testes de unidade reais. Outros indicaram que os testes de unidade não devem ter uma dependência de ordem, mas outros tipos de teste costumam ter, então isso fornece uma boa maneira de executar apenas a categoria de testes que você deseja e também ordenar esses testes ponta a ponta.

Chrispy
fonte
você pode me ajudar com um problema que eu tenho, aqui está o link: stackoverflow.com/questions/31281395/…
Morgan Soren
1

Estou surpreso que a comunidade NUnit não apareceu com nada, então fui criar algo assim sozinho.

Atualmente estou desenvolvendo uma biblioteca de código aberto que permite que você solicite seus testes com o NUnit. Você pode solicitar acessórios de teste e também "especificações de teste solicitadas".

A biblioteca oferece os seguintes recursos:

  • Construir hierarquias de pedidos de teste complexas
  • Pule os testes subsequentes se um teste falhar
  • Ordene seus métodos de teste por dependência em vez de ordem inteira
  • Oferece suporte ao uso lado a lado com testes não ordenados. Os testes não ordenados são executados primeiro.

A biblioteca é realmente inspirada em como o MSTest testa pedidos de .orderedtestarquivos. Por favor, veja um exemplo abaixo.

[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
}
Sebazzz
fonte
1

Se você estiver usando [TestCase], o argumento TestNamefornece um nome para o teste.

Se não for especificado, um nome será gerado com base no nome do método e nos argumentos fornecidos.

Você pode controlar a ordem de execução do teste conforme abaixo:

                    [Test]
            [TestCase("value1", TestName = "ExpressionTest_1")]
            [TestCase("value2", TestName = "ExpressionTest_2")]
            [TestCase("value3", TestName = "ExpressionTest_3")]
            public void ExpressionTest(string  v)
            {
                //do your stuff
            }

Aqui, usei o "ExpressionTest"sufixo do nome do método com um número.

Você pode usar qualquer nome em ordem alfabética, consulte o atributo TestCase

M.Hassan
fonte
0

Você não deve depender da ordem em que a estrutura de teste seleciona os testes para execução. Os testes devem ser isolados e independentes. Nesse sentido, eles não devem depender de algum outro teste preparando o cenário para eles ou limpando depois deles. Eles também devem produzir o mesmo resultado, independentemente da ordem de execução dos testes (para um determinado instantâneo do SUT)

Eu pesquisei um pouco no Google. Como de costume, algumas pessoas recorreram a truques furtivos (em vez de resolver o problema de testabilidade / design subjacente

  • nomear os testes em ordem alfabética, de modo que os testes apareçam na ordem em que 'precisam' ser executados. No entanto, o NUnit pode optar por alterar esse comportamento com uma versão posterior e, então, seus testes serão suspensos. É melhor verificar os binários NUnit atuais para o controle de origem.
  • VS (IMHO encorajando o comportamento errado com suas 'ferramentas ágeis') tem algo chamado de "Testes ordenados" em sua estrutura de teste MS. Não perdi tempo lendo, mas parece direcionado ao mesmo público

Veja também: características de um bom teste

Gishu
fonte
Há ocasiões em que você gostaria que os testes de execução mais rápida fossem executados antes dos testes de longa execução, especificamente em testes de integração e aceitação. Por exemplo, em um aplicativo de blog: você testa o login primeiro, porque se esse recurso não funcionar, a postagem também não funcionará, então não há por que executar esse teste (você pode parar o runner manualmente). Mas se você tentar continuar executando os testes, isso levará mais tempo.
Marcel Valdez Orozco
@MarcelValdezOrozco - você pode atingir esse objetivo particionando seus testes por meio de diferentes dll físicas ou usando tags / categorias. Você pode criar seus scripts de construção para executar dlls / categorias em ordem. Em geral, permitir a ordenação de testes geralmente leva a testes acoplados que desenvolvem dependências nos testes vizinhos (com o tempo, é claro). AFAIR no próximo grande lançamento do NUnit, ele suportará diferentes ordens de testes, por exemplo, aleatório etc.
Gishu
2
Particionar ainda mais o mesmo tipo de testes (testes de aceitação, por exemplo) não faz sentido, e separá-los em outra DLL aumenta desnecessariamente a complexidade em todos os lugares: código-fonte, scripts de construção, scripts de teste, estrutura do projeto, etc. Apenas para fazer um reordenamento simples de Os testes.
Marcel Valdez Orozco
A emissão (basicamente, todas as bibliotecas de simulação) é uma razão pela qual a ordem seria importante. Você não pode descarregar o domínio do seu aplicativo, e o nunit runner (se estiver executando todos os testes em um assembly) mantém esse domínio para todos os testes pelo menos nessa 'fixação'. Se um teste cria tipos para testar algo, e outro teste entra em conflito com aquele tipo criado, por causa da ordem, não é um teste com defeito. Eles são isolados logicamente, mas o nUnit não fornece o isolamento adequado entre cada 'teste' em si.
Kelly Elton
6
Esta é uma resposta bastante condescendente e torna-a engraçada porque ela realmente só se aplica a testes de unidade e ignora completamente ser pragmático.
tymtam de
0

No caso de usar TestCaseSourcea chave é o override string ToStringmétodo, como isso funciona:

Suponha que você tenha a classe TestCase

public class TestCase
{
    public string Name { get; set; }
    public int Input { get; set; }
    public int Expected { get; set; }
}

E uma 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
        }
    };
}

Agora vamos usá-lo com um método de teste e ver o que acontece:

[TestCaseSource(nameof(TestSource))]
public void MethodXTest(TestCase testCase)
{
    var x = Power(testCase.Input);
    x.ShouldBe(testCase.Expected);
}

Isso não será testado em ordem e a saída será assim:

insira a descrição da imagem aqui

Portanto, se adicionarmos override string ToStringà nossa classe:

public class TestCase
{
    public string Name { get; set; }
    public int Input { get; set; }
    public int Expected { get; set; }

    public override string ToString()
    {
        return Name;
    }
}

O resultado mudará e obteremos a ordem e o nome do teste como:

insira a descrição da imagem aqui

Nota:

  1. Este é apenas um exemplo para ilustrar como obter o nome e a ordem no teste, a ordem é feita numericamente / alfabeticamente, então se você tiver mais de dez testes, sugiro fazer o Teste 01, Teste 02 .... Teste 10, Teste 11 etc porque se você faz o Teste 1 e em algum momento o Teste 10, então o pedido será Teste 1, Teste 10, Teste 2 .. etc.
  2. A entrada e o esperado podem ser qualquer tipo, string, objeto ou classe personalizada.
  3. Além da ordem, o bom aqui é que você vê o nome do teste, que é mais importante.
maytham-ɯɐɥʇʎɐɯ
fonte