NUnit Test Run Order

Domyślnie testy nunit są uruchamiane Alfabetycznie. Czy ktoś wie, jak ustawić rozkaz egzekucji? Czy istnieje do tego jakiś atrybut?

Author: Riain McAtamney, 2009-07-03

15 answers

Twoje testy jednostkowe powinny być w stanie działać niezależnie i samodzielnie. Jeżeli spełniają to kryterium, to zamówienie nie ma znaczenia.

Są jednak okazje, w których będziesz chciał najpierw przeprowadzić pewne testy. Typowym przykładem jest sytuacja ciągłej integracji, w której niektóre testy działają dłużej niż inne. Używamy atrybutu category, dzięki czemu możemy uruchomić testy, które używają mocking przed testami, które używają bazy danych.

Tzn. umieścić to na początek szybkich testów

[Category("QuickTests")]

Jeśli masz testy zależne od pewnych warunków środowiskowych, rozważ atrybuty Testfixtureteardown i TestFixtureTearDown , które umożliwiają zaznaczanie metod, które mają być wykonane przed i po testach.

 47
Author: NeedHack,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-11 07:18:40

Chcę tylko podkreślić, że podczas gdy większość respondentów zakładała, że były to testy jednostkowe, pytanie nie precyzowało, że były.

NUnit to świetne narzędzie, które można wykorzystać w różnych sytuacjach testowych. Widzę odpowiednie powody, by chcieć kontrolować kolejność testów.

W takich sytuacjach musiałem uciekać się do włączenia kolejności uruchamiania do nazwy testu. Byłoby wspaniale móc określić kolejność uruchamiania za pomocą atrybutu.

 159
Author: Leslie,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-08-19 18:29:16

NUnit 3.2.0 dodał OrderAttribute, Zobacz:

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

Przykład:

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


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

    [Test]
    public void TestC() { ... }
}
 79
Author: Răzvan Flavius Panda,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-05 15:53:11

Chęć uruchomienia testów w określonej kolejności nie oznacza, że testy są od siebie zależne - pracuję obecnie nad projektem TDD, a będąc dobrym Tdderem, wyśmiewałem/stubowałem wszystko, ale byłoby to bardziej czytelne, gdybym mógł określić kolejność wyświetlania wyników testów - tematycznie zamiast Alfabetycznie. Jak na razie jedyne co przychodzi mi do głowy to prepend a_ b_ c_ do klas do klas, przestrzeni nazw i metod. (Nieładnie) myślę, że a [TestOrderAttribute] atrybut byłby miły-Nie ściśle po framework, ale podpowiedź, dzięki której możemy to osiągnąć

 21
Author: William,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-20 14:15:24

Niezależnie od tego, czy testy są zależne od kolejności... niektórzy z nas chcą po prostu kontrolować wszystko, w uporządkowany sposób.

Testy jednostkowe są zwykle tworzone w kolejności złożoności. Dlaczego więc nie powinny być również uruchamiane w kolejności złożoności lub kolejności, w jakiej zostały stworzone?

Osobiście lubię oglądać testy w kolejności, w jakiej je stworzyłem. W TDD każdy kolejny test będzie naturalnie bardziej złożony i zajmie więcej czasu. Wolałabym zobacz najpierw prostszy test się nie powiedzie, ponieważ będzie lepszym wskaźnikiem co do przyczyny awarii.

Ale widzę również korzyści z uruchamiania ich w losowej kolejności, zwłaszcza jeśli chcesz przetestować, że twoje testy nie mają żadnych zależności od innych testów. Co powiesz na dodanie opcji testowania biegaczy, aby "uruchamiać testy losowo do momentu zatrzymania"?

 10
Author: Mont Pierce,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-26 15:45:12

Testuję z Selenium na dość złożonej stronie internetowej i cały zestaw testów może działać dłużej niż pół godziny, a nie jestem jeszcze blisko pokrycia całej aplikacji. Jeśli muszę upewnić się, że wszystkie poprzednie formularze są wypełnione poprawnie dla każdego testu, to dodaje to wiele czasu, a nie tylko niewielką ilość czasu, do ogólnego testu. Jeśli testy są zbyt obciążające, ludzie nie będą je uruchamiać tak często, jak powinni.

Więc uporządkowałem je i zależy od poprzednich testów, aby mieć pola tekstowe i takie wypełnione. Używam Assert.Ignoruj (), gdy warunki wstępne nie są poprawne, ale muszę je uruchomić w porządku.

 9
Author: Anthony Biagioli,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-22 22:30:23

Bardzo podoba mi się poprzednia odpowiedź.

Zmieniłem go trochę, aby móc użyć atrybutu do ustawienia zakresu kolejności:

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

            }
        }
    }
}
 9
Author: PvtVandals,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-29 14:50:06

Wiem, że jest to stosunkowo stary post, ale oto inny sposób na utrzymanie porządku testu bez sprawiania, że nazwy testów są niezręczne. Używając atrybutu TestCaseSource i mając obiekt, który przekazujesz, masz delegata (akcję), możesz całkowicie nie tylko kontrolować kolejność, ale także nazwać test, jaki to jest.

To działa, ponieważ, zgodnie z dokumentacją, elementy w kolekcji zwrócone ze źródła testowego będą zawsze wykonywane w takiej kolejności, w jakiej są na liście.

Oto demo z jutrzejszej prezentacji:

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");
            }
        }
    }
}
 7
Author: Dave Bush,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-05 14:00:24

Pracuję z Selenium WebDriver end-to-end UI przypadków testowych napisanych w C#, które są uruchamiane przy użyciu frameworku NUnit. (Nie przypadki jednostkowe jako takie)

Te testy UI z pewnością zależą od kolejności wykonania, ponieważ inne testy muszą dodać pewne dane jako warunek wstępny. (Nie jest możliwe wykonanie kroków w każdym teście)

Teraz, po dodaniu 10-tego przypadku testowego, widzę, że NUnit chce uruchomić w tej kolejności: Test_1 Test_10 Test_2 Test_3 ..

Więc chyba muszę zbytnio na razie nazwy spraw, ale dobrze by było, gdyby do NUnit dodano tę małą funkcję kontrolowania zleceń wykonania.

 5
Author: Hexa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-25 11:10:08

Zazwyczaj test jednostkowy powinien być niezależny, ale jeśli musisz, możesz nazwać swoje metody w porządku alfabetycznym np:

[Test]
public void Add_Users(){}

[Test]
public void Add_UsersB(){}

[Test]
public void Process_Users(){}
Albo możesz to zrobić..
        private void Add_Users(){}

        private void Add_UsersB(){}

        [Test]
        public void Process_Users()
        {
           Add_Users();
           Add_UsersB();
           // more code
        }
 3
Author: Sebastian Castaldi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-03-12 21:31:35

Istnieją bardzo dobre powody, aby skorzystać z mechanizmu zamawiania testów. Większość moich własnych testów wykorzystuje dobre praktyki, takie jak setup/teardown. Inne wymagają ogromnych ilości konfiguracji danych, które można następnie wykorzystać do testowania szeregu funkcji. Do tej pory używałem dużych testów do obsługi tych (Selenium Webdriver) testów integracyjnych. Wydaje mi się jednak, że powyższy post na https://github.com/nunit/docs/wiki/Order-Attribute ma wiele zalet. Oto przykład, dlaczego zamawianie być niezwykle cenne:

  • użycie Selenium Webdriver do uruchomienia testu w celu pobrania raportu
  • Stan raportu (czy można go pobrać, czy nie) jest buforowany przez 10 minut
  • oznacza to, że przed każdym testem muszę zresetować stan raportu, a następnie poczekać do 10 minut , zanim stan zostanie potwierdzony jako zmieniony, a następnie zweryfikować poprawne pobranie raportu.
  • raporty nie mogą być generowane w sposób praktyczny / terminowy poprzez wyśmiewanie lub inny mechanizm w ramach badania ze względu na ich złożoność.

Ten 10-minutowy czas oczekiwania spowalnia zestaw testowy. Mnożenie podobnych opóźnień buforowania w wielu testach pochłania dużo czasu. Zamawianie testów może umożliwić konfigurację danych jako" Test " bezpośrednio na początku zestawu testów, przy czym testy polegające na awarii pamięci podręcznej są wykonywane pod koniec testu.

 3
Author: user2986256,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-20 01:17:46

To pytanie jest teraz naprawdę stare, ale dla ludzi, którzy mogą dotrzeć do tego z wyszukiwania, wziąłem doskonałe odpowiedzi od user3275462 i PvtVandals / Rico i dodał je do repozytorium GitHub wraz z niektórymi z moich własnych aktualizacji. Stworzyłem również powiązany post na blogu z dodatkowymi informacjami, na które możesz spojrzeć, aby uzyskać więcej informacji.

Mam nadzieję, że to będzie pomocne dla was wszystkich. Ponadto często lubię używać atrybutu Category, aby odróżnić moje testy integracyjne lub inne testy end-to-end z moich rzeczywistych testów jednostkowych. Inni wskazywali, że testy jednostkowe nie powinny mieć zależności od kolejności, ale inne typy testów często tak robią, więc zapewnia to dobry sposób na uruchamianie tylko wybranej kategorii testów, a także zamawianie testów end-to-end.

 2
Author: Chrispy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-19 22:03:31

Dziwi mnie, że społeczność NUnit nic nie wymyśliła, więc sama postanowiłam stworzyć coś takiego.

Obecnie rozwijam bibliotekę open-source , która pozwala na zamawianie testów za pomocą NUnit. Możesz zamówić oprawy testowe i zamawiać "zamówione specyfikacje testowe".

Biblioteka oferuje następujące funkcje:

  • budowanie złożonych hierarchii porządkowania testów
  • Pomiń kolejne testy, jeśli test w kolejności fails
  • Uporządkuj metody testowe według zależności zamiast kolejności całkowitej
  • obsługuje użycie side-by-side z nieuporządkowanymi testami. Nieuporządkowane testy są wykonywane jako pierwsze.

Biblioteka jest zainspirowana tym, jak MSTest wykonuje testowanie zamówień z plikami .orderedtest. Proszę spojrzeć na przykład poniżej.

[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
}
 1
Author: Sebazzz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-15 12:05:50

Nie należy zależeć od kolejności, w jakiej framework testowy wybiera testy do wykonania. testy powinny być izolowane i niezależne. W tym, że nie powinny one zależeć od jakiegoś innego testu ustawienie sceny dla nich lub Sprzątanie po nich. Powinny one również dawać ten sam wynik niezależnie od kolejności wykonania testów (dla danego migawki SUT)

Trochę wygooglowałem. Jak zwykle niektórzy uciekają się do podstępnych sztuczek (zamiast rozwiązywać podstawowa kwestia testowalności / projektowania

  • nazywanie testów w porządku alfabetycznym tak, aby testy pojawiały się w kolejności, w jakiej są "potrzebne" do wykonania. Jednak NUnit może zmienić to zachowanie w późniejszym wydaniu, a następnie testy zostaną zawieszone. Lepiej sprawdzić w bieżących binariach NUnit do kontroli źródła.
  • VS (IMHO zachęcające do niewłaściwego zachowania z ich 'zwinnymi narzędziami') ma coś, co nazywa się "uporządkowanymi testami" w ich ramach testowania MS. Nie. trać czas na czytanie, ale wydaje się, że jest skierowany do tej samej grupy odbiorców.]}

Zobacz też: charakterystyka dobrego testu

 0
Author: Gishu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:54:58

Jeśli używasz [TestCase], argument TestName zawiera nazwę testu.

Jeśli nie podano, generowana jest nazwa na podstawie nazwy metody i podanych argumentów.

Możesz kontrolować kolejność wykonania testu, jak podano poniżej:

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

Tutaj użyłem nazwy metody "ExpressionTest" przyrostek z liczbą.

Możesz używać dowolnych nazw uporządkowanych Alfabetycznie zobacz atrybut TestCase

 0
Author: M.Hassan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-25 17:47:46