将功能和基本测试分成两个cs文件

时间:2014-06-30 17:11:52

标签: c# selenium

我想为我的所有测试项目创建全局cs文件,以保留我的所有常量和函数。 例如,此文件用于不同的测试global.cs:

namespace SeleniumTests
{ 
    Public class forAllTests
    {
        //....
        public void Login()
        { 
            wait.Until<IWebElement>((d) => { return d.FindElement(By.Id("login")); });
            driver.FindElement(By.Id("login")).SendKeys("login");
            wait.Until<IWebElement>((d) => { return d.FindElement(By.Id("password")); });
            driver.FindElement(By.Id("password")).SendKeys("password");
        }
    }
}

例如另一个文件Program.cs

namespace SeleniumTests
{ 
    Public class Test
    { 
        forAllTests.Login();
        //.....
    }
}

它可能与否?

UPD。

感谢您的回答。是的,我想要更具体的建议。我正在为Firefox,Chrome和Safari进行测试。我知道页面对象模式,我正在使用它。例如我的一些代码。 这里有一些代码(部分3 * 4 * - 不起作用,并希望使它们正确,请帮助我)。它现在如何运作: 1 * Program.cs -

       using System;
        using System.Web;
        using System.Text;
        using System.Text.RegularExpressions;
        using System.Threading;
        using NUnit.Framework;
        using OpenQA.Selenium;
        using OpenQA.Selenium.Chrome;
        using OpenQA.Selenium.Safari;
        using OpenQA.Selenium.Firefox;
        using OpenQA.Selenium.Support.UI;
        using OpenQA.Selenium.Support.PageObjects;
        using System.Diagnostics;
        using System.Threading;
        using Microsoft.Office.Interop.Excel;
        using Excel = Microsoft.Office.Interop.Excel;
        using System.Web;
        using System.Linq;
        using System.Windows.Forms;
        using System.IO;
        using System.Windows.Controls;





         namespace SeleniumTests
            {

                [TestFixture]
                public class Auth01
                {

                    private bool acceptNextAlert = true;
                    private LoginPage loginPage;
                    private PatientsPage patientsPage;        
                    private MainViewPage mainViewPage;
                    private EmkPage emkPage;
                    private IWebDriver driver;
                    private StringBuilder verificationErrors;
                    private string baseURL;                      
                    string drop_down_id;
                    string drop_down_text;
                    string url1;
                    string url2;
                    string now1;


                    [SetUp]
                    public void SetupTest()
                    {
                        driver = new FirefoxDriver();
                        driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(10));
                        baseURL = "http://....";
                        driver.Navigate().GoToUrl(baseURL + Constants.startUrl);
                        // driver.Manage().Window.Maximize();
                        loginPage = new LoginPage();
                        PageFactory.InitElements(driver, loginPage);
                        verificationErrors = new StringBuilder();

                    }


                     public void login()
                    {
                        WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
                        loginPage.Login.Clear();
                        loginPage.Login.SendKeys("login");
                        loginPage.Password.Clear();
                        loginPage.Password.SendKeys("password");
                        IWebElement myDynamicElement = wait.Until<IWebElement>((d) => { return d.FindElement(By.CssSelector(loginPage.enterbuttonPublic)); });
                        loginPage.EnterButton.Click();
                    }

        public void drop_down()
                    {
                        IWebElement elem = driver.FindElement(By.Id(drop_down_id));           
                        var options = elem.FindElements(By.TagName("option"));
                        string opt;
                        string value;
                        string x;
                        foreach (IWebElement option in options)
                        {

                            opt = option.Text;
                            value = option.GetAttribute("value");
                            if (drop_down_text.Equals(opt))
                            {
                                x = "//select[@id='" + drop_down_id + "']/option[@value='" + value + "']";

                            }
                        } 
                    }



                    [TearDown]
                    public void TeardownTest()
                    {
                        try
                        {
                            driver.Quit();
                        }
                        catch (Exception)
                        {

                        } Assert.AreEqual("", verificationErrors.ToString());
                    }

                    [Test]
                    public void The0Auth01Test()
                    {
                        Stopwatch stopWatch = new Stopwatch();
                        stopWatch.Start();
    login();
                     //.....
    drop_down_id="id";
    drop_down_text = "text";
    drop_down();
    //...
    stopWatch.Stop();
    } 
 static void Main()
        {

            Auth01 Auth01_1 = new Auth01();
            Auth01_1.SetupTest();
            Auth01_1.The0Auth01Test();
        }

2 * AllAuth.cs --- //适用于所有测试

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.IE;
using OpenQA.Selenium.Support.UI;
using OpenQA.Selenium.Support.PageObjects;
using System.IO
;


namespace SeleniumTests
{

 public class LoginPage
    {



        private IWebDriver driver;
        const string login = "USERNAME";  
        public string loginPublic = login;
        [FindsBy(How = How.Id, Using = login)]  
        public IWebElement Login { get; set; }
        const string password = "PASSWORD";  
        public string passwordPublic = password;
        [FindsBy(How = How.Id, Using = password)]  
        public IWebElement Password { get; set; }
        const string enterbutton = "button.button-gray"; 
        public string enterbuttonPublic = enterbutton;
        [FindsBy(How = How.CssSelector, Using = enterbutton)]
        public IWebElement EnterButton { get; set; }
        const string notification = "#notification-message";  
        public string notificationPublic = notification;  
         [FindsBy(How = How.CssSelector, Using = notification)]
        public IWebElement Notification { get; set; }
        const string body = "BODY";    
        public string bodyPublic = body;
        [FindsBy(How = How.CssSelector, Using = body)]
        public IWebElement Body { get; set; }

        public LoginPage() { }

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


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

    }

3 *我梦想着:

AllAuth.cs ---

///...
namescpace SeleniumTests 
{
/////.....
public class Fantasy
{
 private IWebDriver driver;
login()
{
//....
}
drop_down()
{
//...
}
}
}

4 * Program.cs ---

///...
    namescpace SeleniumTests 
    {
    /////.....
 [Test]
                    public void The0Auth01Test()
                    {
fantasy.login();
fantasy.drop_down();
}
///...
}

1 个答案:

答案 0 :(得分:1)

当然有可能。 Selenium仅通过WebDriver.dll访问API以驱动浏览器。您想要使用的任何编码结构都可以轻松用于此目的。我为一家公司做了一个7层版本,看到很多人只是在1,2或3层写下它们。

问题是什么对您的组织最有利。例如......如果您使用特定的UnitTest Framework,那么您的“测试”将全部存在于单元测试项目中,并引用类似于API层的核心功能。我建议至少要将其合并,因为应用程序中常见控件的重复代码对于可维护性和最佳实践来说真的很差。

以上是图层而不是文件。除非你只有5次总测试,否则尝试将所有内容放入一个或两个文件中是非常不切实际和困难的。我真的建议使用常见的编码标准和实践来配合Selenium测试,就像常规的c#代码一样。以下链接适用于c#,因为它被标记为c#。

命名约定:http://msdn.microsoft.com/en-us/library/ff926074.aspx

框架指南:http://msdn.microsoft.com/en-us/library/ms229042.aspx

标准指南:http://blogs.msdn.com/b/brada/archive/2005/01/26/361363.aspx

如果您想了解更多内容...如果您想要更具体的建议,请在您的问题中添加更多详细信息,以指明您的项目是什么,测试的数量,Web应用程序类型的具体情况以及有多少不同的浏览器支持类型,它支持移动,数据库使用,团队规模等......所有因素都成为一个好的设计

更新: 看起来你是在正确的道路上,但是你需要设置你的驱动程序并将其传递给函数......或者使用对所有人都相同的公共/受保护变量。你现在拥有它的方式看起来它每次调用一个单独的函数/方法时都会启动一个新的驱动程序,这当然是行不通的。

因此,使用(#4)中的单个测试方法将您的设置置于测试文件(#3)的顶部以“设置”。当调用(#4)第一个测试时,安装程​​序将实例化您的驱动程序并将其保存在(#3)中。然后将该驱动程序变量传递到(#3-&gt;#2)上的所有函数中,以便它们在同一个驱动程序实例上执行。实际的设置调用应该在(#3)中,但调用与fantasy.setup()相似;来自(#4)。同样,当您更新页面对象时,您将现有的驱动程序传递给它,并使用新的页面对象覆盖现有的页面对象...除非您想保留一堆不同的页面...监视内存使用情况。这将使您的方法根本不必担心驱动程序处理。这也将允许您启动多个测试线程,每个线程都将维护自己的驱动程序。然后当你调用fantasy.login();它将转到(#3)中的该方法并调用(#2)方法并将私有驱动程序从(#3)中的内存传递到(#2)方法以供执行。

如果不清楚,请告诉我......