Есть ли у MSTest эквивалент TestCase от NUnit?

107

Я считаю эту TestCaseфункцию в NUnit весьма полезной как быстрый способ указать параметры теста без необходимости использовать отдельный метод для каждого теста. Есть ли что-нибудь подобное в MSTest?

 [TestFixture]  
 public class StringFormatUtilsTest  
 {  
     [TestCase("tttt", "")]  
     [TestCase("", "")]  
     [TestCase("t3a4b5", "345")]  
     [TestCase("3&5*", "35")]  
     [TestCase("123", "123")]  
     public void StripNonNumeric(string before, string expected)  
     {  
         string actual = FormatUtils.StripNonNumeric(before);  
         Assert.AreEqual(expected, actual);  
     }  
 }  
Tjjjohnson
источник
Аналогичный вопрос см. Stackoverflow.com/questions/347535/how-to-rowtest-with-mstest/…
Майкл Фрейдгейм
Почему вы не используете NUnit?
Майк де Клерк
1
@MikedeKlerk: Nunit невероятно медленный, если вы используете Entity Framework ... Очевидно, он отражается на всех ваших сгенерированных классах каждый раз, когда вы запускаете тест.
Роберт Харви,
Вообще говоря, NUnit имеет больше функций, чем MSTest, если вы используете MSTest только для того, чтобы иметь возможность запускать свои тесты с помощью VS Test Explorer, вы можете сделать то же самое с NUnit, установив расширение NUnit Test Adapter через NuGet
Stacked
1
Попробуйте DataRow(), см .: blogs.msdn.microsoft.com/devops/2016/06/17/…
Бабак

Ответы:

62

Недавно Microsoft анонсировала «MSTest V2» (см. Статью в блоге ). Это позволяет последовательно (рабочий стол, UWP, ...) использовать DataRow-attribute!

 [TestClass]  
 public class StringFormatUtilsTest  
 {  
     [DataTestMethod]  
     [DataRow("tttt", "")]  
     [DataRow("", "")]  
     [DataRow("t3a4b5", "345")]  
     [DataRow("3&5*", "35")]  
     [DataRow("123", "123")]  
     public void StripNonNumeric(string before, string expected)  
     {  
         string actual = FormatUtils.StripNonNumeric(before);  
         Assert.AreEqual(expected, actual);  
     }  
 } 

Опять же, обозреватель тестов Visual Studio Express, к сожалению, не распознает эти тесты. Но, по крайней мере, «полные» версии VS теперь поддерживают эту функцию!

Чтобы использовать его, просто установите пакеты NuGet MSTest.TestFramework и MSTest.TestAdapter (оба предварительные выпуски на данный момент).

Старый ответ:

Если вам не нужно придерживаться MSTest, и вы просто используете его для запуска тестов через Test Explorer потому что у вас есть только версия Visual Studio Express, то это может быть решением для вас:

Существует расширение VsTestAdapter VSIX для возможности запускать тесты NUnit через обозреватель тестов. К сожалению, пользователи VS Express не могут устанавливать расширения ... Но, к счастью, VsTestAdapter поставляется с простым пакетом NuGet !

Итак, если вы пользователь VS Express, просто установите NuGet-пакет VsTestAdapter и наслаждайтесь запуском тестов / тестовых наборов NUnit через обозреватель тестов!


К сожалению, вышеупомянутое утверждение не соответствует действительности. Хотя вполне возможно установить пакет через выпуск Express, это бесполезно, так как он не может использовать Test Explorer. Ранее было примечание о более старой версии TestAdapter, которая была удалена со страницы описания 2.0.0 :

Обратите внимание, что это не работает с VS Express

khlr
источник
4
MSTest «v2» теперь является фреймворком по умолчанию при использовании VS 2017. Теперь, когда это будет поддерживаться OOTB в последней версии, эта информация, вероятно, должна быть в верхней части ответа.
Marc L.
34

Я знаю, что это запоздалый ответ, но, надеюсь, это поможет другим.

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

https://github.com/Thwaitesy/MSTestHacks

1) Установите пакет NuGet .

2) Наследуйте свой тестовый класс от TestBase

public class UnitTest1 : TestBase
{ }

3) Создайте свойство, поле или метод, который возвращает IEnumerable

[TestClass]
public class UnitTest1 : TestBase
{
    private IEnumerable<int> Stuff
    {
        get
        {
            //This could do anything, get a dynamic list from anywhere....
            return new List<int> { 1, 2, 3 };
        }
    }
}

4) Добавьте атрибут MSTest DataSource в свой тестовый метод, указав на имя IEnumerable выше. Это должно быть полностью квалифицировано.

[TestMethod]
[DataSource("Namespace.UnitTest1.Stuff")]
public void TestMethod1()
{
    var number = this.TestContext.GetRuntimeDataSourceObject<int>();

    Assert.IsNotNull(number);
}

Конечный результат: 3 итерации, как в обычном DataSource :)

using Microsoft.VisualStudio.TestTools.UnitTesting;
using MSTestHacks;

namespace Namespace
{
    [TestClass]
    public class UnitTest1 : TestBase
    {
        private IEnumerable<int> Stuff
        {
            get
            {
                //This could do anything, get a dynamic list from anywhere....
                return new List<int> { 1, 2, 3 };
            }
        }

        [TestMethod]
        [DataSource("Namespace.UnitTest1.Stuff")]
        public void TestMethod1()
        {
            var number = this.TestContext.GetRuntimeDataSourceObject<int>();

            Assert.IsNotNull(number);
        }
    }
}
Thwaitesy
источник
Будет ли это работать с несколькими параметрами для каждого случая?
Lonefish
Поскольку в базовую библиотеку были внесены изменения, это не работает с MsTest «v2» . Это значение по умолчанию для VS15 (VS 2017).
Marc L.
3
Да, если вы используете MSTest V2, есть новый поставщик тестовых примеров, похожий на NUnit. Таким образом , нет необходимости в этой работе вокруг 👏
Thwaitesy
Похоже, что это не работает в VS 2015, файл конфигурации приложения не заполняется динамически, и поэтому источники данных не найдены
Рид
13

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

Например, предположим, что у вас есть такой метод расширения:

public static class Extensions
{
    /// <summary>
    /// Get the Qtr with optional offset to add or subtract quarters
    /// </summary>
    public static int GetQuarterNumber(this DateTime parmDate, int offset = 0)
    {
        return (int)Math.Ceiling(parmDate.AddMonths(offset * 3).Month / 3m);
    }
}

Вы можете использовать массив анонимных типов в сочетании с LINQ для написания таких тестов:

[TestMethod]
public void MonthReturnsProperQuarterWithOffset()
{
    // Arrange
    var values = new[] {
        new { inputDate = new DateTime(2013, 1, 1), offset = 1, expectedQuarter = 2},
        new { inputDate = new DateTime(2013, 1, 1), offset = -1, expectedQuarter = 4},
        new { inputDate = new DateTime(2013, 4, 1), offset = 1, expectedQuarter = 3},
        new { inputDate = new DateTime(2013, 4, 1), offset = -1, expectedQuarter = 1},
        new { inputDate = new DateTime(2013, 7, 1), offset = 1, expectedQuarter = 4},
        new { inputDate = new DateTime(2013, 7, 1), offset = -1, expectedQuarter = 2},
        new { inputDate = new DateTime(2013, 10, 1), offset = 1, expectedQuarter = 1},
        new { inputDate = new DateTime(2013, 10, 1), offset = -1, expectedQuarter = 3}
        // Could add as many rows as you want, or extract to a private method that
        // builds the array of data
    }; 
    values.ToList().ForEach(val => 
    { 
        // Act 
        int actualQuarter = val.inputDate.GetQuarterNumber(val.offset); 
        // Assert 
        Assert.AreEqual(val.expectedQuarter, actualQuarter, 
            "Failed for inputDate={0}, offset={1} and expectedQuarter={2}.", val.inputDate, val.offset, val.expectedQuarter); 
        }); 
    }
}

При использовании этого метода полезно использовать форматированное сообщение, включающее входные данные в Assert, чтобы помочь вам определить, какая строка вызывает сбой теста.

Я писал об этом решении с более подробной информацией и подробностями на AgileCoder.net .

Гэри Рэй
источник
4
Самая большая проблема с этим заключается в том, что если какой-либо случай выходит из массива значений, весь тест не выполняется, и больше случаев не проверяется.
ytoledano
Это создает тестовые примеры, которые могут влиять друг на друга.
BartoszKP
@BartoszKP Только в том случае, если тестируемая система имеет побочные эффекты, и в этом случае это, вероятно, не оптимальный метод.
Gary.Ray
@ Gary.Ray Кроме того, когда система не имеет побочных эффектов , тем не менее . Также, когда тест не проходит, и другой разработчик пытается это исправить и тратит часы, пытаясь выяснить, имеет ли значение зависимость или нет. Это то, что тебе никогда не следует делать, и точка.
BartoszKP
Достаточно хорошо. +1
Trey Mack
7

Khlr дал хорошие подробные объяснения, и, видимо, этот подход начал работать в VS2015 Express for Desktop. Я попытался оставить комментарий, но отсутствие репутации не позволило мне это сделать.

Позвольте мне скопировать решение здесь:

[TestClass]  
 public class StringFormatUtilsTest  
 {  
     [TestMethod]  
     [DataRow("tttt", "")]  
     [DataRow("", "")]  
     [DataRow("t3a4b5", "345")]  
     [DataRow("3&amp;amp;5*", "35")]  
     [DataRow("123", "123")]  
     public void StripNonNumeric(string before, string expected)  
     {  
         string actual = FormatUtils.StripNonNumeric(before);  
         Assert.AreEqual(expected, actual);  
     }  
 } 

Чтобы использовать его, просто установите пакеты NuGet MSTest.TestFramework и MSTest.TestAdapter .

Одна проблема

Ошибка CS0433 Тип TestClassAttribute существует как в Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version = 10.0.0.0, так и в Microsoft.VisualStudio.TestPlatform.TestFramework, Version = 14.0.0.0.

Итак, удалите Microsoft.VisualStudio.QualityTools.UnitTestFramework из ссылок на проект.

Вы можете отредактировать исходный ответ и удалить этот.

Искусство
источник
0

MSTest имеет атрибут DataSource, который позволит вам передать ему таблицу базы данных, csv, xml и т. Д. Я использовал его, и он хорошо работает. Я не знаю, как поместить данные прямо выше в виде атрибутов, как в вашем вопросе, но очень легко настроить внешние источники данных, и файлы могут быть включены в проект. У меня он работал час с момента начала, и я не специалист по автоматическому тестированию.

https://msdn.microsoft.com/en-us/library/ms182527.aspx?f=255&MSPPError=-2147217396 содержит полное руководство, основанное на вводе базы данных.

http://www.rhyous.com/2015/05/11/row-tests-or-paramerterized-tests-mstest-xml/ содержит руководство, основанное на вводе файла XML.

CindyH
источник