Bagaimana cara menjalankan metode pengujian dengan beberapa parameter di MSTest?

140

NUnit memiliki fitur yang disebut Nilai, seperti di bawah ini:

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

Ini berarti bahwa metode pengujian akan berjalan 6 kali:

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

Kami menggunakan MSTest sekarang, adakah yang setara untuk ini sehingga saya dapat menjalankan tes yang sama dengan beberapa parameter?

[TestMethod]
public void Mytest()
{
    // ...
}
Cahaya
sumber
Anda dapat menggunakan MSTestHacks, seperti dijelaskan dalam stackoverflow.com/a/19536942/52277 jawaban.
Michael Freidgeim
Kemungkinan duplikat dari How to RowTest dengan MSTest?
Michael Freidgeim
@MichaelFreidgeim Pertanyaan ini memiliki jawaban yang lebih baik daripada target yang Anda sarankan
Rob
1
@Rob: IMHO, jawaban yang paling tepat -MSTestHacks - Bagaimana cara RowTest dengan MSTest? tidak ada dalam pertanyaan ini.
Michael Freidgeim
@MichaelFreidgeim Mungkin, meskipun tampaknya fungsionalitas telah ada selama 3 1/2 tahun sekarang ( stackoverflow.com/questions/9021881/… )
Rob

Jawaban:

46

Sayangnya tidak didukung di MSTest. Rupanya ada model ekstensibilitas dan Anda bisa menerapkannya sendiri . Pilihan lain adalah menggunakan tes berbasis data .

Pendapat pribadi saya akan tetap dengan NUnit meskipun ...

EDIT: Pada Visual Studio 2012, pembaruan 1, MSTest memiliki fitur serupa. Lihat jawaban @ McAden di bawah ini.

Jeroenh
sumber
Kami menggunakan Selenium yang menghasilkan kode NUnit jadi kami beralih menggunakan NUnit :)
The Light
4
Saya telah menemukan bahwa sesuatu yang serupa sekarang mungkin di Visual Studio 2012 Pembaruan 1, hanya FYI untuk pertimbangan masa depan siapa pun yang melihat jawaban ini.
McAden
@ MCAden apakah Anda memiliki tautan dengan penjelasan?
jeroenh
6
Saya memberikan jawaban di bawah ini dengan contoh dan tautan ke posting blog saya. Itu menyebutkan atribut yang diperlukan dan juga properti "DisplayName" pada atribut yang membedakan kasus di Test Explorer. Itu juga disebutkan dalam pengumuman CTP Oktober (yang sekarang memiliki rilis resmi) blogs.msdn.com/b/visualstudioalm/archive/2012/10/26/… Saya telah menambahkan informasi ke pertanyaan SO ini karena saya menghabiskan sedikit waktu mencarinya. Semoga ini akan menghemat waktu seseorang.
McAden
167

EDIT 4 : Sepertinya ini selesai di MSTest V2 17 Juni 2016: https://blogs.msdn.microsoft.com/visualstudioalm/2016/06/17/taking-the-mstest-framework-forward-with-mstest- v2 /

Jawaban Asli :

Pada sekitar seminggu yang lalu di Visual Studio 2012 Pembaruan 1 sesuatu yang serupa sekarang mungkin:

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

EDIT : Tampaknya ini hanya tersedia dalam proyek pengujian unit untuk WinRT / Metro . Kekecewaan

EDIT 2 : Berikut ini adalah metadata yang ditemukan menggunakan "Go To Definition" dalam 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);
    }
}

EDIT 3 : Masalah ini diangkat dalam forum UserVoice Visual Studio. Status Pembaruan Terakhir:

MEMULAI · Tim Visual Studio Tim Visual Studio ADMIN (Tim Produk, Microsoft Visual Studio) merespons · 25 April 2016 Terima kasih atas umpan baliknya. Kami sudah mulai mengerjakan ini.

Studio Visual Pratap Lakshman

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

McAden
sumber
4
Windows Phone sekarang didukung juga, dengan Visual Studio 2012 Update 2 (saat ini, CTP 4)
Pedro Lamas
8
Saya memiliki pembaruan 1 tetapi DataTestMethod dan DataRow tidak dikenali, di perpustakaan mana atribut ini berada?
DevDave
3
Apakah ada sumber resmi tentang DataTestMethod? Apa namespace itu, majelis yang mana?
Igor Lankin
2
Saya menemukan bahwa UnitTestFramework.dll diinstal pada komputer saya dan setelah merujuknya secara manual, saya dapat menulis metode menggunakan atribut [DataTestMethod] dengan baris data tetapi saya tidak bisa mendapatkan Test Explorer di Visual Studio 2012.3 untuk menemukan metode tersebut.
Josh DeLong
5
Saya pergi ke jalur file "C: \ Program Files (x86) \ Microsoft SDKs \ Windows \ v8.0 \ ExtensionSDKs \ MSTestFramework \ 11.0 \ Referensi \ CommonConfiguration \ neutral \ Microsoft.VisualStudio.TestPlatform.UnitTestFramework.dll" di komputer saya dan file itu ada di sana. Jadi saya merujuknya dalam proyek uji unit dasar saya. Membuka dll di JustDecompile menunjukkan bahwa perpustakaan hanya memiliki referensi ke mscorlib, System, dan System.Core. Ini bukan proyek Windows Store.
Josh DeLong
34

Fitur ini dalam pra-rilis sekarang dan berfungsi dengan VS 2015.

Sebagai contoh:

[TestClass]
public class UnitTest1
{
    [DataTestMethod]
    [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);
    }
}
Pompair
sumber
Ini jawaban yang benar. Perhatikan bahwa tidak perlu mengatakan [DataTestMethod] untuk menggunakan [DataRow] ( stackoverflow.com/a/59162403/2540235 )
mattastricht
11

Karena tidak ada yang menyebutkan - tidak persis sama dengan atribut NUnit Value(atau TestCase), tetapi MSTest memiliki DataSourceatribut, yang memungkinkan Anda untuk melakukan hal serupa. Anda dapat menghubungkannya ke database atau file XML - tidak semudah fitur NUnit, tetapi melakukan tugasnya.

km
sumber
7

MSTest memiliki atribut kuat yang disebut DataSource , menggunakan ini Anda dapat melakukan tes data didorong saat Anda bertanya. Anda dapat memiliki data pengujian dalam XML, CSV atau dalam database. Berikut adalah beberapa tautan yang akan memandu Anda

http://visualstudiomagazine.com/articles/2009/09/15/unit-testing-with-vsts2008-part-3.aspx http://msdn.microsoft.com/en-us/library/ms182527.aspx
http: //msdn.microsoft.com/en-us/library/ms243192.aspx

Semoga ini bisa membantu Anda.

Pritam Karmakar
sumber
6

Ini sangat sederhana untuk diterapkan - Anda harus menggunakan TestContextproperti danTestPropertyAttribute .

Contoh

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

EDIT:

Saya menyiapkan beberapa metode ekstensi untuk menyederhanakan akses ke TestContextproperti dan bertindak seperti kami memiliki beberapa kasus uji. Lihat contoh dengan memproses properti uji sederhana di sini:

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

dan contoh dengan membuat objek tes yang kompleks:

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

Lihatlah metode ekstensi dan set sampel untuk lebih jelasnya.

Andrey Burykin
sumber
2
Pendekatan ini berfungsi tetapi tidak membuat kasus uji individual untuk setiap set parameter.
usr4896260
Anda dapat menggunakan sesuatu yang lebih kompleks sebagai nilai TestProperty (mis. "0-100"), parsing dan tangani di badan uji.
Andrey Burykin
4

Ada, tentu saja, cara lain untuk melakukan ini yang belum dibahas dalam utas ini, yaitu dengan cara pewarisan kelas yang berisi TestMethod. Dalam contoh berikut, hanya satu TestMethod telah didefinisikan tetapi dua test case telah dibuat.

Di Visual Studio 2012, itu menciptakan dua tes di 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) { }
    }
Soumya Dutta
sumber
3

Saya tidak dapat DataRowAttributemengaktifkan The di Visual Studio 2015, inilah yang akhirnya saya lakukan:

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

Solusi sebenarnya di sini adalah dengan hanya menggunakan NUnit (kecuali Anda terjebak di MSTest seperti saya dalam contoh khusus ini).

Brandon
sumber
3
Anda harus membagi setiap panggilan tes ke tes terpisah untuk menghemat waktu Anda ketika salah satu dari mereka akan terputus. (yang kita semua tahu akan terjadi)
perak
Ya tentu saja. Dalam praktiknya itulah yang akan dilakukan. Dalam hal ini saya hanya mengilustrasikannya untuk kesederhanaan
Brandon