Làm cách nào để chạy một phương thức thử nghiệm với nhiều tham số trong MSTest?


140

NUnit có một tính năng gọi là Giá trị, như dưới đây:

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

Điều này có nghĩa là phương pháp thử nghiệm sẽ chạy 6 lần:

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

Hiện tại chúng tôi đang sử dụng MSTest, có điều gì tương đương với điều này để tôi có thể chạy thử nghiệm tương tự với nhiều tham số không?

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

Bạn có thể sử dụng MSTestHacks, như được mô tả trong stackoverflow.com/a/19536942/52277 câu trả lời.
Michael Freidgeim


@MichaelFreidgeim Câu hỏi này có câu trả lời tốt hơn mục tiêu đề xuất của bạn
Rob

1
@Rob: IMHO, câu trả lời thích hợp nhất -MSTestHacks - Làm thế nào để RowTest với MSTest? bị thiếu trong câu hỏi này.
Michael Freidgeim

@MichaelFreidgeim Có lẽ, mặc dù có vẻ như các chức năng đã tồn tại 3 1/2 năm nay ( stackoverflow.com/questions/9021881/... )
Rob

Câu trả lời:


46

Thật không may, không được hỗ trợ trong MSTest. Rõ ràng có một mô hình mở rộng và bạn có thể tự thực hiện nó . Một lựa chọn khác là sử dụng các bài kiểm tra dựa trên dữ liệu .

Ý kiến ​​cá nhân của tôi sẽ chỉ gắn bó với NUnit mặc dù ...

EDIT: Kể từ Visual Studio 2012, cập nhật 1, MSTest có một tính năng tương tự. Xem câu trả lời của @ McAden bên dưới.


Chúng tôi đang sử dụng Selenium tạo mã NUnit nên chúng tôi đã chuyển sang sử dụng NUnit thay thế :)
The Light

4
Tôi đã thấy rằng một cái gì đó tương tự hiện có thể có trong Visual Studio 2012 Update 1, chỉ là FYI để xem xét trong tương lai của bất kỳ ai nhìn vào câu trả lời này.
McAden

@McAden bạn có một liên kết với một lời giải thích?
jeroenh

6
Tôi đã đưa ra một câu trả lời dưới đây với một ví dụ và một liên kết đến bài viết trên blog của tôi. Nó đề cập đến các thuộc tính cần thiết và cũng là thuộc tính "DisplayName" trên thuộc tính để phân biệt các trường hợp trong Test Explorer. Nó cũng đã được đề cập trong thông báo tháng 10 của CTP (hiện đã có bản phát hành chính thức) blog.msdn.com/b/visualstudioalm/archive/2012/10/26/ Tôi đã thêm thông tin vào câu hỏi SO này vì tôi đã dành khá nhiều thời gian để tìm kiếm nó. Hy vọng điều này sẽ giúp ai đó tiết kiệm thời gian.
McAden

167

EDIT 4 : Có vẻ như điều này đã được hoàn thành trong MSTest V2 ngày 17 tháng 6 năm 2016: https://bloss.msdn.microsoft.com/visualstudioalm/2016/06/17/taking-the-mstest-framework-forward-with-mstest- v2 /

Câu trả lời gốc :

Kể từ khoảng một tuần trước trong Visual Studio 2012 Update 1, một cái gì đó tương tự hiện có thể:

[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 : Dường như điều này chỉ khả dụng trong dự án thử nghiệm đơn vị cho WinRT / Metro . Bummer

EDIT 2 : Sau đây là siêu dữ liệu được tìm thấy bằng cách sử dụng "Chuyển đến định nghĩa" trong 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 : Vấn đề này đã được đưa lên trong các diễn đàn UserVoice của Visual Studio. Cập nhật lần cuối:

BẮT ĐẦU · Nhóm Visual Studio Nhóm ADMIN Visual Studio (Nhóm sản phẩm, Microsoft Visual Studio) đã trả lời · 25 tháng 4 năm 2016 Cảm ơn bạn đã phản hồi. Chúng tôi đã bắt đầu làm việc này.

Phòng thu hình ảnh của Pratap Lakshman

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


4
Windows Phone hiện cũng được hỗ trợ, với Visual Studio 2012 Update 2 (hiện tại, CTP 4)
Pedro Lamas

8
Tôi đã cập nhật 1 nhưng DataTestMethod và DataRow không được nhận dạng, những thuộc tính này nằm trong thư viện nào?
DevDave

3
Có nguồn chính thức nào về DataTestMethod không? Không gian tên là gì trong đó, lắp ráp?
Igor Lankin

2
Tôi thấy rằng UnitTestFramework.dll đã được cài đặt trên máy tính của tôi và sau khi tham khảo thủ công, tôi có thể viết một phương thức bằng cách sử dụng thuộc tính [DataTestMethod] với các hàng dữ liệu nhưng tôi không thể lấy Test Explorer trong Visual Studio 2012.3 để tìm phương thức.
Josh DeLong

5
Tôi đã đi đến đường dẫn tệp "C: \ Program Files (x86) \ Microsoft SDKs \ Windows \ v8.0 \ ExtensionSDKs \ MSTestFramework \ 11.0 \ Tài liệu tham khảo \ CommonConfiguration \ neut \ Microsoft.VisualStudio.TestPl platform.UnitTestFramework.dll" trên máy tính của tôi và tập tin đã ở đó Vì vậy, tôi đã tham chiếu nó trong dự án thử nghiệm đơn vị cơ bản của tôi. Mở dll trong JustDecompile cho thấy rằng thư viện chỉ có các tham chiếu đến mscorlib, System và System.Core. Đây không phải là một dự án Windows Store.
Josh DeLong

34

Tính năng này hiện đang được phát hành trước và hoạt động với VS 2015.

Ví dụ:

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

Đây là câu trả lời chính xác. Lưu ý rằng không cần thiết phải nói [DataTestMethod] để sử dụng [DataRow] ( stackoverflow.com/a/59162403/2540235 )
mattavatar

11

Vì không ai đề cập - không hoàn toàn giống với các thuộc tính Value(hoặc TestCase) của NUnit , nhưng MSTest có DataSourcethuộc tính, cho phép bạn thực hiện điều tương tự. Bạn có thể nối nó với cơ sở dữ liệu hoặc tệp XML - không đơn giản như tính năng của NUnit, nhưng thực hiện công việc.


7

MSTest có một thuộc tính mạnh mẽ được gọi là DataSource , bằng cách này, bạn có thể thực hiện kiểm tra theo hướng dữ liệu như bạn đã yêu cầu. Bạn có thể có dữ liệu thử nghiệm của mình bằng XML, CSV hoặc trong cơ sở dữ liệu. Dưới đây là một vài liên kết sẽ hướng dẫn bạn

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

Hy vọng điều này sẽ giúp bạn.


6

Cách thực hiện rất đơn giản - bạn nên sử dụng thuộc TestContexttính và TestPropertyAttribute.

Thí dụ

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

BIÊN TẬP:

Tôi đã chuẩn bị một vài phương thức mở rộng để đơn giản hóa quyền truy cập vào TestContexttài sản và hành động như chúng ta có một số trường hợp thử nghiệm. Xem ví dụ với việc xử lý các thuộc tính thử nghiệm đơn giản tại đây:

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

và ví dụ với việc tạo các đối tượng thử nghiệm phức tạp:

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

Hãy xem các phương pháp mở rộng và tập hợp các mẫu để biết thêm chi tiết.


2
Cách tiếp cận này hoạt động nhưng không tạo ra các trường hợp thử nghiệm riêng lẻ cho từng bộ thông số.
usr4896260

Bạn có thể sử dụng một cái gì đó phức tạp hơn như giá trị TestProperty (ví dụ: "0-100"), phân tích và xử lý nó trong phần thân của bài kiểm tra.
Andrey Burykin

4

Tất nhiên, có một cách khác để làm điều này chưa được thảo luận trong luồng này, tức là bằng cách kế thừa lớp chứa TestMethod. Trong ví dụ sau, chỉ có một TestMethod được xác định nhưng hai trường hợp thử nghiệm đã được thực hiện.

Trong Visual Studio 2012, nó tạo ra hai thử nghiệm trong 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) { }
    }


3

Tôi không thể có được The DataRowAttributeto work trong Visual Studio 2015, đây là những gì tôi đã kết thúc với:

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

Giải pháp thực sự ở đây là chỉ sử dụng NUnit (trừ khi bạn bị mắc kẹt trong MSTest như tôi trong trường hợp cụ thể này).


3
bạn nên chia mỗi cuộc gọi thử nghiệm thành một thử nghiệm riêng biệt để tiết kiệm thời gian khi một trong số chúng bị hỏng. (mà tất cả chúng ta đều biết sẽ xảy ra)
bạc

Phải, tất nhiên. Trong thực tế đó là cách nó sẽ được thực hiện. Trong trường hợp này, tôi chỉ minh họa cho đơn giản
Brandon
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.