Selenium selenium 入门学习 (二)

顺流而下 · 2017年07月26日 · 最后由 顺流而下 回复于 2017年07月27日 · 1615 次阅读

前文链接:

一个百度登陆的 UI 实现:

import java.io.File;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
public class SeleniumTest {
    public static void main(String[] args) throws IOException {
        String driverPath = new File("./").getCanonicalPath() + "/src/main/resources/driver/chromedriver.exe";
        System.setProperty("webdriver.chrome.driver", driverPath);
        WebDriver webDriver = new ChromeDriver();
        webDriver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
        webDriver.get("https://www.baidu.com/");
        webDriver.manage().window().maximize();
        //点击登陆按钮
        webDriver.findElement(By.xpath("//*[@id='u1']/a[7]")).click();
        webDriver.findElement(By.id("TANGRAM__PSP_10__userName")).sendKeys("用户名称");
        webDriver.findElement(By.id("TANGRAM__PSP_10__password")).sendKeys("用户密码");
        webDriver.findElement(By.id("TANGRAM__PSP_10__verifyCode")).sendKeys("验证码");
        webDriver.findElement(By.id("TANGRAM__PSP_10__submit")).click();
        //在登录后界面查找用户名是否存在,获得用户名
        String username = webDriver.findElement(By.id("user-name")).getText();
        //判断是否一致,设置断言
        if (username.contains("用户名称")) {
            System.out.print(true);
        } else {
            System.out.print(false);
        }
        webDriver.close();
    }
}

码中存在的问题:

  • 测试类存在参数化问题:用户名,密码,验证码,定位的 Xpath 路径等;
  • 测试类只能使用一次,如果需要执行一些异常用例就需要重写;
  • 测试类对测试结果的判断,断言很难在执行后进行提取;
  • 测试类中存在一些异常场景没有进行考虑;

针对上述问题引入 testng 测试框架:

Eclipse 安装 testng 在网上有很多内容,这里就不叙述;安装完成 testng 后,在 maven 的 pom.xml 文件引入 testng 包:

<dependency>
        <groupId>org.testng</groupId>
        <artifactId>testng</artifactId>
        <version>6.9.10</version>
 </dependency>

testng 包引入完成后,新建一个 class 文件,如下图 在输入 @Test后,通过ATL+ /显示出下图,选择 Testng 的注解;

下面代码就是一个 Testng 框架的测试代码基础:

import org.testng.annotations.Test;
public class SeleniumTest1 {
    @Test
    public void test() {
    }
}

将百度 UI 实现 webDriver 代码放入到 testng 中:

import java.io.File;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.annotations.Test;
public class SeleniumTest1 {
    @Test
    public void test() throws IOException {
        // 通过查找当前路径返回一个规范化路径,这样可以把工程放到不同地方执行了
        String driverPath = new File("./").getCanonicalPath() + "/src/main/resources/driver/chromedriver.exe";
        System.setProperty("webdriver.chrome.driver", driverPath);
        WebDriver webDriver = new ChromeDriver();
        webDriver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
        webDriver.get("https://www.baidu.com/");
        webDriver.manage().window().maximize();
        webDriver.findElement(By.xpath("//*[@id='u1']/a[7]")).click();
        webDriver.findElement(By.id("TANGRAM__PSP_10__userName")).sendKeys("username");
        webDriver.findElement(By.id("TANGRAM__PSP_10__password")).sendKeys("password");
        webDriver.findElement(By.id("TANGRAM__PSP_10__verifyCode")).sendKeys("验证码");
        webDriver.findElement(By.id("TANGRAM__PSP_10__submit")).click();
        String username = webDriver.findElement(By.id("user-name")).getText();
        if (username.contains("username")) {
            System.out.print(true);
        } else {
            System.out.print(false);
        }
        webDriver.close();
    }
}
  • 优化一:代码结构:将测试业务代码和 webdriver 配置代码分离
import java.io.File;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
public class SeleniumTest1 {
    WebDriver webDriver;

    @BeforeMethod
    public void beforMethod() throws IOException {
        // 业务无关,启动配置相关代码
        String driverPath = new File("./").getCanonicalPath() + "/src/main/resources/driver/chromedriver.exe";
        System.setProperty("webdriver.chrome.driver", driverPath);
        webDriver = new ChromeDriver();
        webDriver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
    }

    @Test
    public void test() {
        webDriver.get("https://www.baidu.com/");
        webDriver.manage().window().maximize();
        webDriver.findElement(By.xpath("//*[@id='u1']/a[7]")).click();
        webDriver.findElement(By.id("TANGRAM__PSP_10__userName")).sendKeys("username");
        webDriver.findElement(By.id("TANGRAM__PSP_10__password")).sendKeys("password");
        webDriver.findElement(By.id("TANGRAM__PSP_10__verifyCode")).sendKeys("验证码");
        webDriver.findElement(By.id("TANGRAM__PSP_10__submit")).click();
        String username = webDriver.findElement(By.id("user-name")).getText();
        if (username.contains("username")) {
            System.out.print(true);
        } else {
            System.out.print(false);
        }
    }

    @AfterMethod
    public void afterMethod() {
        // 业务无关代码
        webDriver.quit();
    }
}
共收到 6 条回复 时间 点赞
白纸 回复

@BeforeMethod是每次执行 test 方法之前,在 UI 测试中感觉每个用例都要重新的打开一个 webdriver,这样可以保证每个用例之间没有影响。不知道这样对不对

之前在项目做 UI 自动化测试的时候是 selenium+python,用的是 unittest 框架,感觉结构差不多,setUp 初始化,然后是业务代码,最后是 tearDown 还原;只是有一个不一样,在这段代码中,webdriver 在什么时候启动浏览器的?我通常在业务代码里面启动浏览器,然后获取 URL。不是很了解 Java,你这段貌似是在初始化阶段启动浏览器的。

YangClyde 回复

是在业务之前创建 webdriver 的,放在了@BeforeMethod里面执行;我的想法是启动 webdriver 过程不依赖于业务执行,所以就放到了执行测试方法之前;

是否考虑过把这些部分 用 selnium 的 pagefactory 封装呢?
这些 element 的可读性需要搞一搞吧

webDriver.findElement(By.xpath("//*[@id='u1']/a[7]")).click();
webDriver.findElement(By.id("TANGRAM_PSP_10userName")).sendKeys("username");
webDriver.findElement(By.id("TANGRAM
PSP_10password")).sendKeys("password");
webDriver.findElement(By.id("TANGRAM
PSP_10verifyCode")).sendKeys("验证码");
webDriver.findElement(By.id("TANGRAM
PSP_10_submit")).click();
String username = webDriver.findElement(By.id("user-name")).getText();

韩将 回复

是的,一步步写下去的;后面会有逐步的细化;谢谢建议哈

顺流而下 selenium 入门学习 (三) 中提及了此贴 07月27日 15:44
顺流而下 selenium 入门学习 (四) 中提及了此贴 08月07日 16:06
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册