Как мы можем запустить тестовый метод с несколькими параметрами в MSTest?

В NUnit есть функция, называемая значениями, как показано ниже:

[Test]
public void MyTest(
    [Values(1,2,3)] int x,
    [Values("A","B")] string s)
{
    // ...
}

Это означает, что тестовый метод будет выполнен шесть раз:

MyTest(1, "A")
MyTest(1, "B")
MyTest(2, "A")
MyTest(2, "B")
MyTest(3, "A")
MyTest(3, "B")

Сейчас мы используем MSTest, но есть ли для него эквивалент, чтобы я мог запустить один и тот же тест с несколькими параметрами?

[TestMethod]
public void Mytest()
{
    // ...
}

person The Light    schedule 26.01.2012    source источник
comment
Вы можете использовать MSTestHacks, как описано в ответе stackoverflow.com/a/19536942/52277.   -  person Michael Freidgeim    schedule 03.05.2016
comment
Возможный дубликат Как выполнить RowTest с MSTest?   -  person Michael Freidgeim    schedule 03.05.2016
comment
@MichaelFreidgeim На этот вопрос есть лучшие ответы, чем предложенная вами цель   -  person Rob    schedule 03.05.2016
comment
@Rob: IMHO, наиболее подходящий ответ -MSTestHacks - Как выполнить RowTest с MSTest? отсутствует в этом вопросе.   -  person Michael Freidgeim    schedule 03.05.2016
comment
@MichaelFreidgeim Возможно, хотя кажется, что функциональность существует уже 3,5 года (stackoverflow.com/questions/9021881/)   -  person Rob    schedule 03.05.2016
comment
@Rob: доступно только в рамках проекта модульного тестирования для WinRT / Metro. См. visualstudio.uservoice.com/forums/330519-team-services/   -  person Michael Freidgeim    schedule 03.05.2016


Ответы (9)


К сожалению, он не поддерживается в более старых версиях MSTest. По-видимому, существует модель расширяемости, и вы можете реализовать ее самостоятельно. Другой вариант - использовать тесты на основе данных.

Мое личное мнение было бы просто придерживаться NUnit ...

Начиная с Visual Studio 2012, обновление 1, MSTest имеет аналогичную функцию. См. ответ Макадена.

person jeroenh    schedule 26.01.2012
comment
Мы используем Selenium, который генерирует код NUnit, поэтому мы перешли на использование NUnit :) - person The Light; 27.01.2012
comment
Я обнаружил, что что-то подобное теперь возможно в Visual Studio 2012 Update 1, просто к вашему сведению для будущего рассмотрения всех, кто смотрит этот ответ. - person McAden; 04.12.2012
comment
@McAden у вас есть ссылка с объяснением? - person jeroenh; 05.12.2012
comment
Я дал ответ ниже с примером и ссылкой на мой пост в блоге. В нем упоминаются необходимые атрибуты, а также свойство DisplayName для атрибута, который различает случаи в обозревателе тестов. Это также упоминалось в октябрьском объявлении CTP (у которого теперь есть официальный выпуск) blogs.msdn.com/b/visualstudioalm/archive/2012/10/26/ Я добавил информацию в этот ТАК вопрос, потому что я потратил довольно много времени на его поиск. Надеюсь, это кому-нибудь сэкономит время. - person McAden; 05.12.2012

РЕДАКТИРОВАТЬ 4: похоже, это завершено в MSTest V2 17 июня 2016 г .: https://blogs.msdn.microsoft.com/visualstudioalm/2016/06/17/taking-the-mstest-framework-forward-with-mstest-v2/

Исходный ответ:

Примерно неделю назад в Visual Studio 2012 Update 1 теперь возможно нечто подобное:

[DataTestMethod]
[DataRow(12,3,4)]
[DataRow(12,2,6)]
[DataRow(12,4,3)]
public void DivideTest(int n, int d, int q)
{
  Assert.AreEqual( q, n / d );
}

ИЗМЕНИТЬ: похоже, это доступно только в проекте модульного тестирования для WinRT / Metro. Облом

ИЗМЕНИТЬ 2. Следующие метаданные можно найти с помощью функции «Перейти к определению» в Visual Studio:

#region Assembly Microsoft.VisualStudio.TestPlatform.UnitTestFramework.dll, v11.0.0.0
// C:\Program Files (x86)\Microsoft SDKs\Windows\v8.0\ExtensionSDKs\MSTestFramework\11.0\References\CommonConfiguration\neutral\Microsoft.VisualStudio.TestPlatform.UnitTestFramework.dll
#endregion

using System;

namespace Microsoft.VisualStudio.TestPlatform.UnitTestFramework
{
    [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
    public class DataTestMethodAttribute : TestMethodAttribute
    {
        public DataTestMethodAttribute();

        public override TestResult[] Execute(ITestMethod testMethod);
    }
}

ИЗМЕНИТЬ 3: эта проблема была поднята на форумах Visual Studio UserVoice. Последнее обновление гласит:

НАЧАЛО · Команда Visual Studio ADMIN Команда Visual Studio (группа разработки продукта, Microsoft Visual Studio) ответила · 25 апреля 2016 г. Спасибо за отзыв. Мы начали над этим работать.

Пратап Лакшман Visual Studio

https://visualstudio.uservoice.com/forums/330519-team-services/suggestions/3865310-allow-use-of-datatestmethod-datarow-in-all-unit

person McAden    schedule 04.12.2012
comment
Windows Phone теперь также поддерживается с Visual Studio 2012 Update 2 (в настоящее время CTP 4) - person Pedro Lamas; 14.03.2013
comment
У меня есть обновление 1, но DataTestMethod и DataRow не распознаются. В какой библиотеке находятся эти атрибуты? - person DevDave; 27.03.2013
comment
Какой тип проекта вы тестируете? - person McAden; 06.04.2013
comment
Есть ли какой-нибудь официальный источник о DataTestMethod? В каком пространстве имен он находится, в какой сборке? - person Igor Lankin; 07.04.2013
comment
Я обнаружил, что UnitTestFramework.dll был установлен на моем компьютере, и после ручного обращения к нему я смог написать метод с использованием атрибута [DataTestMethod] со строками данных, но я не могу заставить Test Explorer в Visual Studio 2012.3 найти метод. - person Josh DeLong; 07.08.2013
comment
В проекте, отличном от магазина Windows? - person McAden; 07.08.2013
comment
Я перешел по пути к файлу C: \ Program Files (x86) \ Microsoft SDKs \ Windows \ v8.0 \ ExtensionSDKs \ MSTestFramework \ 11.0 \ References \ CommonConfiguration \ нейтральный \ Microsoft.VisualStudio.TestPlatform.UnitTestFramework.dll на моем компьютере и файл был там. Поэтому я сослался на него в своем базовом проекте модульного тестирования. Открытие dll в JustDecompile показывает, что в библиотеке есть ссылки только на mscorlib, System и System.Core. Это не проект Магазина Windows. - person Josh DeLong; 07.08.2013
comment
Мне удалось заставить его работать только с проектами Магазина Windows. - person McAden; 07.08.2013
comment
Можете ли вы указать ожидаемый результат в DataRow? - person Leonid Vasilev; 05.02.2017
comment
Единственный способ, который я знаю, - это сделать его одним из аргументов, как в примере, который я привел в ответе. - person McAden; 06.02.2017
comment
Я использую VS2017 и обнаружил DataTestMethod в пакете nuget, имя которого, к сожалению, не могу вспомнить. Я написал [DataTestMethod], а затем нажал ctrl-., чтобы VS установила пакет nuget. Затем мне пришлось удалить старую тестовую библиотеку, так как есть конфликт имен. FWIW. - person LosManos; 24.07.2018

Эта функция находится в предварительный выпуск сейчас и работает с Visual Studio 2015.

Например:

[TestClass]
public class UnitTest1
{
    [TestMethod]
    [DataRow(1, 2, 2)]
    [DataRow(2, 3, 5)]
    [DataRow(3, 5, 8)]
    public void AdditionTest(int a, int b, int result)
    {
        Assert.AreEqual(result, a + b);
    }
}
person Pompair    schedule 17.06.2016
comment
Это правильный ответ. Обратите внимание, что для использования [DataRow] необязательно указывать [DataTestMethod] (stackoverflow.com/a/59162403/2540235 ) - person design.garden; 17.02.2020
comment
Это правильный ответ, который следует принять! У меня действительно работает! Спасибо! - person Anduin; 18.11.2020
comment
@JohnB предположительно аргументы для a, b и result соответственно. - person timelmer; 15.04.2021
comment
Я говорю, что первый набор тестовых данных неверен. Думаю, должно быть: [DataRow(1, 2, 3)] - person JohnB; 16.04.2021

Не совсем то же самое, что атрибуты Value (или TestCase) NUnit, но MSTest имеет _ 3_, который позволяет делать то же самое.

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

person k.m    schedule 26.01.2012

MSTest имеет мощный атрибут, называемый DataSource. Используя это, вы можете выполнять тесты на основе данных по вашему запросу. Вы можете иметь свои тестовые данные в XML, CSV или в базе данных. Вот несколько ссылок, которые помогут вам

person Pritam Karmakar    schedule 27.01.2012

Реализовать это очень просто - нужно использовать свойство TestContext и TestPropertyAttribute.

Пример

public TestContext TestContext { get; set; }
private List<string> GetProperties()
{
    return TestContext.Properties
        .Cast<KeyValuePair<string, object>>()
        .Where(_ => _.Key.StartsWith("par"))
        .Select(_ => _.Value as string)
        .ToList();
}

//usage
[TestMethod]
[TestProperty("par1", "http://getbootstrap.com/components/")]
[TestProperty("par2", "http://www.wsj.com/europe")]
public void SomeTest()
{
    var pars = GetProperties();
    //...
}

РЕДАКТИРОВАТЬ:

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

[TestMethod]
[TestProperty("fileName1", @".\test_file1")]
[TestProperty("fileName2", @".\test_file2")]
[TestProperty("fileName3", @".\test_file3")]
public void TestMethod3()
{
    TestContext.GetMany<string>("fileName").ForEach(fileName =>
    {
        //Arrange
        var f = new FileInfo(fileName);

        //Act
        var isExists = f.Exists;

        //Asssert
        Assert.IsFalse(isExists);
    });
}

и пример с созданием сложных тестовых объектов:

[TestMethod]
//Case 1
[TestProperty(nameof(FileDescriptor.FileVersionId), "673C9C2D-A29E-4ACC-90D4-67C52FBA84E4")]
//...
public void TestMethod2()
{
    //Arrange
    TestContext.For<FileDescriptor>().Fill(fi => fi.FileVersionId).Fill(fi => fi.Extension).Fill(fi => fi.Name).Fill(fi => fi.CreatedOn, new CultureInfo("en-US", false)).Fill(fi => fi.AccessPolicy)
        .ForEach(fileInfo =>
        {
            //Act
            var fileInfoString = fileInfo.ToString();

            //Assert
            Assert.AreEqual($"Id: {fileInfo.FileVersionId}; Ext: {fileInfo.Extension}; Name: {fileInfo.Name}; Created: {fileInfo.CreatedOn}; AccessPolicy: {fileInfo.AccessPolicy};", fileInfoString);
        });
}

Обратите внимание на методы и набор образцов для получения дополнительных сведений.

person Andrey Burykin    schedule 16.05.2016
comment
Этот подход работает, но не создает отдельных тестовых примеров для каждого набора параметров. - person usr4896260; 29.06.2018
comment
Вы можете использовать что-то более сложное в качестве значения TestProperty (например, 0-100), анализировать и обрабатывать его в теле теста. - person Andrey Burykin; 29.06.2018

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

В Visual Studio 2012 он создает два теста в TestExplorer:

  1. DemoTest_B10_A5.test
  2. DemoTest_A12_B4.test

    public class Demo
    {
        int a, b;
    
        public Demo(int _a, int _b)
        {
            this.a = _a;
            this.b = _b;
        }
    
        public int Sum()
        {
            return this.a + this.b;
        }
    }
    
    public abstract class DemoTestBase
    {
        Demo objUnderTest;
        int expectedSum;
    
        public DemoTestBase(int _a, int _b, int _expectedSum)
        {
            objUnderTest = new Demo(_a, _b);
            this.expectedSum = _expectedSum;
        }
    
        [TestMethod]
        public void test()
        {
            Assert.AreEqual(this.expectedSum, this.objUnderTest.Sum());
        }
    }
    
    [TestClass]
    public class DemoTest_A12_B4 : DemoTestBase
    {
        public DemoTest_A12_B4() : base(12, 4, 16) { }
    }
    
    public abstract class DemoTest_B10_Base : DemoTestBase
    {
        public DemoTest_B10_Base(int _a) : base(_a, 10, _a + 10) { }
    }
    
    [TestClass]
    public class DemoTest_B10_A5 : DemoTest_B10_Base
    {
        public DemoTest_B10_A5() : base(5) { }
    }
    
person Soumya Dutta    schedule 25.03.2014

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

См. Включение параметризованных тестов в MSTest с помощью PostSharp.

person Massimiliano Peluso    schedule 26.01.2012

Мне не удалось заставить The DataRowAttribute работать в Visual Studio 2015, и вот что у меня получилось:

[TestClass]
public class Tests
{
    private Foo _toTest;

    [TestInitialize]
    public void Setup()
    {
        this._toTest = new Foo();
    }

    [TestMethod]
    public void ATest()
    {
        this.Perform_ATest(1, 1, 2);
        this.Setup();

        this.Perform_ATest(100, 200, 300);
        this.Setup();

        this.Perform_ATest(817001, 212, 817213);
        this.Setup();
    }

    private void Perform_ATest(int a, int b, int expected)
    {
        // Obviously this would be way more complex...

        Assert.IsTrue(this._toTest.Add(a,b) == expected);
    }
}

public class Foo
{
    public int Add(int a, int b)
    {
        return a + b;
    }
}

Настоящее решение здесь - просто использовать NUnit (если вы не застряли в MSTest, как я в этом конкретном случае).

person Brandon    schedule 27.10.2016
comment
вы должны разделить каждый тестовый вызов на отдельный тест, чтобы сэкономить время, когда один из них сломается. (что, как мы все знаем, произойдет) - person silver; 08.02.2017
comment
Ну конечно; естественно. На практике так и будет. В данном случае я просто проиллюстрировал это для простоты. - person Brandon; 08.02.2017