java - Selenium - 多浏览器和多用户登录

标签 java selenium testng

我们正在尝试开始在我们基于交易的网站上实现回归测试的自动化。我成功设置了 testng xml 以打开 Firefox、IE 和 Chrome。并且它将运行事务类。在带有参数的 setUP 方法中,它检查浏览器并为该线程打开正确的浏览器。然后它被定向到 main() 方法测试,该方法启动 Login 类,然后返回事务类实际进行事务测试。这样做的原因是有一个有组织的结构,每个类中只有一个测试用于调试目的。

当我使用单个用户凭据运行此测试时,它运行良好并完成了这两个测试。问题是我们的系统允许用户每 10 秒输入一次交易(这只是我们的安全功能之一,以避免刷新或多次交易提交)。无论如何,使用多个用户凭据的最佳方法是什么?我尝试了多种逻辑,但每次 Firefox 都会使用 Username1,而 IE 和 Chrome 都会使用 Username 2 或 3。

换句话说

  • Firefox = 用户名1
  • Chrome = 用户名2
  • IE = 用户名2

  • Firefox = 用户名1
  • Chrome = 用户名3
  • IE = 用户名3

我想出了几个成功的解决方案,但我必须复制类或代码。

因此,一种解决方案是为每个浏览器创建单独的登录类,并为每个浏览器创建单独的事务类。在 testng 中,我为每个浏览器运行了正确的类。我认为这是一个糟糕的解决方案,尽管它有效。

我提出的另一个解决方案是采用登录测试方法,并在检查每个浏览器时将其放入 Transaction 类的参数方法中的每个 if() 语句中。然后每个 if 语句都有其正确的用户名。

但我也不喜欢这个解决方案,因为如果我运行单个测试来检查正在开发的函数的新代码,我必须将相同的代码添加到我将创建的所有 future 测试类中。它只是重复的代码,我认为应该在它自己的类中。

这是转换为 testng 之前的 Login 和 Transaction 类。另外,我还创建了一个环境类,其中包含用户名和 url 等静态变量。

附注我删除了一堆这个问题不需要的测试代码。

例如:

static {
            URL = "https://website.com";
            DEFAULT_WAIT_TIME = 60;
            SYSTEM_ID = "IDnumber";
            USERNAME = "Username1";
            PASSWORD = "Password1";
    }
<小时/>
import static org.junit.Assert.fail;

import java.util.concurrent.TimeUnit;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

public class Login {
    private WebDriver driver;
    private String baseURL;
    private StringBuffer verificationErrors = new StringBuffer();

        @Before
        public void setUp() throws Exception {
            //driver = new FirefoxDriver();
            //baseURL = Environment.URL;
            driver.manage().timeouts().implicitlyWait(Environment.DEFAULT_WAIT_TIME, TimeUnit.SECONDS);
        }

        public static void doLogin(WebDriver driver, String baseURL) {
            WebDriverWait wait = new WebDriverWait(driver, Environment.DEFAULT_WAIT_TIME);
            System.out.println("Log in to trunk...");
            driver.get(baseURL);

            wait.until(ExpectedConditions.presenceOfElementLocated(By.id("company_id")));
            if (driver.findElement(By.xpath("//div[span='Log In']/span")).isEnabled()) {
                System.out.println("    1 - 'Login' page is opened");
            }   else {
                    System.out.println("    !ERROR! - Can NOT open 'Login' page");
                    driver.findElement(By.id("This is to throw exception if Can NOT open 'Login' page"));
                }
            driver.findElement(By.id("company_id")).clear();
            driver.findElement(By.id("company_id")).sendKeys(Environment.SYSTEM_ID);
            driver.findElement(By.xpath("//input[@name='username']")).clear();
            driver.findElement(By.xpath("//input[@name='username']")).sendKeys(Environment.USERNAME);
            driver.findElement(By.id("c_password")).clear();
            driver.findElement(By.id("c_password")).sendKeys(Environment.PASSWORD);
            System.out.println("    2 - Info filled");

            //I removed the rest of the code that finishes the login because          
            //I don't think it is needed for demonstration

        }

        @Test
        public void main() {
            doLogin(driver, baseURL);
        }

        @After
        public void tearDown() throws Exception {
                driver.quit();
                    String verificationErrorString = verificationErrors.toString();
                        if (!"".equals(verificationErrorString)) {
                        fail(verificationErrorString);
                        }
        }
}
<小时/>
import static org.junit.Assert.fail;

import java.util.concurrent.TimeUnit;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.Select;
import org.openqa.selenium.support.ui.WebDriverWait;

public class Transaction {
    private WebDriver driver;
    private String baseURL;
    private StringBuffer verificationErrors = new StringBuffer();

    public static String country = "22";
    public static String ammount = "500";

        @Before
        public void setUp() throws Exception {
//          System.setProperty("webdriver.ie.driver", "../IEDriverServer.exe");
//          driver = new InternetExplorerDriver();
            driver = new FirefoxDriver();
            baseURL = Environment.URL;

            driver.manage().timeouts().implicitlyWait(Environment.DEFAULT_WAIT_TIME, TimeUnit.SECONDS);
        }

        public static void doTransaction(WebDriver driver) {
            WebDriverWait wait = new WebDriverWait(driver, Environment.DEFAULT_WAIT_TIME);
            System.out.println("Performing transaction...");


        // This is where the transaction code is ......

        }

        @Test
        public void transaction() {
        //Login first   
            Login.doLogin(driver, baseURL);

        // Transaction  
            doTransaction(driver);
        }

        @After
        public void tearDown() throws Exception {
                driver.quit();
                    String verificationErrorString = verificationErrors.toString();
                        if (!"".equals(verificationErrorString)) {
                        fail(verificationErrorString);
                        }
        }
}

最佳答案

您的示例代码是 JUnit,但您提到您正在使用 TestNG。在这种情况下,您可以使用 @Parameters 将不同的参数传递给您的测试。文件:http://testng.org/doc/documentation-main.html#parameters

示例:

testng.xml

<suite>
    <test name="firstTest">
        <parameter name="username" value="username1"/>
        <parameter name="password" value="password1"/>
        ....
    </test>
        <test name="secondTest">
        <parameter name="username" value="username2"/>
        <parameter name="password" value="password2"/>
        ....
    </test>
</suite>

你的类(class):

  @Parameters({"username", "password"})
  @BeforeTest
  public void beforeTest(String username, String password) {
    this.getDriver().get("http://mypage.com");
    this.getDriver().findElement(By.id("usernameInputField")).sendKeys(username);
    this.getDriver().findElement(By.id("passwordInputField")).sendKeys(password);
    ...
  }

关于java - Selenium - 多浏览器和多用户登录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29264755/

相关文章:

java - testng 运行多线程吗?

java - 使用已插入的一些字段打开 Android 的联系人 Activity

java - 如何在控制台中显示从文件读取的方法?

selenium - 使用 Protractor 配置以 headless 模式运行 Firefox

java - 是否可以在计算机锁定时以编程方式截取屏幕截图?

java - TestNG 未在 eclipse 上运行测试

java - 为什么@BeforeSuite和@AfterSuite在单独的线程中运行?

java - ETL架构

java - 通过 Android 按钮发送 HTTP-POST 请求

Selenium - 如何在 WebDriver 中通过 href 值单击链接