Порядок выполнения теста NUnit


110

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


7
Зачем вам это нужно? Похоже, у вас есть зависимость от порядка выполнения, а это плохо. Вам нужно пересмотреть, почему вы этого хотите. Модульные тесты должны выполняться изолированно и быть полностью независимыми от других. Похоже, вы создаете кандидатов для теста Erratic Tests .
RichardOD

Это похоже на дубликат, но вы можете увидеть мой ответ здесь
Джонно Нолан,

12
@RichardOD - надо! = Обязательно. И на самом деле это не обязательно, потому что на самом деле почти все интеграционные тесты выполняются по порядку - спросите команду QA, не изменяют ли они порядок своего тестирования случайным образом.
tymtam

4
В настоящее время у меня есть несколько тестов, порядок которых кажется важным, хотя и не должен. Лично я хотел бы иметь способ рандомизировать порядок тестов специально, чтобы помочь мне убедиться, что мои тесты НЕ ЯВЛЯЮТСЯ каким-то образом зависимым от порядка. Конечно, я ДЕЙСТВИТЕЛЬНО хотел бы, чтобы средство запуска тестов запускало все мои тесты в случайном порядке, пока не обнаружит проблему или я не скажу «стоп». Если бы я провел это в течение ночи, а утром все было еще зеленым, то я мог бы быть уверен, что устранил последний из непреднамеренных побочных эффектов.
Mel

1
этот вопрос стал бы более актуальным, если бы вопрос был обновлен, чтобы указать, что мы говорим здесь об интеграционных тестах ... Мы все знаем правила модульного тестирования, по крайней мере, если вы читали тестовые шаблоны XUnit и следовали за дядей Бобом и т. д. вы делаете ... но такие фреймворки, как NUnit, также действительно полезны для быстрого запуска и запуска интеграционных тестов ... и вы определенно не хотите, чтобы они были случайными, особенно когда задействована дорогостоящая настройка базы данных ...
nrjohnstone

Ответы:


51

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

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

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

[Category("QuickTests")]

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


2
@Chris, я обычно не использую эти атрибуты, это интересный пост в блоге jamesnewkirk.typepad.com/posts/2007/09/why-you-should-.html . Тем не менее, хороший момент по поводу категорийных тестов.
RichardOD

29
Другой пример тестов, зависящих от порядка, - это когда вы хотите использовать структуру nunit для запуска теста интеграции ...
Байрон Росс

1
@ByronRoss: Я стараюсь делать тесты крупнее, когда я это делаю, и максимально опираюсь на существующие модульные тесты, чтобы писать меньше тестов. Тогда каждый полный проход может дать сбой отдельно. Я также стараюсь спроектировать свои данные так, чтобы они могли существовать отдельно от существующих данных, а не зависеть от существующих данных.
Мерлин Морган-Грэм

1
Если вы не запускаете тесты в случайном порядке, как вы можете убедиться, что они действительно работают, когда они выходят из строя? То, что вы говорите, аналогично высказыванию: «Если в вашем программном обеспечении нет ошибок, тестирование невозможно».
jforberg

@jforberg: Если у вас случайный сбой, как вы его исправили?
NeedHack

176

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

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

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


Вы имеете в виду, что вы позвонили на свои тесты, например, 001_first_test 002_second_testи так далее?
ashes999

Да, верно, хотя я обычно использую шаблон, который позволяет мне легко вставлять тесты при необходимости, так что, возможно, 010_first_test, 020_second_test и т. Д.
Les,

84
Спасибо за единственный разумный ответ здесь. Это конкретный вопрос, но за какие-то расплывчатые педантичные ответы он получает поддержку. Да, все мы знаем, какими должны быть модульные тесты, но вопрос не в этом.
Егор Павлихин

1
Не следует полагаться на алфавитный порядок выполнения. Многие участники тестирования запускают ваши тесты одновременно во многих потоках или процессах и не обязательно в алфавитном порядке. Например, NCrunch определяет приоритеты тестов на основе кода, который вы изменяете (затронутые тесты), затем от того, не удалось ли они в прошлый раз, а затем от того, выполняются ли они быстро или медленно. Если вам нужен определенный порядок , просто создайте мета-бегун для этих тестов и исключите их из обычных прогонов.
Abel

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

125

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() { ... }
}

5
Спасибо, прямо в точку, что я искал - и никаких обсуждений, почему это хорошо или плохо :)
aknoepfel 01

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

Вы всегда можете начать с очень больших чисел, таких как миллионы или что-то в этом роде, если хотите таким образом ввести средние элементы - просто больше набора текста. Imo, должен быть более простой способ упорядочить вещи, чем использовать числа для приоритета, например, дерево зависимостей методов, но у каждого есть свои недостатки / преимущества.
Рэзван Флавиус Панда

9
Хороший ответ, но будьте осторожны, в документации указано, что тесты не дожидаются завершения предыдущих тестов.
ROX

Интересно, что по моему опыту, если мы добавим атрибуты Test и Order отдельно, нет гарантии упорядочивания тестов.
AT

22

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


10

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

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

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

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


9

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

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


1
Полностью. Я здесь в одной лодке.
Sleeper Smith

Я тоже! Именно поэтому я остановился на этом вопросе!
Niklas Wulff

@NiklasRingdahl, если вы используете Visual Studio с nunit, создайте дамп nunit и используйте тесты MS. тогда вы можете использовать файл OrderTest от Visual Studio, чтобы расположить тестовые примеры в том порядке, в котором вы хотите, чтобы они выполнялись
Рахул Лодха,

@RahulLodha Спасибо! Я займусь этим.
Niklas Wulff

9

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

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

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

            }
        }
    }
}

Я считаю, что это отличный подход. Однако обратите внимание, что код отражения будет использовать все методы с атрибутом, поэтому, если вы пытаетесь запустить конкретное тестовое устройство, вы можете быть удивлены, обнаружив, что он работает больше, чем вы думали. Вы можете легко изменить запрос LINQ, если это нежелательное поведение. См. Ссылки в моем ответе для получения дополнительной информации.
Chrispy

OrderedTestбольше не поддерживается в NUnit 3.
Конрад,

7

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

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

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

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

Я использую этот шаблон для параллельных интеграционных тестов, которые потребуют слишком много времени для линейного выполнения. Все тесты относятся к одному типу, поэтому я использую Action <T in>, и у каждого Action есть ключ, который говорит, что делает «ShouldBeFoo». Таким образом, то, что делает тест, будет видно в имени теста, а TestCaseSource можно будет отфильтровать, чтобы различные типы тестов были сгруппированы вместе. По иронии судьбы меня не волнует порядок исполнения, но я согласен, что это сработает.
Новатерата

Использование в TestCaseSourceкачестве способа запуска упорядоченных тестов - это гениальный ход. Отлично сработано. Я использовал этот подход вместе с приведенным ниже и добавил несколько дополнительных модификаций, чтобы упростить его использование. См. Ссылки в моем ответе для получения дополнительной информации, но основная идея взята из этого отличного ответа!
Chrispy

К сожалению, с NUnit 3 источник TestCaseSourceдолжен быть статическим, что исключает использование шаблона. Облом.
Конрад,

@ Конрад. Я не понимаю, какая разница, делает метод статическим или нет. В любом случае тест по-прежнему вернется в порядок.
Дэйв Буш,

Это не тот метод, который должен быть статическим - источник (переменная или свойство) TestCaseSourceдолжен быть статическим объектом в NUnit 3, иначе тесты не будут выполняться. И вы не можете создавать динамические объекты внутри статического объекта. Вот почему это не сработает в версии 3.
Конрад,

5

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

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

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

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


9
Не согласен с Арраном: тесты пользовательского интерфейса по своей сути представляют собой последовательность небольших шагов. Каждый шаг должен быть тестом (причина - если он не удастся, мне нужно знать, какой шаг). Последовательности могут быть независимыми, но внутри последовательности важен порядок и необходима остановка в случае сбоя.
Zasz

3

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

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

2
Только теперь имена нужно делать в алфавитном порядке, что является ужасным решением. :(

@ user166390 - не это не ужасно. Это работает и зависит от документированного поведения NUnit.
tymtam

➕1 Достаточно хорошо для меня, намного проще, если вы начнете свои тесты a_ b_ t1_, t2_вместо этого или полагаясь на легко пропустить завершающие символы
Крис Марисик

3

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

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

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


2

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

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


Можете ли вы помочь мне с проблемой, которая у меня есть, вот ссылка: stackoverflow.com/questions/31281395/…
Морган Сорен

1

Я удивлен, что сообщество 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
}

1

Если вы используете [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


0

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

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

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

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


Бывают случаи, когда вы хотите, чтобы тесты выполнялись быстрее, чем длительные, особенно в интеграционных и приемочных тестах. Например, в приложении для ведения блога: вы сначала проверяете логин, потому что, если эта функция не работает, публикация также не будет работать, поэтому нет смысла выполнять этот тест (вы можете остановить бегуна вручную). Но если вы попытаетесь продолжать тесты, то на это уйдет больше времени.
Марсель Вальдес Ороско

@MarcelValdezOrozco - вы можете достичь этой цели, разделив свои тесты либо с помощью разных физических dll, либо с помощью тегов / категорий. Вы можете создавать свои сценарии сборки для запуска dll / категорий по порядку. В общем, разрешение упорядочивания тестов обычно приводит к объединенным тестам, которые развивают зависимости от соседних тестов (конечно, со временем). AFAIR в следующем большом выпуске NUnit будет поддерживать различный порядок тестов, например случайный и т. Д.
Gishu

2
Дальнейшее разделение тестов одного и того же типа (например, приемочные тесты) не имеет смысла, а разделение их на другую DLL излишне увеличивает сложность повсюду: исходный код, сценарии сборки, сценарии тестирования, структура проекта и т. Д. Просто чтобы просто переупорядочить тесты.
Марсель Вальдес Ороско,

Излучение (так что в основном все имитирующие библиотеки) - причина, по которой порядок важен. Вы не можете выгрузить домен своего приложения, а средство выполнения nunit (при выполнении всех тестов в сборке) сохраняет этот домен для всех тестов по крайней мере в этом «исправлении». Если один тест создает типы для проверки чего-либо, а другой тест конфликтует с этим созданным типом из-за порядка, это не ошибочный тест. Они логически изолированы, просто nUnit не обеспечивает должной изоляции между каждым «тестом».
Келли Элтон

6
Это довольно снисходительный ответ, и он делает его забавным, потому что он действительно применим только к модульным тестам и полностью игнорирует прагматичность.
tymtam

0

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

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

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

И список 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
        }
    };
}

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

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

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

введите описание изображения здесь

Итак, если мы добавим 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;
    }
}

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

введите описание изображения здесь

Примечание:

  1. Это просто пример, чтобы проиллюстрировать, как получить имя и порядок в тесте, порядок берется в числовом / алфавитном порядке, поэтому, если у вас более десяти тестов, я предлагаю сделать Test 01, Test 02 .... Test 10, Test 11 и т. Д., Потому что если вы выполняете Тест 1, а в какой-то момент Тест 10, тогда порядок будет Тест 1, Тест 10, Тест 2 и т. д.
  2. Input и Expected могут быть любого типа, строки, объекта или настраиваемого класса.
  3. Помимо порядка, здесь хорошо то, что вы видите имя теста, которое более важно.
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.