15 ответов:
модульные тесты должны быть способны работать независимо и автономно. Если они удовлетворяют этому критерию, то порядок не имеет значения.
однако есть случаи, когда вы захотите сначала выполнить определенные тесты. Типичным примером является ситуация непрерывной интеграции, когда некоторые тесты выполняются дольше, чем другие. Мы используем атрибут category, чтобы мы могли запускать тесты, которые используют насмешки перед тестами, которые используют базу данных.
т. е. положить это в начале ваших быстрых тестов
[Category("QuickTests")]где у вас есть тесты, которые зависят от определенных условий окружающей среды, рассмотрим!--8-->TestFixtureSetUp и TestFixtureTearDown атрибуты, которые позволяют вам отмечать методы, которые будут выполняться до и после ваших тестов.
Я просто хочу отметить, что хотя большинство респондентов предположили, это были модульные тесты, вопрос не уточнил, что они были.
nUnit является отличным инструментом, который может быть использован для различных ситуаций тестирования. Я вижу соответствующие причины для того, чтобы контролировать порядок испытаний.
в этих ситуациях мне пришлось прибегнуть к включению порядка запуска в имя теста. Было бы здорово иметь возможность указать порядок выполнения с помощью атрибута.
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() { ... } }
желая, чтобы тесты выполнялись в определенном порядке, это не означает, что тесты зависят друг от друга - на данный момент я работаю над проектом TDD, и будучи хорошим TDDer, я издевался/заглушал все, но это сделало бы его более читаемым, если бы я мог указать порядок, в котором результаты тестов отображается - тематически, а не по алфавиту. Пока единственное, что я могу придумать, это добавить a_ b_ c_ к классам классам, пространствам имен и методам. (Нехорошо) я думаю атрибут [TestOrderAttribute] был бы хорош - не строго следовать рамкой, но подсказкой, чтобы мы могли достичь этого
независимо от того, являются ли тесты зависимыми от порядка... некоторые из нас просто хотят контролировать все, упорядоченно.
модульные тесты обычно создаются в порядке сложности. Итак, почему они не должны также выполняться в порядке сложности или порядке, в котором они были созданы?
лично я бы хотел увидеть тесты в том порядке, в котором я их создал. В TDD каждый последующий тест, естественно, будет более сложным и займет больше времени для запуска. Я бы предпочел сначала увидеть более простой тест, так как это будет лучшим индикатором причины сбоя.
но я также вижу преимущество их запуска в случайном порядке, особенно если вы хотите проверить, что ваши тесты не имеют никаких зависимостей от других тестов. Как насчет добавления опции для тестирования бегунов, чтобы "запускать тесты случайным образом, пока не остановится"?
Я тестирую с селеном на довольно сложном веб-сайте, и весь набор тестов может работать более получаса, и я еще не близок к тому, чтобы охватить все приложение. Если я должен убедиться, что все предыдущие формы заполнены правильно для каждого теста, это добавляет много времени, а не только небольшое количество времени, к общему тесту. Если есть слишком много накладных расходов на выполнение тестов, люди не будут запускать их так часто, как они должны.
Итак, я привел их в порядок и зависят от предыдущих тестов, чтобы текстовые поля и таким образом. Я использую Assert.Игнорируйте (), когда предварительные условия недействительны, но мне нужно, чтобы они работали по порядку.
Мне очень нравится предыдущий ответ.
Я немного изменил его, чтобы иметь возможность использовать атрибут для установки диапазона порядка:
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); } } } } } }
Я знаю, что это относительно старый пост, но вот еще один способ сохранить ваш тест в порядке, не делая имена тестов неудобными. Используя атрибут 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"); } } } }
Я работаю с Selenium WebDriver сквозными тестовыми случаями пользовательского интерфейса, написанными на C#, которые запускаются с использованием NUnit framework. (Не единичные случаи как таковые)
эти тесты пользовательского интерфейса, безусловно, зависят от порядка выполнения, так как другой тест должен добавить некоторые данные в качестве предварительного условия. (Это не представляется возможным сделать шаги в каждом тесте)
теперь, после добавления 10-го тестового случая, я вижу, что NUnit хочет работать в этом порядке: Test_1 Test_10 Test_2 Test_3 ..
Так что я думаю, я тоже на данный момент алфавитизируйте имена тестовых случаев, но было бы неплохо добавить эту небольшую функцию управления порядком выполнения в NUnit.
[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 }
есть очень веские причины использовать механизм заказа тестов. Большинство моих собственных тестов используют хорошую практику, такую как настройка/демонтаж. Другие требуют огромных объемов настройки данных, которые затем могут быть использованы для тестирования ряда функций. До сих пор я использовал большие тесты для обработки этих (Selenium Webdriver) интеграционных тестов. Однако, я думаю, что выше предложенный пост на https://github.com/nunit/docs/wiki/Order-Attribute имеет много заслуг. Вот пример того, почему заказ был бы чрезвычайно ценным:
- использование Selenium Webdriver для запуска теста для загрузки отчета
- состояние отчета (независимо от того, загружается он или нет) кэшируется для 10 минут
- это означает, что перед каждым тестом мне нужно сбросить состояние отчета, а затем подождать до 10 минут перед подтверждением изменения состояния, а затем проверьте правильность загрузки отчета.
- отчеты не могут генерироваться практически / своевременно с помощью насмешек или любого другого механизма в рамках теста из-за их сложности.
это 10-минутное время ожидания замедляет набор тестов. Когда вы умножаете подобные задержки кэширования на множество тестов, это занимает много времени. Упорядочение тестов может позволить выполнить настройку данных как" тест " прямо в начале набора тестов, при этом тесты, основанные на кеше, будут выполняться к концу теста бежать.
этот вопрос действительно стар сейчас, но для людей, которые могут достичь этого от поиска, я взял отличные ответы от user3275462 и PvtVandals / Rico и добавил их к репозитории GitHub вместе с некоторыми из моих собственных обновлений. Я тоже создал связанный блог дополнительную информацию вы можете посмотреть на Подробнее.
надеюсь, что это полезно для вас всех. Кроме того, мне часто нравится использовать атрибут Category для дифференциации моей интеграции тесты или другие сквозные тесты с тесты. Другие отметили, что модульные тесты не должны иметь зависимости от порядка, но другие типы тестов часто это делают, поэтому это обеспечивает хороший способ запускать только ту категорию тестов, которую вы хотите, а также заказывать эти сквозные тесты.
Я удивлен, что сообщество 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 }
вы не должны зависеть от порядка, в котором платформа тестирования выбирает тесты для выполнения. тесты должны быть изолированными и независимыми. В том, что они не должны зависеть от какого-то другого теста заводя их или убирать за ними. Они также должны давать один и тот же результат независимо от порядка выполнения тестов (для данного снимка SUT)
Я немного погуглил. Как обычно, некоторые люди прибегают к хитрым трюкам (вместо того, чтобы решение основной проблемы тестируемости / дизайна
- именование тестов в алфавитном порядке таким образом, чтобы тесты отображались в том порядке, в котором они "должны" выполняться. Однако NUnit может изменить это поведение с более поздним выпуском,а затем ваши тесты будут закрыты. Лучше проверить текущие двоичные файлы NUnit в системе управления версиями.
- VS (IMHO поощряет неправильное поведение с помощью своих "гибких инструментов") имеет что-то, называемое "упорядоченными тестами" в их MS рамки тестирования. Я не тратил время на чтение, но он, кажется, ориентирован на ту же аудиторию
Читайте Также: характеристики хорошего теста
если вы используете
[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 Атрибут
Comments