2014-05-23 18 views
14

Chúng tôi đã được sử dụng xUnit Khung trong dự án của chúng tôi như khuôn khổ thử nghiệm kể từ sự khởi đầu. Hiện nay có 2200+ kiểm tra đơn vị trong dự án và mọi thứ có vẻ ổn.xUnit Async thử nghiệm không làm việc đúng

Nhưng hôm qua tôi quyết định chạy thử nghiệm đơn vị tại CI xây dựng và đêm xây dựng. Chiến đấu với đội xây dựng bộ điều khiển để chạy thử nghiệm xunit trong 1-2 giờ tôi thành công để chạy thử nghiệm. Nhưng có một vấn đề, có 22 cảnh báo abouts kiểm tra như dưới đây, - Xunit.Sdk.EqualException: Assert.Equal() thất bại hoặc - System.ArgumentNullException: Giá trị không thể rỗng.

Sau khi một số nghiên cứu hơn tôi nhận ra những thử nghiệm này phải được thất bại nhưng dường như trôi qua vì tất cả những thử nghiệm này được đánh dấu với từ khóa "async".

Thực ra không nên có bất kỳ lỗi, vì xUnit hỗ trợ kiểm tra async liên quan đến các bài viết http://bradwilson.typepad.com/blog/2012/01/xunit19.html http://sravi-kiran.blogspot.com.tr/2012/11/UnitTestingAsynchronousMethodsUsingMSTestAndXUnit.html Howerver thực tế là khác biệt nhẹ hơn đối với tôi. Có xUnit chạy mà không có bất kỳ vấn đề nhưng không kiểm tra đúng.

Dưới đây là hai phương pháp ít.

public async Task<string> AsyncTestMethod() { 
    throw new Exception("Test"); 
} 
public string NormalTestMethod() { 
    throw new Exception("Test"); 
} 

Như bạn thấy chỉ chênh lệch, phương pháp đầu tiên định nghĩa là "async" Và đây là hai bài kiểm tra cho các phương pháp này.

[Fact] 
    public async void XunitTestMethod_Async() { 
     Program p = new Program(); 
     string result = await p.AsyncTestMethod(); 
     Assert.Equal("Ok", result); 
    } 
     [Fact] 
    public void XunitTestMethod_Normal() { 
     Program p = new Program(); 
     string result = p.NormalTestMethod(); 
     Assert.Equal("Ok", result); 
    } 

Cả hai phương pháp ban đầu đều ném ngoại lệ, vì vậy tôi nghĩ cả hai thử nghiệm đều thất bại nhưng kết quả lại khác. Bạn có thể xem kết quả: Test results

XunitTestMethod_Async kiểm tra vượt qua nhưng XunitTestMethod_Normal không thành công. Ném một ngoại lệ không phải là trường hợp, bạn có thể thay đổi nội dung phương pháp bất cứ điều gì bạn muốn AsyncTestMethod luôn vượt qua.

Dưới đây là giải pháp dụ: https://github.com/bahadirarslan/AsyncTestWithxUnit

tôi có thể hiểu lầm hay nghĩ sai nhưng bây giờ hành vi này gây ra rất nhiều đau đớn cho tôi

Hy vọng bạn có thể Enlight tôi.

PS: Tôi tạo ra một vấn đề tại trang github xUnit, nhưng tôi không thể chắc chắn đó là điều này gây ra từ tôi hoặc xUnit. Vì vậy, tôi quyết định yêu cầu ở đây quá. Vấn đề: https://github.com/xunit/xunit/issues/96

+2

Hãy thử thay đổi chữ ký 'async void' thành' async Task' cho 'XunitTestMethod_Async'. Tôi nhớ nhìn thấy một câu hỏi tương tự được hỏi và trả lời trước đây, nhưng không thể tìm thấy nó. – Noseratio

+2

@Noseratio tuyệt vời. Tôi không thể nghĩ câu trả lời đơn giản như thế này. Nếu bạn đăng câu trả lời bình luận của bạn tôi muốn chấp nhận nó. Rất cảm ơn. –

Trả lời

27

Vấn đề là phương thức async void không trả về đối tượng Task mà xUnit có thể kiểm tra ngoại lệ. xUnit thậm chí không thể theo dõi việc hoàn thành một phương thức cụ thể async void, trái ngược với phương thức async Task.

Hơn nữa, async void phương pháp không ném ngoại lệ trên cùng một khung ngăn xếp, ngay cả đối với trường hợp ngoại lệ được ném từ phần đồng bộ của phương thức. Thay vào đó, ngoại lệ được truyền đến ngữ cảnh đồng bộ hóa hiện tại qua SynchronizationContext.Post (trong trường hợp SynchronizationContext.Current != null) hoặc thông qua ThreadPool.QueueUserWorkItem. Hành vi này khác với phương thức async Task, more details. Có thể theo dõi tổng số phương thức async void đang chờ xử lý (qua SynchronizationContext.OperationStarted/OperationCompleted), nhưng không theo dõi các phương pháp riêng lẻ.

Vì vậy, việc thay đổi chữ ký của phương thức XunitTestMethod_Async từ async void thành async Task sẽ giải quyết được sự cố.

+1

Rất thú vị và một quirk lẻ về 'async void' nhưng nó chắc chắn có ý nghĩa. Tôi ngẫu nhiên đến với câu hỏi này, nhưng tôi rất vui vì đã đọc nó. –

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