2010-07-19 6 views
4

현재 HP Quality Center 10.0과 통합되는 일부 .Net 기반 소프트웨어 (.Net Framework 3.5 SP1)를 작업 중입니다. COM 클라이언트 API (TDApiOle80 또는 TDApiOle80.TDConnection이라고도 함)를 통해통합 테스트를 수행 할 때 .Net 응용 프로그램에서 불량 COM 구성 요소 (HP Quality Center 10.0)를 분리하는 방법

우리는 xUnit의 1.6.1.1521 및 (AN은 MSBuild 파일에서 호출) 갈 리오의 3.1.397.0

우리의 과정을 거쳐야 사용 : 테스트 실행 연결

  • 만들기

    • 을 GC.Collection를 (강제
    • 배치
    • 폐쇄 연결
    • )/GC.AwaitingPendingFinalizers ()

    각 통합 테스트마다 - 각 통합 테스트는 사실로 구성된 시간 초과로 실행됩니다.

    우리가 가지고있는 문제는 불려질 때 몇 가지 테스트 (약 10 정도) 품질 센터 블록이 무기한으로 나타나고 Gallio 전체가 멈추고 더 이상 응답하지 않는다는 것입니다.

    원래 우리는 xunit.net이 사실 내에서 코드에 타임 아웃을 적용했기 때문에 생성자를 무기한 대기하거나 완료 할 메소드를 처리 할 것이므로 - 확인을 위해 테스트 로직으로 로직을 옮겼습니다. ... 그러나 이것은 문제를 해결하지 못했습니다 (특정 수의 테스트를 실행 한 후에도 계속 중단됩니다).

    TestDriven.Net을 사용할 때도 똑같은 일이 발생합니다. 대화 형으로 1 개 또는 몇 개의 테스트를 실행할 수 있지만, 약 10 개 이상의 테스트와 전체 실행이 정지 할 수 있으며, TD 만 사용하는 ProcessInvocation86.exe 프로세스를 죽일 수 있습니다 .그물.

    누구나 이런 일이 발생하지 않도록하는 방법이나 이러한 종류의 문제로부터 내 통합 테스트를 차단하는 방법에 대한 팁/트릭이 있습니다. QC API가 무한정 차단되는 테스트에서 테스트가 실패합니다 시간 제한을 설정하고 Gallio가 다음 테스트로 이동하도록 허용합니다.

    업데이트 STA 스레드를 사용하여 대한 힌트 앞으로 조금 문제를 이동 도움이되었습니다

    - XUnit.Net 우리가 지금 자신의 STA 스레드에서 테스트를 시작 속성 사용자 정의를 통해. 이로 인해 Gallio/TestDriven.Net이 완전히 잠기지 않게되었으므로 hudson 빌드 서버에서 통합 테스트를 실행할 수 있습니다. 일반적으로 단지 1 또는 실패 시험 두 가지를 우연히 지나가는 몇 번 모든 테스트가 발생합니다 하나 같은 제품군을 실행 또는 - TestDriven.Net와 테스트를 실행할 때

    public class StaThreadFactAttribute : FactAttribute 
        { 
         const int DefaultTime = 30000; // 30 seconds 
    
         public StaThreadFactAttribute() 
         { 
          Timeout = DefaultTime; 
         } 
    
         protected override System.Collections.Generic.IEnumerable<Xunit.Sdk.ITestCommand> EnumerateTestCommands(Xunit.Sdk.IMethodInfo method) 
         { 
          int timeout = Timeout; 
    
          Timeout = 0; 
    
          var commands = base.EnumerateTestCommands(method).ToList(); 
    
          Timeout = timeout; 
    
          return commands.Select(command => new StaThreadTimeoutCommand(command, Timeout, method)).Cast<ITestCommand>(); 
         } 
        } 
    
        public class StaThreadTimeoutCommand : DelegatingTestCommand 
        { 
         readonly int _timeout; 
         readonly IMethodInfo _testMethod; 
    
         public StaThreadTimeoutCommand(ITestCommand innerComand, int timeout, IMethodInfo testMethod) 
          : base(innerComand) 
         { 
          _timeout = timeout; 
          _testMethod = testMethod; 
         } 
    
         public override MethodResult Execute(object testClass) 
         { 
          MethodResult result = null; 
    
          ThreadStart work = delegate 
                    { 
                     try 
                     { 
                      result = InnerCommand.Execute(testClass); 
                      var disposable = testClass as IDisposable; 
                      if (disposable != null) disposable.Dispose(); 
                     } 
                     catch (Exception ex) 
                     { 
                      result = new FailedResult(_testMethod, ex, this.DisplayName); 
                     } 
                    }; 
    
          var thread = new Thread(work); 
    
          thread.SetApartmentState(ApartmentState.STA); //Set the thread to STA 
    
          thread.Start(); 
    
          if (!thread.Join(_timeout)) 
          { 
           return new FailedResult(_testMethod, new Xunit.Sdk.TimeoutException((long)_timeout), base.DisplayName); 
          } 
    
          return result; 
         } 
        } 
    

    대신 우리는 지금과 같은 출력을 참조하십시오. 첫 번째 오류가 발생하면 두 번째 오류로 인해이 'appdomain을 언로드하는 동안의 오류'문제가 발생합니다.

    테스트 'IntegrationTests.Execute_Test1' 실패 : 테스트 실행 시간 초과 : 30000ms

    테스트 'T : IntegrationTests.Execute_Test2 ' 실패 : appdomain을 언로드하는 동안 오류가 발생했습니다. (HRESULT 예외 : 0x80131015) System.CannotUnloadAppDomainException : appdomain을 언로드하는 동안 오류가 발생했습니다. Xunit.Runner.TdNet.TdNetRunner.TestDriven.Framework.ITestRunner.RunMember에서 Xunit.ExecutorWrapper.Dispose()에서 System.AppDomain.Unload ( 도메인의 AppDomain) (ITestListener 수신기에서 : (0x80131015 HRESULT에서 예외) TestDriven.TestRunner.AdaptorTestRunner.Run (ITestListener testListener, ITraceListener TraceListener에서, TestDriven.TestRunner.ThreadTestRunner.Runner.Run()에서 assemblyPath 문자열, 문자열 testPath)

    에서, 어셈블리 어셈블리 MemberInfo가 부재) 4 건 통과, 2 건 실패, 0 건 건너 뛰기, 012 건50.42 초 (xunit).

    저는 아직 Quality Center API가 무한정 무제한으로 매달려있는 이유를 아직 밝히지 않았으며 조만간이를 조사 할 것입니다.

    업데이트 드디어 매달려의 원인이 설립 한

    27/07/2010 - 여기에 문제가있는 코드입니다 :

    connection = new TDConnection(); 
    connection.InitConnectionEx(credentials.Host); 
    connection.Login(credentials.User, credentials.Password); 
    connection.Connect(credentials.Domain, credentials.Project); 
    connection.ConnectProjectEx(credentials.Domain, credentials.Project, credentials.User, credentials.Password); 
    

    연결이 ConnectProjectEx 다음 부르심 것으로 보인다 기회가있다 차단 (하지만 비 결정적입니다). 나는 많은 생각의 연결 코드를 제공하지 않은 코드베이스를 상속 데

    connection = new TDConnection(); 
    connection.InitConnectionEx(credentials.Host); 
    connection.ConnectProjectEx(credentials.Domain, credentials.Project, credentials.User, credentials.Password); 
    

    : 올바른 연결 코드 - 중복 연결 호출을 제거하면 극적으로 테스트의 안정성을 증가 것 같습니다.

    내가 아직 알아 내지 못한 한 가지 이유는 위에 포함 된 제한 시간 코드를 사용해도 Thread.Join (timeout)이 반환되지 않는 이유입니다. 디버거를 연결할 수 있으며 테스트 스레드가 결합/대기 작업에 있음을 보여줍니다. 아마도 STA 스레드에서 실행하는 것과 관련이 있을까요?

  • +3

    그래서, 그들은 단지 아이러니했다? – Gabe

    +0

    그냥 제품에 대한 비누 나 REST 서비스에 대해 내가 제품의 팬이 아니라고합시다 : – Bittercoder

    +0

    QC 10에 대해 OTA/TDApiOle80에서 실행되는 수백 가지의 통합 테스트가 있습니다. 아무 문제 나 블로킹이 없습니다. 그래서 이론적으로 당신은 똑같이 할 수 있어야합니다. 차단 문제 자체를 해결하려고 시도해 보셨습니까? 문제를 해결하려고 시도하는 것이 아니라 차단하는 이유를 이해하는 것이 더 나을 수도 있습니다. –

    답변

    1

    는 그런 다음, 별도의 스레드에서 코드를 실행하는 시간 종료와 함께 새로운 스레드에서 Join를 호출하고 시간 제한 안타 경우를 중단 시도 할 수 있습니다. 예를 들어

    : 그들은 그것을 "품질 센터"를 부를 때

    static readonly TimeSpan Timeout = TimeSpan.FromSeconds(10); 
    public static void RunWithTimeout(ThreadStart method) { 
        var thread = new Thread(method); 
        thread.Start(); 
        if (!thread.Join(Timeout)) { 
         thread.Abort(); 
         Assert.False(true, "Timeout!"); 
    } 
    
    +0

    나는 그것이 작동하지 않을까 걱정됩니다 - 이것은 XUnit Fact 속성의 타임 아웃 값이 이미 수행하고있는 것입니다. 수동으로이 작업을 수행해도 문제가 해결되지 않는 경우 - Quality Center 라이브러리 호출로 인해 모든 작업이 중단 될 때 표시됩니다. 디버거를 프로세스에 연결하면 모든 스레드가 차단/조인을 기다리고 있음을 알 수 있으므로 (비록 내가 도움이되는지 아직 Intellitrace를 시도하지 않았지만) 스택 트레이스를 얻는다. – Bittercoder

    +0

    @Bittercoder : 나는 그것이 가능한 방법을 이해하지 못합니다. 스레드를 STA 또는 MTA로 설정해보십시오. – SLaks

    +1

    테스트가 STA 스레드에서 실행되는지 확인하십시오. TDConnection은 실행중인 MTA 스레드와 잘 반응하지 않습니다. –

    관련 문제