java - JUnit/ Selenium : Splitting my class to use the Page Object Model

标签 java selenium selenium-webdriver junit

意识到这可能是一个有点大的要求,但我在拆分测试类以使用页面对象模型时遇到了麻烦。

我当前的类(class)基本上是这样工作的:

  1. @BeforeClass - startUp() 加载变量的属性文件并启动 ChromeDriverService
  2. @Before - createDriver() 打开 Chrome 浏览器,并导航至主页
  3. @Test - desktopHappyCallback() 进行一些页面交互,然后调用:
  4. hideDynamicElements() 隐藏页面上的一些元素
  5. runScreenshotValidation() 保存屏幕截图并通过调用进行比较:
  6. compareScreen() 比较并返回真/假
  7. @After - tearDown() 退出 ChromeDriver
  8. @AfterClass - stopService() 终止 ChromeDriverService

该类当前(已从方法中删除一些部分以使其更短):

public class desktopHappy {

private static ChromeDriverService service;
private static WebDriver driver;
private static Properties obj = new Properties();

//Set up screenshot comparison via im4java
private static boolean compareScreen(String expectedImage, String currentImage, String diffImage) {
    CompareCmd compare = new CompareCmd();
    compare.setErrorConsumer(StandardStream.STDERR);
    IMOperation comparisonExe = new IMOperation();
    comparisonExe.metric("mae"); //mae = Mean Absolute error (average of all the color differences)
    comparisonExe.addImage(currentImage);
}

//Compare via ImageMajick
private void runScreenshotValidation() throws IOException, InfoException {
    String current = "screenshots\\current\\Current.png";
    boolean compareSuccess = compareScreen(baseline, current, difference); //Run the compare method
    }
}

//Hide dynamic elements on the page (if they exist)
private void hideDynamicElements() throws IOException, InterruptedException {
    List<By> criteria = Arrays.asList(
            By.className("telephone-number"),
            By.cssSelector("#chatContainer"),
    );
    for (By dynamicElement : criteria) { //Loop through the criteria
        List<WebElement> elements = driver.findElements(dynamicElement);
        for (WebElement hideElement : elements){ //Loop through each instance of an element
            ((JavascriptExecutor) driver).executeScript("arguments[0].style.visibility='hidden'", hideElement);
    }
}

@BeforeClass //Pulls in Properties, and starts up the ChromeDriverService before the Tests run
public static void startUp() throws IOException {
    FileInputStream propfile = new FileInputStream(System.getProperty
            ("user.dir") + "\\src\\main\\resources\\config.properties");
    obj.load(propfile);

    service = new ChromeDriverService.Builder()
            .usingDriverExecutable(new File(obj.getProperty("chromeDriverLoc"))) //Driver set in properties
            .usingAnyFreePort()
            .build();
    service.start();
}

@Before //Starts up the Chrome browser (on home page) before each Test
public void createDriver() {
    driver = new RemoteWebDriver(service.getUrl(), DesiredCapabilities.chrome());
    driver.get(obj.getProperty("targetENV")); //Opens home page (set in properties)
}

@Test //Checks the Callback form (modal)
public void desktopHappyCallback() throws Exception {
    driver.findElement(By.cssSelector("#callbackInputPhone")).sendKeys(obj.getProperty("formsPhone"));
    driver.findElement(By.xpath("//input[@value='Request a callback']")).click();
    WebDriverWait waitForSuccessMessage = new WebDriverWait(driver, 5);
    waitForSuccessMessage.until(ExpectedConditions.elementToBeClickable
            (By.cssSelector("#callbackForm > div.success-message")));

    hideDynamicElements(); //Run the hide dynamic elements method
    runScreenshotValidation(); //Run the screenshot comparison method
}

@After //Quits the ChromeDriver after each Test
public void tearDown() throws Exception {
    driver.quit();
}

@AfterClass //Kills the ChromeDriverService at end of Tests
public static void stopService() {
    service.stop();
}}

因此,在 IntelliJ 中,我尝试将我的项目与包分开,如下所示:

structure

我一直在尝试进入 baseCompare 类:

  • 隐藏动态元素()
  • 比较屏幕()
  • runScreenshotValidation()

然后进入baseSetup类:

  • startUp()
  • createDriver()
  • tearDown()
  • 停止服务()

然后 homePage 将包含我的表示,desktopHappy 将包含我的测试断言。

但是,我真的陷入了如何将事物分开以便它们一起工作的困境。有谁能给我一个关于如何在这些包下分割东西的例子吗? (抱歉问得太大了!)

最佳答案

我认为你的逻辑划分非常公平。

我唯一要改变的就是将您的 base* 类放在您的基础包下,而不是实际的物理 base 包下。

例如:

com.salessite/
  baseCompare.java
  baseSetup.java
  basePage.java
  baseTest.java
  pages/
    homePage.java < basePage.java
  tests/
    desktopHappy.java < baseTest.java

此外,通过创建更多基础,您可以为自己的 future 变化提供更多余地。

so that they work together

如果你所说的工作是编译,那么你应该没有问题。例如,homePage.java 扩展了 basePage.java,那么在 homePage.java 中,您将拥有适当的导入。

导入 com.salessite.basePage;

导入是如何访问外部类和引用。 (当然,访问修饰符允许。)

关于java - JUnit/ Selenium : Splitting my class to use the Page Object Model,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37486154/

相关文章:

java - Selenium Json和xml从Url读取,get方法用java打开它

java - onClick() 更改图像

java - volatile 的发生之前和重新排序

java - Android Studio 闹钟 MP3 歌曲

selenium - Selenium 的两种不同语法结构

java - org.testng.internal.reflect.MethodMatcherException : Data provider mismatch

java - 扩展阅读器,如何返回我的 "read"?

python - selenium python 向下翻页 - 未知错误:net::ERR_NAME_NOT_RESOLVED

python - 如何处理SessionNotCreatedException : Message: session not created exception from disconnected: Unable to receive message from renderer?

java - 当我们只有元素的标题时,如何获取某个列表元素的属性?