2012-01-07 15 views
5

Używam WatiN do niektórych automatycznych testów i odkryłem, że tworzenie instancji IE dla każdego testu nie było skalowalne. Czas tworzenia i wyłączanie poszczególnych instancji IE jadł mnie przy życiu:Jak mogę się upewnić, że usunę obiekt w swoim singletonie przed zamknięciem aplikacji?

[TestMethod] 
    public void Verify_Some_Useful_Thing() 
    { 
     using (var browser = new IE()) 
     { 
      browser.GoTo("/someurl"); 
      // etc.. 
      // some assert() statements 
     } 
    } 

Jednak stosując oświadczenie nie okazać się przydatne, zawsze mogę zapewnić, że moje wystąpienie IE musiałby metoda jego Dispose() o nazwie, która zamknąć okno IE.

Zresztą stworzony pojedyncza który utrzymuje pojedynczą instancję IE którym wszystkie moje próby wykorzystania we wszystkich moich klas Test:

public class BrowserPool 
{  
    private static readonly Lazy<BrowserPool> _instance = new Lazy<BrowserPool>(() => new BrowserPool());   

    private IE _browser; 
    private string _ieHwnd; 
    private int _threadId; 

    public IE Browser 
    { 
     get 
     { 
      var currentThreadId = GetCurrentThreadId(); 
      if (currentThreadId != _threadId) 
      { 
       _browser = IE.AttachTo<IE>(Find.By("hwnd", _ieHwnd)); 
       _threadId = currentThreadId; 
      } 
      return _browser; 
     } 
     set 
     { 
      _browser = value; 
      _ieHwnd = _browser.hWnd.ToString(); 
      _threadId = GetCurrentThreadId(); 
     } 
    } 

    /// <summary> 
    /// private to prevent direct instantiation. 
    /// </summary> 
    private BrowserPool() 
    { 
     Browser = new IE(); 
    } 

    /// <summary> 
    /// Get the current executing thread's id. 
    /// </summary> 
    /// <returns>Thread Id.</returns> 
    private int GetCurrentThreadId() 
    { 
     return Thread.CurrentThread.GetHashCode(); 
    } 

    /// <summary> 
    /// Accessor for instance 
    /// </summary> 
    public static BrowserPool Instance 
    { 
     get 
     { 
      return _instance; 
     } 
    } 
} 

a test now:

[TestMethod] 
    public void Verify_Some_Useful_Thing() 
    { 
     var browser = BrowserPool.Instance.Browser; 
     browser.GoTo("/someurl"); 
     // some assertions 
    } 

to działa dobrze i moje testy przebiegają znacznie szybciej teraz, gdy nie otwieram i nie zamykam IE każdego testu. Mam jednak ten jeden problem, ponieważ po zakończeniu testów moje instancja IE pozostanie otwarta.

Nie mogę znaleźć eleganckiego sposobu, aby BrowserPool.Browser miał dispose() lub close() do wywołania, zanim aplikacja się zakończy. Próbowałem nawet używać finalizatora w klasie BrowserPool, ale to nie działało, ponieważ zmienna _browser została już odzyskana po wywołaniu mojego finalizatora.

Jak mogę się upewnić, że dispose() zostanie wywołane w mojej instancji IE po uruchomieniu testu?

+0

Czy próbowałeś umieścić utylizację w destruktorze Singleton? –

+0

@ M.Babcock, mam i to nie działało. Zmienna przeglądarki została już odzyskana przed wywołaniem destruktora. – KingNestor

Odpowiedz

4

Użyj narzędzia [AssemblyCleanupAttribute()], aby wyczyścić zasoby po zakończeniu testów znalezionych w zespole.

Btw, nigdy nie polegaj na użyciu destruktorów w .NET.

+0

Zakładając, że prowadzisz VS> Professional. – mxmissile

Powiązane problemy