2013-08-29 56 views
5

Sử dụng MSTEST trong VS2012.3 .NET4.5 và R # cho nhân tố thử nghiệm.Nhiều thuộc tính TestInitialize trong MSTEST

Mã bên dưới hoạt động theo thứ tự 1,2,3,4.

Tuy nhiên tôi đang lo ngại rằng nó có thể không luôn luôn thực hiện theo thứ tự này như nhiều TestInitialize thuộc tính không được hỗ trợ Câu hỏi MSDN

: Sản phẩm này cho phép, và các tài liệu chỉ có nghĩa là nhiều TestInitialize thuộc tính không được phép vào Cùng lớp?

Tôi muốn giữ cấu trúc này khi có nhiều thử nghiệm tích hợp kế thừa từ TransactedTestBase, nhưng yêu cầu các tập lệnh SQL khác nhau để thiết lập.

hành vi tương tự đã được tìm thấy here

[TestClass] 
public class DelegationTest : TransactedTestBase 
{ 
    [TestInitialize] 
    public void Setup() 
    { 
     Console.WriteLine("2 Setup"); 
     //var script = "INSERT INTO blah..."; 
     //var sqlConnect = new SqlConnection(dbConnection.ConnectionString); 
     //sqlConnect.Open(); 
     //var server = new Server(sqlConnect); 
     //var database = server.Databases[sqlConnect.Database]; 
     //database.ExecuteNonQuery(script); 
    } 

    [TestMethod] 
    public void TestMethod1() 
    { 
     Console.WriteLine("3 Test Method"); 
    } 
} 

[TestClass] 
public class TransactedTestBase 
{ 
    //protected userEntities userEntities; 
    //private TransactionScope scope; 
    //public static SqlDatabase dbConnection; 

    //private const bool ShouldWriteToDB = true; 
    //private const bool ShouldWriteToDB = false; 

    [TestInitialize()] 
    public virtual void TestStart() 
    { 
     Console.WriteLine("1 TestStart"); 
     //if (ShouldWriteToDB) 
     //{ 
     // dbConnection = EnterpriseLibraryContainer.Current.GetInstance<SqlDatabase>("DBConnect"); 
     // return; 
     //} 

     //scope = new TransactionScope(TransactionScopeOption.RequiresNew); 
     //user = new userEntities(); 
     //dbConnection = EnterpriseLibraryContainer.Current.GetInstance<SqlDatabase>("DBConnect"); 
    } 

    [TestCleanup()] 
    public virtual void TestEnd() 
    { 
     Console.WriteLine("4 TestEnd"); 
     //if (ShouldWriteToDB) return; 

     //scope.Dispose(); 
    } 
} 
+0

Bạn có thể tránh một sự ngạc nhiên và gọi các phương thức lớp cơ sở trực tiếp: [TestInitialize] void override public TestStart() { base.TestStart(); Console.WriteLine ("2 Thiết lập"); } – SlavaGu

Trả lời

5

Tôi tin rằng các tài liệu đang đề cập đến việc sử dụng TestInitializeAttribute nhiều lần trên cùng một phương pháp. Điều này được kiểm soát bởi AttributeUsage(AllowMultiple=false). FWIW, tôi có một bộ kiểm tra kích thước trung bình (~ 200 bài kiểm tra) dựa trên mã bạn đã làm việc như bạn mong đợi: TestStart được gọi trước Setup.

Có vấn đề khi đặt phương thức TestInitialize ảo và ghi đè phương thức đó (xem here) và kế thừa phương thức ClassInitialize (MsTest ClassInitialize and Inheritance).

+0

Cảm ơn Mike, Sunny và SlavaGu.Bây giờ có ý nghĩa hơn, và tôi thực sự thích cách này để chạy thử nghiệm. –

2

Tôi tin rằng bạn hiểu sai bài viết MSDN. Họ tuyên bố:

Thuộc tính này có thể được chỉ định trên phương pháp. Chỉ một thể hiện thuộc tính này có thể được áp dụng cho một phương pháp.

Điều đó có nghĩa rằng bạn không thể có mã như thế này:

[TestInitialize] 
[TestInitialize] 
public void MyIntilialzer(){} 

Nó không có nghĩa là bạn không thể có nhiều initializers, thậm chí trong cùng một lớp.

Tôi không chắc chắn về MSTest, but in NUnit its well defined rằng trong trường hợp bạn mô tả, trình khởi chạy sẽ được chạy theo thứ tự đúng, từ lớp cơ sở lên. Và nếu bạn có vài initializers trong cùng một lớp, thứ tự không được bảo đảm.

Tôi cho rằng điều này cũng đúng đối với MSTest (nhưng tôi không có điểm tham chiếu).

2

Lưu ý rằng thứ tự thực thi phụ thuộc vào nhân tố thử nghiệm. Visual Studio thử nghiệm Á hậu và R # thử nghiệm Á hậu có thể hành xử khác nhau. Bây giờ tôi tin rằng họ có hành vi tương tự, nhưng vẫn còn là R # nó sẽ hành xử như thế nào.

Tôi nhớ rằng một trong những phiên bản cũ của R # có lỗi và phương pháp TestInitialize từ phân lớp được thực hiện trước đó sau đó phương thức TestInitialize trong lớp cơ sở. Tất nhiên, nó đã được sửa chữa nhanh chóng :)