【问题标题】:Test Automation Framework for Web Application using Java使用 Java 的 Web 应用程序测试自动化框架
【发布时间】:2013-11-16 22:37:22
【问题描述】:

我开始为我的 Web 应用程序用 Java(我熟悉的语言)编写测试自动化框架。目前,它完全在 UI 上进行了测试。近期没有后端/API 测试。

我打算使用 Selenium Web Driver。该框架将支持功能/集成和性能测试。

我第一次使用开源解决方案进行构建(过度使用 LoadRunner 等工具),我的需求是该框架将与 Jenkins/Hudson 等持续集成工具和用于报告结果的内部测试管理工具一起使用。

我搜索了这个特定的场景,但找不到。我知道会有很多集成、插件等需要构建。我的问题是您能否提供一些指导(即使是好的阅读也可以)开始使用开源解决方案构建这个框架?

【问题讨论】:

  • 我最近一直在尝试在我的 GitHub 存储库上编写一个框架,但到目前为止,我仍在努力解决最后的问题。我可能会在年底前完成它。

标签: selenium-webdriver jenkins-plugins hudson-plugins gui-test-framework


【解决方案1】:
  • Selenium 将允许您自动执行所有网络(浏览器)操作 自动化。
  • Junit/TestNG作为测试框架, 包括他们的默认报告系统
  • Maven 项目 管理和生命周期(包括surefire plugin 的测试阶段)
  • Jenkins 是一个很好的集成工具,可以轻松 运行上面的设置

祝你好运!

【讨论】:

  • 谢谢伊蒂尔。我会合并这些。
【解决方案2】:

我在这里给出了大大减少代码的框架函数

public TestBase() throws Exception{
    baseProp = new Properties();
    baseProp.load(EDCPreRegistration.class.getResourceAsStream("baseproperties.properties"));

    // Firefox profile creation
    FirefoxProfile profile = new FirefoxProfile();
    profile.setPreference("network.proxy.type", ProxyType.AUTODETECT.ordinal());
    profile.setPreference("browser.cache.disk.enable", false); 

    profile.setPreference("network.proxy.http", "localhost");
    profile.setPreference("network.proxy.http_port",8080);
    driver = new FirefoxDriver(profile);
    //System.setProperty("webdriver.ie.driver","E:\\Phyweb Webdriver\\IEDriverServer.exe");
    //driver = new InternetExplorerDriver();
    driver.manage().window().maximize();
}

 //To find WebElement by id
  public static WebElement FindElement(String id)
  {
      try
      {
            webElement= driver.findElement(By.id(id));
      }
      catch(Exception e)
      {
          Print(e);
      }
      return webElement;
  }

  //To find WebElement by name
  public static WebElement FindElementByName(String name)
  {
      try
      {
            webElement= driver.findElement(By.name(name));
      }
      catch(Exception e)
      {
          Print(e);
      }
       return webElement;
  }

  //To find WebElement by Class
  public static WebElement FindElementByClass(String classname)
  {
      try
      {
            webElement= driver.findElement(By.className(classname));
      }
      catch(Exception e)
      {
          Print(e);
      }
       return webElement;
  }

//To get data of a cell
public static String GetCellData(XSSFSheet sheet,int row,int col)
{
    String cellData = null;
    try 
    {
        cellData=PhyWebUtil.getValueFromExcel(row, col, sheet);
    }
    catch (Exception e) 
    {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return cellData;
}

    //To click a button using id
    public static void ClickButton(String id,String label)
    {
        try
        {
                WebElement webElement= FindElement(id);
                Snooze();
                webElement.click();
                PrintMessage(label+" is selected");
        }
        catch(Exception e)
        {
            Print(e);
        }
    }   

            //To click a button using class
            public void ClickButtonByClass(String classname,String label)
            {
                try
                {
                        WebElement webElement= FindElementByClass(classname);
                        Snooze();
                        webElement.click();
                        PrintMessage(label+" is selected");
                }
                catch(Exception e)
                {
                    Print(e);
                }
            }   
     //To enter data into Textbox
     public String editTextField(int rownum, int celnum,WebElement element ,XSSFSheet sheet,String Label)
      {
            XSSFRow row = sheet.getRow(rownum);
            XSSFCell Cell = row.getCell(celnum);
            String inputValue = Cell.getStringCellValue().trim();
            element.clear();//To clear contents if present
            try
            {
                      element.sendKeys(inputValue);
                      String  elementVal=element.toString();
                      if(elementVal.contains("password"))
                      {   
                          PrintMessage("Password is entered");
                      }
                      else
                      {   
                          PrintMessage("Value entered for "+Label+" is "+inputValue);
                      }  
            }
            catch(Exception e){
                Print(e);
                //cv.verifyTrue(false, "<font color= 'red'> Failed due to : </font> "+e.getMessage());
            }
            return inputValue;
      }

    //To enter data into Textbox
     public String editTextFieldDirect(WebElement element ,String text,String label)
      {
            element.clear();//To clear contents if present
            try
            {
                      element.sendKeys(text);
                      String  elementVal=element.toString();
                      if(elementVal.contains("password"))
                      {   
                          PrintMessage("Password is entered");
                      }
                      else
                      {   
                          PrintMessage("Value entered for "+label+" is "+text);
                      }  
            }
            catch(Exception e){
                Print(e);
                //cv.verifyTrue(false, "<font color= 'red'> Failed due to : </font> "+e.getMessage());
            }
            return text;
      }
        //To select Radio button
        public void ClickRadioButton(String id)
        {
            try
            {
                    WebElement webElement= FindElement(id);
                    Snooze();
                    webElement.click();                 
                    text=webElement.getText();          
                    PrintMessage(text+" is selected");
            }
            catch(Exception e)
            {
                Print(e);
            }
        } 

    //To select Link
    public void ClickLink(String id,String label)
    {
        try
        {
                ClickButton(id,label);
        }
        catch(Exception e)
        {
            Print(e);
        }
    } 

  //To Click an Image button
    public void ClickImage(String xpath)
    {
        try
        {
                WebElement webElement= FindElement(id);
                Snooze();
                webElement.click();
                text=GetText(webElement);
                PrintMessage(text+" is selected");
        }
        catch(Exception e)
        {
            Print(e);
        }
    } 

    //Select a checkbox
    public void CheckboxSelect(String id,String label)
    {
        try
        {
                WebElement webElement= FindElement(id);
                Snooze();
                webElement.click();
                PrintMessage("Checkbox "+label+" is selected");
        }
        catch(Exception e)
        {
            Print(e);
        }
    } 

    //To select value in Combobox
    public void SelectData(String id,String label,String cellval)
    {
        try
        {
                WebElement webElement= FindElement(id);
                Snooze();
                webElement.click();
                String elementStr=webElement.toString();
                int itemIndex=elementStr.indexOf("value");
                if(itemIndex>-1)
                {   
                    int endIndex=elementStr.length()-3;
                    String item=elementStr.substring(itemIndex+7, endIndex);
                    if(cellval=="0")
                    {   
                         PrintMessage(item+" is selected for "+label);
                    }
                    else
                    {
                        PrintMessage(cellval+"  "+label+" is selected");
                    }
                }   
                else
                {
                    PrintMessage(cellval+" is selected for "+label);
                }
        }
        catch(Exception e)
        {
            Print(e);
        }
    } 

      //To check if WebElement with id exists
      public static boolean isExists(String id) 
      {
          boolean exists = false;
          driver.manage().timeouts().implicitlyWait(0, TimeUnit.MILLISECONDS);
              try 
              {
                       exists=driver.findElements( By.id(id) ).size() != 0;    
              } 
              catch (Exception e) 
              {
                  Print(e);
             }
              if(exists==true)


               return true;


              else


               return false;
      }

      //To check if WebElement with name exists
      public static boolean isExistsName(String name) 
      {
          boolean exists = false;
          driver.manage().timeouts().implicitlyWait(0, TimeUnit.MILLISECONDS);
              try 
              {
                       exists=driver.findElements( By.name(name) ).size() != 0;    
              } 
              catch (Exception e) 
              {
                  if(e.getMessage().contains("InvalidSelectorError"))
                  {   
                      System.out.println("");
                  }
                  else
                      Print(e);
             }
              if(exists==true)


               return true;


              else


               return false;
      }

        //Explicit wait until a element is visible and enabled using id
        public void ExplicitlyWait(String id)
          {
              try
              {
                  WebElement myDynamicElement = (new WebDriverWait(driver, 10))
                            .until(ExpectedConditions.presenceOfElementLocated(By.id(id)));
              }
              catch(Exception e)
              {
                  Print(e);
              }
          }

        //Explicit wait until a element is visible and enabled using classname
        public void ExplicitlyWaitByClass(String classname)
          {
              try
              {
                  WebElement myDynamicElement = (new WebDriverWait(driver, 10))
                            .until(ExpectedConditions.presenceOfElementLocated(By.className(classname)));
              }
              catch(Exception e)
              {
                  Print(e);
              }
          }

        //Explicit wait until a element is visible and enabled using id
        public void ExplicitlyWaitSpecific(int sec,String id)
          {
              try
              {
                  WebElement myDynamicElement = (new WebDriverWait(driver, sec))
                            .until(ExpectedConditions.presenceOfElementLocated(By.id(id)));
              }
              catch(Exception e)
              {
                  Print(e);
              }
          }

    //Snooze for 10 seconds
    public static void Snooze()
      {
          try
          {
              driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
          }
          catch(Exception e)
          {
              Print(e);
          }
      }

    //Snooze for Secs
    public static void SnoozeSpecific(int seconds)
      {
          try
          {
              driver.manage().timeouts().implicitlyWait(seconds, TimeUnit.SECONDS);
          }
          catch(Exception e)
          {
              Print(e);
          }
      }

    //Sleep for milliSeconds
    public static void Sleep(int milisec) throws InterruptedException
    {
        Thread.sleep(milisec);
    }

    //To get text using text()
     public static String GetText(WebElement element)
     {
         try
         {  
             text=element.getText();
         }   
         catch(Exception e){


             Print(e);
         }
        return text;
     }

     //To get text using getAttribute("value")
     public static String GetTextAttribute(WebElement element)
     {
         try
         {  
             text=element.getAttribute("value");
         }   
         catch(Exception e){


             Print(e);
         }
        return text;
  }
     //To Print error messages to both Console and Results file
     public static void Print(Exception e)
     {
         Reporter.log("Exception is :"+e.getMessage());
         System.out.println(e);
     }

     //To Print messages to both Console and Results file
     public static void PrintMessage(String str)
     {
         Reporter.log(str);
         System.out.println(str);
     }

    //To Print Blank row
     public static void BlankRow()
     {
         Reporter.log("                                              ");
         System.out.println("                                              ");
     }

    //To Print Sub header
     public static void Header(String str)
     {
         BlankRow();
         Reporter.log("***********************"+str+" Verifications***********************");
         System.out.println("***********************"+str+" Verifications***********************");
         BlankRow();
     }

    //To Print Sub header
     public static void SubHeader(String str)
     {
         BlankRow();
         Reporter.log("-----------------------"+str+" Verifications-----------------------");
         System.out.println("-----------------------"+str+" Verifications-----------------------");
         BlankRow();
     }

【讨论】:

    【解决方案3】:

    只要您有一个用于启动框架的命令行并使用 xunit 日志格式进行报告,那么您应该能够很好地与任意数量的持续集成框架集成。

    您在负载下运行浏览器实例的权衡将是减少每台主机的虚拟用户数,并非常仔细地检查负载下的负载生成器资源。不要忘记在您的框架中包含监控 API,以监测负载下的系统指标和与 SLA 指标接受相关的自动评估引擎,以确定在给定负载点负载下的失败标准是否通过。

    【讨论】:

    • 谢谢詹姆斯。这很有用。
    【解决方案4】:

    我们正在开始开发与您的需求非常相关的东西; Java、Webdriver、Jenkins、Maven 等。我们对自动化还很陌生,但仍然有很好的 Java 资源。 我们正在构建基于来自 www.seleniumtests.com 的 Tarun Kumar 的框架。 他有很多来自 Youtube 的好视频(声音质量不太好),并且他设法使用 PageObjects Pattern 创建了一些非常用户友好的东西。 如果你不知道从哪里开始,我会从那里开始。 祝你好运!

    【讨论】:

      【解决方案5】:

      我在 selenium 之上创建了一个 java 库,它简化了网站的测试自动化。它具有隐式等待机制,易于使用:

      https://github.com/gartenkralle/web-ui-automation

      例子:

      import org.junit.Test;
      import org.openqa.selenium.By;
      
      import common.UserInterface;
      import common.TestBase;
      
      public class Google extends TestBase
      {
          private final static String GOOGLE_URL = "https://www.google.com/";
      
          private final static By SEARCH_FIELD = By.xpath("//input[@id='lst-ib']");
          private final static By AUTO_COMPLETION_LIST_BOX = By.xpath("//*[@id='sbtc']/div[2][not(contains(@style,'none'))]");
          private final static By SEARCH_BUTTON = By.xpath("//input[@name='btnK']");
      
          @Test
          public void weatherSearch()
          {
              UserInterface.Action.visitUrl(GOOGLE_URL);
              UserInterface.Action.fillField(SEARCH_FIELD, "weather");
              UserInterface.Verify.appeared(AUTO_COMPLETION_LIST_BOX);
              UserInterface.Action.pressEscape();
              UserInterface.Action.clickElement(SEARCH_BUTTON);
          }
      }
      

      【讨论】:

        【解决方案6】:

        Selenium WebDriver 无疑是一种 UI 自动化工具,我们广泛使用它在 Browser Stack 等云解决方案上进行跨浏览器测试。

        我们的用例让我们使用 TestNG 作为测试运行器构建了一个用 Java 构建的开源框架“omelet”,它负责几乎所有与网络测试相关的事情并让我们真正实现自动化应用程序,而不是考虑报告、并行运行和 CI 集成等。

        建议,总是欢迎贡献:)

        here 的文档和 Github链接超过here

        记得在网站上查看 5 分钟教程

        【讨论】:

          【解决方案7】:

          对于功能回归测试:

          Selenium Webdriver - Selenium 是一个基于 Web 的自动化工具,它可以自动化网页上的所有内容。您将 Selenium Webdriver 与 JAVA 一起使用。

          Watij- Java 中的 Web 应用程序测试 通过真实的 Web 浏览器自动执行 Web 应用程序的功能测试。

          TestProject - 它支持测试网络和移动(Android 和 iOS)。

          对于非功能测试:

          Gatling- 用于性能测试和压力测试

          Apache JMeter - 用于容量、性能、负载和压力测试

          CI 工具:

          Jenkins- Jenkins 为软件开发提供持续集成服务。

          【讨论】:

            【解决方案8】:

            对于功能回归测试:

            TestProject
            Selenium
            Cucumber :这是一个 BDD 工具

            对于非功能性:性能和负载测试:

            JMeter

            注意: TestComplete 是一个非常好的商业工具。

            【讨论】: