2014-05-23 16 views
14

우리는 xUnit 프레임 워크를 처음부터 테스트 프레임 워크로 사용했습니다. 현재 프로젝트에 2200 이상의 유닛 테스트가 있으며 모든 것이 잘된 것처럼 보입니다.xUnit 비동기 테스트가 제대로 작동하지 않음

어제 나는 CI 빌드와 야간 빌드에서 단위 테스트를하기로 결정했습니다. 1 시간에서 2 시간 동안 xunit 테스트를 실행하는 팀 빌드 컨트롤러와 함께 테스트를 진행하는 데 성공합니다. 하지만 거기에 문제가 있었는데, 거기에 22 경고에 대한 테스트와 같은 - Xunit.Sdk.EqualException : Assert.Equal() 실패 또는 - System.ArgumentNullException : 값은 null 일 수 없습니다.

더 많은 조사가 끝나면이 테스트가 실패해야한다는 것을 깨달았지만 이러한 테스트 모두에 "비동기"키워드가 표시되어 통과 된 것 같습니다. xUnit의이 http://bradwilson.typepad.com/blog/2012/01/xunit19.html http://sravi-kiran.blogspot.com.tr/2012/11/UnitTestingAsynchronousMethodsUsingMSTestAndXUnit.html Howerver 현실 나를 위해 경미한 차이가이 게시물에 대한 비동기 테스트를 지원하기 때문에

사실, 오류가 없을 것이다. 예 xUnit은 문제없이 실행되지만 제대로 테스트되지 않습니다.

다음 두 가지 방법이 있습니다.

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

만 차이를 볼 수 있듯이, "비동기" 그리고 여기로 정의 된 첫 번째 방법은이 방법에 대한 두 가지 시험이다.

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

원래의 두 메소드 모두 예외가 발생하므로 두 테스트 모두 실패해야하지만 결과는 다릅니다. 결과는 다음과 같습니다. Test results

XunitTestMethod_Async 테스트 통과지만 XunitTestMethod_Normal은 실패합니다. 예외를 throw하는 경우가 아니라면, AsyncTestMethod가 항상 통과 시키길 원하는대로 메서드 내용을 변경할 수 있습니다. 내가 오해 나 잘못된 생각하지만 지금은이 동작을

당신이 날 ENLIGHT 수 있기를 바랍니다 나를 위해 고통의 많은 원인이 있습니다 https://github.com/bahadirarslan/AsyncTestWithxUnit

: 여기

는 예 솔루션입니다.

추신 : 나는 xUnit github 페이지에서 문제를 만들었지 만, 이것이 나 또는 xUnit에서 발생했는지 확신 할 수 없습니다. 그래서 나는 여기에도 물기로 결정했다. 문제 : https://github.com/xunit/xunit/issues/96

+2

'XunitTestMethod_Async'에 대해'async void' 서명을'async Task'로 변경해보십시오. 이전에 비슷한 질문을하고 기억하지만 기억이 안납니다. – Noseratio

+2

@Noseratio amazing. 나는 대답이 이렇게 단순하다고 생각할 수 없었다. 귀하의 의견을 게시하면 답변을 수락하고 싶습니다. 정말 고마워. –

답변

27

문제는 async void 방법 xUnit의 가능성이 예외를 검사 할 수있는 Task 개체를 반환하지 않습니다. xUnit은 async Task 메서드가 아니라 특정 async void 메서드의 완료를 추적 할 수도 없습니다.

또한 async void 메서드는 메서드의 동기 부분에서 throw 된 예외의 경우에도 동일한 스택 프레임에 예외를 throw하지 않습니다. 오히려 예외는 SynchronizationContext.Post (SynchronizationContext.Current != null의 경우) 또는 ThreadPool.QueueUserWorkItem을 통해 현재 동기화 컨텍스트로 전파됩니다. 이 동작은 async Task 메서드와 다릅니다 (more details). 대기중인 async void 메소드의 총 수를 (SynchronizationContext.OperationStarted/OperationCompleted을 통해) 추적 할 수 있지만 개별 메소드는 추적 할 수 없습니다.

따라서 async void에서 XunitTestMethod_Async 방법의 서명을 변경하면 async Task으로 변경해야 문제가 해결됩니다.

+1

'async void'에 대한 흥미롭고 이상한 버릇이 있지만 분명히 이해가됩니다. 나는이 질문에 무작위로 나왔다. 그러나 나는 그것을 읽었 기 때문에 기쁘다. –

관련 문제