NUnit Test Run Order - программирование
Подтвердить что ты не робот

NUnit Test Run Order

По умолчанию тесты nunit выполняются в алфавитном порядке. Кто-нибудь знает, как установить порядок выполнения? Существует ли для этого атрибут?

4b9b3361

Ответ 1

Каждый юнит-тест должен работать независимо и автономно. Если они удовлетворяют этому критерию, тогда порядок не имеет значения.

Однако есть случаи, когда вы захотите сначала запустить определенные тесты. Типичным примером является ситуация с непрерывной интеграцией, когда некоторые тесты более продолжительные, чем другие. Мы используем атрибут категории, чтобы мы могли запускать тесты, которые используют насмешку перед тестами, которые используют базу данных.

то есть. положите это на начало ваших быстрых тестов

[Category("QuickTests")]

Если у вас есть тесты, зависящие от определенных условий окружающей среды, рассмотрите атрибуты TestFixtureSetUp и TestFixtureTearDown, которые позволяют вам отмечать методы, которые будут выполняться до и после ваших тестов.

Ответ 2

Я просто хочу отметить, что, хотя большинство респондентов предполагали, что это были единичные тесты, вопрос не указывал, что они были.

nUnit - отличный инструмент, который можно использовать для различных тестовых ситуаций. Я вижу соответствующие причины для того, чтобы контролировать порядок тестирования.

В таких ситуациях мне приходилось прибегать к включению порядка выполнения в тестовое имя. Было бы замечательно иметь возможность указывать порядок выполнения с использованием атрибута.

Ответ 3

В NUnit 3.2.0 добавлен OrderAttribute, см.

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

Пример:

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


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

    [Test]
    public void TestC() { ... }
}

Ответ 4

Желание запуска тестов в определенном порядке не означает, что тесты зависят друг от друга - сейчас я работаю над проектом TDD и, будучи хорошим TDDer, я издевался над всем, но это сделало бы его более читаемым, если бы я мог указать порядок отображения результатов тестов - тематически, а не в алфавитном порядке. До сих пор единственное, что я могу придумать, - это дополнить класс________ классами классам, пространствам имен и методам. (Неплохо) Я думаю, что атрибут [TestOrderAttribute] был бы хорош - за ним не следует строго рамки, а подсказка, чтобы мы могли достичь этого

Ответ 5

Независимо от того, зависят или нет тесты, зависит от порядка... некоторые из нас просто хотят контролировать все, упорядоченным образом.

Модульные тесты обычно создаются в порядке сложности. Итак, почему они не должны запускаться в порядке сложности или порядка, в котором они были созданы?

Лично мне нравится, чтобы тесты выполнялись в том порядке, в котором я их создал. В TDD каждый последующий тест, естественно, будет более сложным и займет больше времени для запуска. Я предпочел бы, чтобы более простой тест завершился с ошибкой, так как он станет лучшим индикатором причины сбоя.

Но я также вижу преимущество запуска их в случайном порядке, особенно если вы хотите проверить, что ваши тесты не имеют каких-либо зависимостей от других тестов. Как насчет добавления опции для проверки бегунов на "Запуск тестов в случайном порядке до остановки"?

Ответ 6

Я тестирую Selenium на довольно сложном веб-сайте, и весь набор тестов может работать более полутора часов, и я пока не готов охватить все приложение. Если мне нужно убедиться, что все предыдущие формы заполнены правильно для каждого теста, это добавляет много времени, а не только небольшое количество времени, к общему тесту. Если на выполнение тестов слишком много накладных расходов, люди не будут запускать их так часто, как должны.

Итак, я приводил их в порядок и полагался на предыдущие тесты, чтобы иметь текстовые поля и такие завершены. Я использую Assert.Ignore(), когда предварительные условия недействительны, но мне нужно, чтобы они выполнялись в порядке.

Ответ 7

Мне очень нравится предыдущий ответ.

Я немного изменил его, чтобы использовать атрибут для установки диапазона заказа:

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

            }
        }
    }
}

Ответ 8

Я знаю, что это относительно старое сообщение, но вот еще один способ сохранить ваш тест в порядке, не делая имена тестов неудобными. С помощью атрибута TestCaseSource и наличия объекта, в котором вы проходите, есть делегат (Action), вы можете полностью не только контролировать заказ, но и называть тестом, что это такое.

Это работает, потому что, согласно документации, элементы коллекции, возвращенные из тестового источника, будут всегда выполняться в том порядке, в котором они перечислены.

Вот демонстрация презентации, которую я даю завтра:

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

Ответ 9

Я работаю над сквозными тестовыми примерами Selenium WebDriver, написанными на С#, которые запускаются с использованием инфраструктуры NUnit. (Не единичные случаи как таковые)

Эти тесты пользовательского интерфейса, безусловно, зависят от порядка выполнения, так как другим тестам необходимо добавить некоторые данные в качестве предварительного условия. (Невозможно выполнить шаги в каждом тесте)

Теперь, после добавления 10-го тестового примера, я вижу, что NUnit хочет работать в следующем порядке: Test_1 Test_10 Test_2 Test_3 ..

Итак, я думаю, что я должен теперь в алфавитном порядке называть имена тестовых случаев, но было бы неплохо иметь эту небольшую функцию для управления порядком выполнения, добавленным в NUnit.

Ответ 10

Обычно Unit Test должен быть независимым, но если вам нужно, вы можете назвать свои методы в алфавитном порядке ex:

[Test]
public void Add_Users(){}

[Test]
public void Add_UsersB(){}

[Test]
public void Process_Users(){}

или вы можете сделать.

        private void Add_Users(){}

        private void Add_UsersB(){}

        [Test]
        public void Process_Users()
        {
           Add_Users();
           Add_UsersB();
           // more code
        }

Ответ 11

Есть очень веские причины для использования механизма тестового заказа. Большинство моих собственных тестов используют передовую практику, такую ​​как установка/срыв. Другие требуют огромных объемов настройки данных, которые затем могут использоваться для тестирования ряда функций. До сих пор я использовал большие тесты для обработки этих тестов (Selenium Webdriver). Тем не менее, я думаю, что вышеуказанный пост на https://github.com/nunit/docs/wiki/Order-Attribute имеет много преимуществ. Вот пример того, почему упорядочение было бы чрезвычайно ценным:

  • Использование Selenium Webdriver для запуска теста для загрузки отчета
  • Состояние отчета (независимо от того, загружается оно или нет) кэшируется в течение 10 минут.
  • Это означает, что перед каждым тестом мне нужно reset состояние отчета, а затем подождите до 10 минут, пока состояние не будет подтверждено, и убедитесь, что отчет загружен правильно.
  • Отчеты не могут быть сгенерированы на практике/своевременно через насмешливый или какой-либо другой механизм в рамках теста из-за их сложности.

Это 10-минутное время ожидания замедляет набор тестов. Когда вы умножаете подобные задержки кеширования на множество тестов, он потребляет много времени. Заказные тесты могут позволить выполнить настройку данных как "Тест" в начале набора тестов, при этом тесты, основанные на том, что кеш будет выполнен, будут выполнены в конце тестового прогона.

Ответ 12

Этот вопрос действительно старый, но для людей, которые могут достичь этого от поиска, я взял отличные ответы от user3275462 и PvtVandals/Rico и добавил их в Репозиторий GitHub вместе с некоторыми из моих собственных обновлений. Я также создал связанное сообщение в блоге с дополнительной информацией, на которую вы можете посмотреть дополнительную информацию.

Надеюсь, это поможет всем вам. Кроме того, мне часто нравится использовать атрибут Category, чтобы отличать мои интеграционные тесты или другие сквозные тесты от моих фактических модульных тестов. Другие отметили, что модульные тесты не должны иметь зависимость от заказа, но часто используются другие типы тестов, поэтому это дает хороший способ запускать только категорию тестов, а также заказывать эти сквозные тесты.

Ответ 13

Я удивлен, что сообщество NUnit ничего не придумало, поэтому я сам создал что-то подобное.

Я сейчас разрабатывает библиотеку с открытым исходным кодом, которая позволяет вам заказывать ваши тесты с помощью NUnit. Вы можете заказать тестовые светильники и заказать "заказные спецификации испытаний".

Библиотека предлагает следующие функции:

  • Построить сложные иерархии порядка тестирования
  • Пропустить последующие тесты, если тест не в порядке
  • Закажите ваши методы тестирования по зависимости вместо целочисленного порядка.
  • Поддерживает использование бок о бок с неупорядоченными тестами. Сначала выполняются неупорядоченные тесты.

На самом деле библиотека вдохновлена ​​тем, как MSTest выполняет тестирование с помощью .orderedtest файлов. Посмотрите пример ниже.

[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
}

Ответ 14

Вы не должны зависеть от порядка, в котором тестовая структура выбирает тесты для выполнения. Тесты должны быть изолированными и независимыми. В этом случае они не должны зависеть от какой-либо другой тестовой установки для сцены или очистки после них. Они также должны давать одинаковый результат независимо от порядка выполнения тестов (для данного моментального снимка SUT)

Я немного погубил. Как обычно, некоторые люди прибегают к подлым трюкам (вместо того, чтобы решать основную проблему проверки/дизайна

  • именовать тесты в алфавитном порядке, чтобы тесты отображались в том порядке, в котором они должны быть выполнены. Однако NUnit может изменить это поведение с более поздним выпуском, а затем ваши тесты будут закрыты. Лучше проверить текущие двоичные файлы NUnit на Source Control.
  • VS (IMHO, поощряющий неправильное поведение с их "гибкими инструментами" ) имеет что-то, называемое "упорядоченные тесты" в их среде тестирования MS. Я не тратил время на чтение, но, похоже, он нацелен на ту же аудиторию.

См. также: характеристики хорошего теста

Ответ 15

Если вы используете [TestCase], аргумент TestName предоставляет имя для теста.

Если не указан, имя генерируется на основе имени метода и предоставленных аргументов.

Вы можете контролировать порядок выполнения теста, как указано ниже:

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

Здесь я использовал суффикс "ExpressionTest" имени метода с номером.

Вы можете использовать любые имена в алфавитном порядке, см. Атрибут TestCase

Ответ 16

В случае использования TestCaseSource ключ должен override string ToString метод override string ToString, как это работает:

Предположим, у вас есть класс TestCase

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

И список тестовых случаев:

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

Теперь давайте использовать его с методом Test и посмотрим, что произойдет:

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

Это не будет проверять по порядку, и результат будет таким:

enter image description here

Так что, если мы добавили override string ToString в наш класс, например:

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

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

Результат изменится, и мы получим заказ и название теста, например:

enter image description here

Замечания:

  1. Это просто пример, чтобы проиллюстрировать, как получить имя и порядок в тесте, порядок принимается численно/в алфавитном порядке, поэтому, если у вас более десяти тестов, я предлагаю сделать Тест 01, Тест 02.... Тест 10, Тест 11 и т.д., Потому что если вы делаете Тест 1 и в какой-то момент Тест 10, чем порядок будет Тест 1, Тест 10, Тест 2 и т.д.
  2. Входными данными и ожидаемыми могут быть любые типы, строки, объекты или пользовательские классы.
  3. Помимо порядка, здесь хорошо то, что вы видите название теста, которое является более важным.