2011-11-16 29 views
28

C#.NetでSelenium 2 Web Driverを使用してテストを作成しています。 Seleniumのドキュメントをたくさん読んだ後も、PageObjectのデザインパターンを使ってテストする方法についてはまだ分かりません。Selenium PageObjectデザインパターンを使用する最良の方法は

セレンの例の多くはJavaでのみ表示されています.Net用のAPIバインディングは、制限や特定の言語によって設定された基準に起因するとは限りません。

.Net Selenium Web DriverのPageFactoryでPageObjectデザインパターンを使用する最も良い方法は何ですか?

PageObject IWebElementsを使用したNUnitテストではなく、より多くの機能を処理するようにしたいと考えています。

以下は、私が現在テストを作成する方法の例です。

[TestFixture] 
public class LoginPageTest : TestBase 
{ 
    private IWebDriver driver; 
    private LoginPage loginPage; 
    private HomePage homePage; 

    [SetUp] 
    [Description("Sets up the test fixture page objects and navigates to the login page.")] 
    public void SetUp() 
    { 
     driver = StartDriver(); 
     Log.Info("Driver started"); 
     driver.Navigate().GoToUrl("http://" + Environment + "); 
     loginPage = new LoginPage(); 
     PageFactory.InitElements(driver, loginPage); 
     //driver.Navigate().Refresh(); 
    } 

    [Test] 
    [Description("Enters invalid credentials and asserts that a correct error message is displayed.")] 
    public void SubmitFormInvalidCredentials() 
    { 
     loginPage.UserName.SendKeys("invalid"); 
     loginPage.Password.SendKeys("invalid"); 
     loginPage.SubmitButton.Click(); 
     IWebElement invalidCredentials = driver.FindElement(By.Id("ctl00_ctl00_ctl00_insideForm_insideForm_ctl02_title")); 
     Assert.AreEqual("Invalid user name or password", invalidCredentials.Text); 
    } 

    [Test] 
    [Description("Enters valid credentials and asserts that the user is taken to the home page.")] 
    public void SubmitFormValidCredentials() 
    { 
     loginPage.UserName.SendKeys("valid"); 
     loginPage.Password.SendKeys("valid"); 
     loginPage.SubmitButton.Click(); 

     homePage = new HomePage(); 
     PageFactory.InitElements(driver, homePage); 
     Assert.AreEqual("pattest", homePage.Username.Text); 
    } 

} 

私はセレンwebdriverをデザインパターンを見つけるの記事やブログ記事のほとんどは、私が見つける前のポストに矛盾を放つ:これは私は現在、NUnitのでやっているものです瞬間

public class LoginPage 
{ 
    private IWebDriver webDriver; 

    [FindsBy(How = How.Id, Using = "ctl00_ctl00_ctl00_insideForm_insideForm_content_txtPassword")] 
    public IWebElement Password { get; set; } 

    [FindsBy(How = How.Id, Using = "ctl00_ctl00_ctl00_insideForm_insideForm_content_cmdSubmit")] 
    public IWebElement SubmitButton { get; set; } 

    [FindsBy(How = How.Id, Using = "ctl00_ctl00_ctl00_insideForm_insideForm_content_txtUserName")] 
    public IWebElement UserName { get; set; } 

    public LoginPage() { } 

    public LoginPage(IWebDriver webDriver) 
    { 
     this.webDriver = webDriver; 


     if(!webDriver.Url.Contains("Login.aspx")) 
     { 
      throw new StaleElementReferenceException("This is not the login page"); 
     } 
     PageFactory.InitElements(webDriver, this); 
    } 

    public HomePage signIn(string username, string password) 
    { 
     UserName.SendKeys(username); 
     Password.SendKeys(password); 
     SubmitButton.Submit(); 

     // Even if i create a NUnit test for this 
     // Issue with page loading still occures when I try and return new object 
     HomePage homePage = new HomePage(webDriver); 
     PageFactory.InitElements(webDriver, homePage); 
     return homePage; 
    } 
} 

だから、正しい方法は何ですか?

これを取り除くために、PageObjectデザインパターンを試してみました。

​​ 私LoginPageインサイド

public LoginPage(IWebDriver driver) 
    { 
     this.driver = driver; 

     if (!driver.Url.Contains("Login.aspx")) 
     { 
      throw new ElementNotFoundException("This is not the login page"); 
     } 
     PageFactory.InitElements(driver, this); 
    } 

    public HomePage SignIn(string username, string password) 
    { 
     UserName.SendKeys(username); 
     Password.SendKeys(password); 
     SubmitButton.Click(); 
     return new HomePage(driver); 
    } 

そして、もちろん私のホームページは、そのコンストラクタで開始する方法を示すために:

私はと効果的にwebdriverをのPageObjectデザインパターンを使用するにはどうすればよい
public HomePage(IWebDriver d) 
    { 
     webDriver = d; 
     // I need to use this as its not freaking waiting for my Page to load when I pass the webdriver in the consturctor. 
     var wait = new WebDriverWait(webDriver, TimeSpan.FromSeconds(60)); 

     try 
     { 
      wait.Until(driver => driver.FindElement(By.Id("ctl00_ctl00_ctl00_insideForm_insideForm_loginStatus"))); 
     } 
     catch(Exception e) 
     { 
      throw new ElementNotFoundException("This is not the home page."); 
     } 
     PageFactory.InitElements(webDriver, this); 
    } 

テスト。 私はこれを理解できません。

答えて

16

PageFactory.InitElements(_driver, this);お使いのベースページクラスのコンストラクタに:

public class Page 
{ 
    public IWebDriver _driver; 

    public Page(IWebDriver driver) 
    { 
     this._driver = driver; 
     PageFactory.InitElements(_driver, this); 
    } 
} 

PageFactory documentation

+0

はい、これは私がプロジェクトを始めたときに終わった構造です。 +1 –

+4

質問、もしあなたの要素がpageobjectの 'Select'(ドロップダウンリスト)ならどうしますか?私はあなたが選択(ドロップダウンリスト)のためにpageobjectを使用することはできないと言われているそれは本当ですか? –

+0

誰かが@Nick Kahnの質問にお答えできますか?私は同じ問題を抱えています。 –

1

私はテストでアサートを避け、ログインに失敗した場合に例外をスローするLoginPage.signInメソッドを使用します。私はNUnitに精通していないが、私はそれが '失敗する予期しない'動作をサポートしていると思う。

ページ依存ロジックを1つの場所(ページクラス)に保存することをお勧めします。

とにかく、主なアプリが進化するにつれて、Web UIテストをたくさん変更する必要があるようです。

+1

おかげで答えるが、私はそれを使用してpercieve方法は、エラーの原因となっている理由、それはこれを行う必要があるため(、ページの負荷を無視して、このようなwebdriverを、ページオブジェクトデザインパターを使用したりする方法をこれはまだ説明していません私が提出したときにページを読み込むのを止めるのはなぜですか? 私が新しいのPageObjectを返すときには、起こっていることに私には思われるが、私はまだ同じWebドライバを参照して渡しているので、私は私が間違ってやって表示されません。 このページオブジェクトのデザインパターンは、実際にはセレンのwikiに関する多くのドキュメントが必要です。 =/ –

+0

私はまた、アサルトに関するあなたのアドバイスに同意します。一度に1ステップずつ、予想される例外をサポートしています。誰かが私は私がなっていたエラーを修正し、質問、申し訳ありません:) –

+0

に私を啓発することができるまで、あなたはそれが私の実際のPageObjectsに文を主張移動するために許容可能だと思いますか? 投げられた例外がユニットテストに含まれることを予期するすべてのアサーション。 – Bond

1

は、ブラウザを閉じるためのドライバと、ナビゲーションとティアダウンのための後藤()(と同様の機能)を作成するために、ブラウザのクラスの作成を参照してくださいしてください。 `

public class Browser 
    { 
     static IWebDriver webDriver = new FirefoxDriver(); 
     //static IWebDriver webDriver = new ChromeDriver(); 
     //InternetExplorerOptions options = new InternetExplorerOptions(); 
     //static IWebDriver webDriver = new InternetExplorerDriver(@"C:\Program Files\Selenium\"); 
     public static void GoTo(string url) 
     { 
      //webDriver.Manage().Timeouts().ImplicitlyWait(new TimeSpan(0, 0, 5)); 
      webDriver.Url = url; 
     } 
     public static ISearchContext Driver 
     { 
      get { return webDriver; } 
     } 
     public static void Teardown() 
     { 
      webDriver.Quit(); 
     } 
     public static void MaximizeWindow() 
     { 
      webDriver.Manage().Window.Maximize(); 
     } 

ページの個別のクラスを作成し、PageFactoryを使用して要素を初期化します。

public class Admin 
    { 
     public static AdminPage AdminPage 
     { 
      get 
      { 
       var adminpage = new AdminPage(); 
       PageFactory.InitElements(Browser.Driver, adminpage); 
       return adminpage; 
      } 

     } 
    } 
    public class AdminPage 
    { 
     string Url = "http://172.18.12.225:4444/admin/admin.aspx"; 
     string Title = "Login"; 
     string Text = "Admin"; 
     public void GoTo() 
     { 
      Browser.GoTo(Url); 
     } 
     public bool IsAt() 
     { 
      return Browser.Title == Title; 
     } 
     public bool Is_At() 
     { 
      return Browser.Title == Text; 
     } 
     [FindsBy(How = How.Id, Using = "ctl16_lblUdpSageMesageCustom")] 
     public IWebElement UpdateMessage { get; set; } 

     [FindsBy(How = How.Id, Using = "hypPreview")] 
     public IWebElement BackHomeLink { get; set; } 
     //Login 
     // [FindsBy(How = How.Id, Using = "ctl14_UserName")] 
     // public IWebElement UserNameLink { get; set; } 
     [FindsBy(How = How.Id, Using = "ctl14_Password")][CacheLookup] 
     public IWebElement PasswordLink { get; set; } 
     [FindsBy(How = How.Id, Using = "ctl14_LoginButton")][CacheLookup] 
     public IWebElement LoginLink { get; set; } 
     //Forgot Password 
     [FindsBy(How = How.Id, Using = "ctl14_hypForgotPassword")][CacheLookup] 
     public IWebElement FPWLink { get; set; } 
     [FindsBy(How = How.Id, Using = "ctl14_wzdForgotPassword_txtUsername")][CacheLookup] 
     public IWebElement FPWUserNameLink { get; set; } 
     [FindsBy(How = How.Id, Using = "ctl14_wzdForgotPassword_CaptchaValue")][CacheLookup] 
     public IWebElement FPWCaptchaLink { get; set; } 
     [FindsBy(How = How.Id, Using = "ctl14_wzdForgotPassword_StartNavigationTemplateContainerID_StartNextButton")][CacheLookup] 
     public IWebElement FPWNextLink { get; set; } 
     [FindsBy(How = How.Id, Using = "ctl14_wzdForgotPassword_StartNavigationTemplateContainerID_CancelButton")][CacheLookup] 
     public IWebElement FPWCancelLink { get; set; } 
     [FindsBy(How = How.Id, Using = "sfToppane")][CacheLookup] 
     public IWebElement TopPane { get; set; } 
     [FindsBy(How = How.Id, Using = "sidebar")][CacheLookup] 
     public IWebElement sidebar { get; set; } 
     //Role 
     //[FindsBy(How = How.Id, Using = "ctl19_rptDashBoard_ctl01_hypPageURL")] 
     //public IWebElement Role { get; set; }  
     //User 
     //[FindsBy(How = How.Id, Using = "ctl19_rptDashBoard_ctl02_hypPageURL")] 
     //public IWebElement User { get; set; } 
     public void LogIn(string Username, string Password) 
     { 
      Browser.MaximizeWindow(); 
      IWebElement UserNameLink = Browser.WaitForElement(By.Id("ctl14_UserName"), 15); 
      UserNameLink.Click(); 
      UserNameLink.Clear(); 
      UserNameLink.SendKeys(Username); 
      PasswordLink.Click(); 
      PasswordLink.Clear(); 
      PasswordLink.SendKeys(Password); 
      LoginLink.Click(); 
     } 
} 

これはログイン機能を備えた小さな例です。 私はこれが遅れて返信しても助けてくれることを願っています。あなたのための

+0

上記はフレームワーク用であり、Microsoft Visual Studio Unit Test Frameworkを使用して作成した単体テストでページの機能を呼び出すテストを作成する方が良いでしょう。 – user3687440

+0

Browser.WaitForElementメソッドに使用されるコードを共有できますか?また、ページオブジェクト経由で作成されたIWebElementからIWebDriverを取得するにはどうすればよいですか? –

関連する問題