2013-08-15 101 views
5

Tôi đang cố gắng tuân theo chặt chẽ hơn việc thực hành 'một xác nhận trên một thử nghiệm đơn vị'. Nó không phải là luôn luôn có thể, nhưng tôi thấy nó hữu ích cho việc xác định lỗi.Có thuộc tính nào để tránh thất bại kiểm tra đơn vị thác trong MSTest không?

Ví dụ tôi có thể có một cái gì đó như:

var toTest; 

[TestInitialize] 
Init() { 
    toTest = // Create toTest 
} 

[TestMethod] 
TestIsCreated() { 
    Assert.IsNotNull(toTest); 
} 

[TestMethod] 
TestIsProperty1Setup() { 
    Assert.IsNotNull(toTest.Property1); 
    // Maybe some more tests on Property1 
} 

// More tests for other properties... 

Vấn đề là nếu việc tạo ra các toTest đã thất bại, sau đó tất cả các bài kiểm tra đơn vị khác thất bại quá. Vì vậy, chúng tôi có thể thêm một số kiểm tra cho điều này như vậy:

... 

[TestMethod] 
TestIsProperty1Setup() { 
    if (toTest == null) Assert.Inconclusive() 
    Assert.IsNotNull(toTest.Property1); 
    // Maybe some more tests on Property1 
} 

... 

Điều này sẽ ngăn chặn lỗi thất bại và chỉ ra vấn đề chính xác. Nếu dòng // Create toTest trả về một giá trị rỗng thì tôi nhận được chính xác một kiểm tra đơn vị không thành công và một loạt các thử nghiệm không xác định khác. Khi tôi sửa chữa một bài kiểm tra thất bại thì mọi thứ khác đều trôi qua.

Có hai địa điểm nơi sự cố này rơi xuống. Một thực tế là bây giờ tôi đã lặp lại mã khi bắt đầu gần như tất cả các bài kiểm tra đơn vị.

Vấn đề thứ hai là khi tôi muốn cài đặt và kiểm tra một đối tượng phức tạp hơn (trong ví dụ giả này toTest cũng có một mảng):

[TestMethod] 
TestArrayIsNotNull() { 
    if (toTest == null) Assert.Inconclusive(); 
    Assert.IsNotNull(toTest.Array); 
} 

[TestMethod] 
TestArrayIsInitilizedWithOneElement() { 
    if (toTest == null) Assert.Inconclusive(); 
    if (toTest.Array == null) Assert.Inconclusive(); 
    Assert.AreEqual(1, toTest.Array.Count()) 
} 

[TestMethod] 
TestArrayIsInitilizedWithCorrectElement() { 
    if (toTest == null) Assert.Inconclusive(); 
    if (toTest.Array == null) Assert.Inconclusive(); 
    if (toTest.Array.Count() != 1) Assert.Inconclusive(); 
    // Assert something about toTest.Array[0] 
} 

Bây giờ có mã trùng lặp hơn cho mỗi bài kiểm tra cá nhân, và quan trọng hơn là các Asserts phải được giữ đồng bộ giữa các phép thử khác nhau có nghĩa là một thay đổi nhỏ có thể gợn qua nhiều thử nghiệm đơn vị.

Lý tưởng nhất là tôi muốn có một thuộc tính nằm trên đầu mỗi thử nghiệm và chỉ chạy thử nghiệm nếu kiểm tra 'điều kiện tiên quyết' vượt qua. Nó có thể trông giống như thế này:

[TestMethod] 
[OnlyRunIfOtherTestPasses(TestIsCreated())] 
TestArrayIsNotNull() { 
    Assert.IsNotNull(toTest.Array); 
} 

[TestMethod] 
[OnlyRunIfOtherTestPasses(TestArrayIsNotNull())] 
TestArrayIsInitilizedWithOneElement() { 
    Assert.AreEqual(1, toTest.Array.Count()) 
} 

[TestMethod] 
[OnlyRunIfOtherTestPasses(TestArrayIsInitilizedWithOneElement())] 
TestArrayIsInitilizedWithCorrectElement() { 
    // Assert something about toTest.Array[0] 
} 

Kiểm tra đơn vị bây giờ rất đơn giản - không có trùng lặp và kiểm tra đồng bộ với 'điều kiện tiên quyết' của họ bây giờ là tự động.

Có điều gì tương tự không? Hoặc có một tính năng hoàn toàn khác mà tôi có thể sử dụng để có được hiệu ứng tương tự không?

Tôi biết rằng hầu như chắc chắn có vấn đề với phương pháp thử trong một thuộc tính đối với phương pháp thử khác - bạn có thể phải sử dụng chuỗi được mã hóa cứng vào tên phương thức (vì vậy điều gì xảy ra nếu phương pháp thay đổi tên hoặc phương thức không tồn tại). Tôi chắc chắn cũng có những vấn đề tiềm năng với tham chiếu vòng tròn. Nhưng bất chấp tất cả những vấn đề này, ai đó phải giải quyết vấn đề này. Bất cứ ai có thể chỉ ra cho tôi?

+1

IMHO bạn có quá nhiều logic trong các bài kiểm tra đơn vị của mình. Chúng phải ngắn gọn và không chứa nhiều logic. Họ cũng không nên phụ thuộc vào các xét nghiệm khác. Tôi nghĩ bạn cần nghĩ lại cách tiếp cận của mình. – Belogix

+0

Khi bạn nói 'suy nghĩ lại cách tiếp cận của bạn', bạn có nghĩa là suy nghĩ lại cách kiểm tra đơn vị được viết (Tôi không nên kiểm tra nếu toTest là null tất cả các thời gian), hoặc để suy nghĩ lại các phụ thuộc của lớp dưới kiểm tra (toTest không nên có một mảng phải được thiết lập)? – Jonny

+0

Nhân bản: http://stackoverflow.com/questions/15871933/how-to-stop-mstest-tests-execution-on-first-failure – BartoszKP

Trả lời

0

Sự phụ thuộc giữa các thử nghiệm không được khuyến khích. Giải pháp có thể cho vấn đề của bạn: nếu bạn ném một ngoại lệ nếu việc tạo "toTest" không thành công (hoặc sử dụng Assert bình thường) trong phương pháp khởi tạo thử nghiệm, thì tôi tin rằng các thử nghiệm từ nhóm sẽ không chạy được. Bạn cũng có thể sử dụng khởi tạo lớp tĩnh (http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.testtools.unittesting.classinitializeattribute.aspx). Tuy nhiên, tất cả các thử nghiệm sẽ vẫn được đánh dấu là không thành công.

+0

Nếu tôi ném ngoại lệ trong phương thức TestInitialize thì tất cả các bài kiểm tra đơn vị đều không thành công.Tôi đang hướng tới chính xác một thử nghiệm đơn vị để thất bại nếu việc tạo ra không hoạt động để nó rất dễ dàng để xác định vấn đề. – Jonny

Các vấn đề liên quan