2016-09-20 49 views
-1

我遇到的問題是我有一堆從父類(BasePage)繼承的類(Pages)。任何時候我初始化一個子類,我還需要運行一個名爲WaitForLoadingToStop()的方法。我如何繼承這個方法並將其實現到我的子類的構造函數中?如何強制繼承類在其構造函數中實現方法?

這就是我需要改變的地方,因爲它被複制到所有的地方,所以我希望這個在創建類時自動被繼承和執行。

 var assPage = new StudentAssesmentPage(Driver); 
     assPage.WaitForLoadingToStop(); 

這是一個示例子類,我有10人是這個樣子

public class StudentAssesmentPage : BasePage<StudentAssesmentPageObjectRepository> 
{ 
    public StudentAssesmentPage(IWebDriver driver) : base(driver, new StudentAssesmentPageObjectRepository(driver)) 
    {} 
} 

下面是我BasePage類

public abstract class BasePage<TObjectRepository> where TObjectRepository : BasePageObjectRepository 
{ 
    protected WebDriverWait Wait { get; } 
    protected IWebDriver Driver { get; } 
    protected ApplicationUrls ApplicationUrls { get; } 
    public IJavaScriptExecutor JavascriptExecutor { get; } 
    protected Actions UserInteractions { get; private set; } 

    protected By _loadingSpinnerLocator = By.Id("spinner"); 
    private readonly double LOADING_SPINNER_TIMEOUT = 60; 
    private TObjectRepository _objectRepository; 

    public BasePage(IWebDriver driver, TObjectRepository repository) 
    { 
     Driver = driver; 
     _objectRepository = repository; 
     UserInteractions = new Actions(Driver); 
     ApplicationUrls = new ApplicationUrls(); 
     Wait = new WebDriverWait(Driver, TimeSpan.FromSeconds(GetPageTimeout())); 
     JavascriptExecutor = Driver as IJavaScriptExecutor; 
    } 

    internal TObjectRepository ObjectRepository 
    { 
     get { return _objectRepository; } 
    } 

    protected bool WaitForLoadingToStop(int secondsToSleep = 5) 
    { 
     var sleepTime = TimeSpan.FromSeconds(secondsToSleep); 
     Reporter.Debug($"{Helpers.GetCurrentMethodName()}. Going to sleep for:{sleepTime.Seconds}"); 
     Thread.Sleep(sleepTime); 
     Reporter.Debug($"Now, going to wait for loading spinner for:{LOADING_SPINNER_TIMEOUT} seconds."); 
     var basePageWait = new WebDriverWait(Driver, TimeSpan.FromSeconds(LOADING_SPINNER_TIMEOUT)); 
     basePageWait.Message = 
      $"Waited for {LOADING_SPINNER_TIMEOUT}sec for the spinner. However, it took longer than that for the application to load."; 


     return basePageWait.Until(ExpectedConditions.InvisibilityOfElementLocated(By.XPath("//img[@src='/Content/images/spinner.gif']"))); 
    } 
} 
+1

混淆......'WaitForLoadingToStop'是基類的一部分,但你直接調用它,沒有上面示例中的實例。你的意思是'assPage.WaitForLoadingToStop()...'? –

+0

哎呀,謝謝你指出。 –

+0

你的問題沒有意義。 'WaitForLoadingToStop()'是'protected',但顯然是由聲明類之外的代碼調用的?無論如何,建設者花費時間是一個壞主意。處理冗長初始化的通常方法是編寫一個工廠方法。你可以在那裏等待,或者更好地使整個事情異步。至於你的問題到目前爲止,還不清楚它將如何工作,除了將該調用放入每個子類的構造函數之外。 –

回答

-1
public class StudentAssesmentPage : BasePage<StudentAssesmentPageObjectRepository> 
{ 
    public StudentAssesmentPage(IWebDriver driver) : base(driver, new StudentAssesmentPageObjectRepository(driver)) 
    { 
     base.WaitForLoadingToStop(); 
    } 
} 
+0

我認爲這個想法對於基類來說並不是都需要手動調用方法。而且,僅有代碼的答案通常可以從一些解釋中受益。 –

+0

我同意@AndrewPiliser,我不想在每個構造函數中都繼續調用這個方法。它違反了DRY priniciple,這正是我試圖解決的問題。 –

1

從基類只是繼承實現BasePageThatWaitsForLoadingToStop,它在構造函數中爲你完成工作。剩下的就是傳遞一個具體實施的構造函數的參數(如StudentAssesmentPage這個基類)

public class StudentAssesmentPage : BasePageThatWaitsForLoadingToStop 
{ 
    public StudentAssesmentPage(IWebDriver driver) : base(driver, new StudentAssesmentPageObjectRepository(driver)) // this is the only boilerplate code that is left 
    { 

    } 
} 

public class BasePageThatWaitsForLoadingToStop : BasePage<StudentAssesmentPageObjectRepository> 
{ 
    public BasePageThatWaitsForLoadingToStop(IWebDriver driver) : base(driver, new StudentAssesmentPageObjectRepository(driver)) 
    { 
     base.WaitForLoadingToStop(); 
    } 
} 

唯一的樣板代碼然後,您可以簡單地調用它,如下所示,它會自動執行爲您的工作:

var assPage = new StudentAssesmentPage(Driver); 

但是,請注意,從測試的角度來看,它是不理想的在構造函數中工作。

+0

感謝您的建議。我有個問題。爲什麼我不能在BasePage構造函數中做同樣的事情而不是新的類? –

+0

你也可以這樣做。就個人而言,我寧願通過具有實現接口的純粹抽象基類的基本實現來保持事物分離(即,純抽象類/方法及其基本實現)。使用這種技術,你可以創建例如爲某些方法提供默認實現的基類(如果你願意的話,仍然可以重寫)以及其他方法可以強制繼承類實現一個方法。 – bergmeister

+0

關於你在主要評論部分提出的其他問題:正如我所說的,在構造函數中進行工作使測試課程變得困難和昂貴(例如,請參見18:00 http://www.youtube.com/watch?v = acjvKJiOvXw)。改爲使用依賴注入(DI)。例如使用DI,你可能有一個Margherita類,它只在構造函數中設置它的定義屬性,然後傳遞給Pizza工廠,它處理所有的複雜性。這也允許延遲初始化,即您可以執行大量的命令,但實際上只在確實需要時才執行該工作。 – bergmeister