1. Selenium
1.1 Selenium是什么?
用来做web自动化测试的框架。
1.2 Selenium特点
支持各种浏览器,支持各种平台,支持各种语言,有丰富的API,
1.3 工作原理
1.4 Selenium环境搭建
-
下载配套浏览器及驱动
这里使用Chrome浏览器演示:Chrome113 & ChromeDriver。(建议安装到同一目录下,方便管理) -
创建一个Maven项目
3. 添加Selenium依赖
<!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java -->
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>4.7.2</version>
</dependency>
4. 在Java包下新建一个类
5. 添加如下代码:
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
public class Main {
public static void main(String[] args) {
ChromeOptions options = new ChromeOptions();
// 允许所有的请求
options.addArguments("--remote-allow-origins=*");
WebDriver webDriver = new ChromeDriver(options);
// 打开百度首页
webDriver.get("https://www.baidu.com");
}
}
- 启动运行代码。接下来会自动打开Chrome浏览器并进入百度首页。
- 到此为止即可视为Selenium环境已经搭建好了。下面的暂时先不管
1.5 Selenium API 详解
1.5.1 元素的定位
- CSS定位(效率比XPath高)
定位元素findElement。
CSS选择语法:
id选择器:#id
类选择器:.class
标签选择器: 标签名
后代选择器:父级选择器,子级选择器
- XPath定位
1.5.2 操作测试对象
click:点击测试对象
send_keys:在对象上模拟按键输入
代码示例:
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import java.util.List;
import static java.lang.Thread.sleep;
public class Main {
public static void main(String[] args) throws InterruptedException {
ChromeOptions options = new ChromeOptions();
options.addArguments("--remote-allow-origins=*");
WebDriver webDriver = new ChromeDriver(options);
// 打开百度首页
webDriver.get("https://www.baidu.com");
// 找到百度输入框
// CSS
// webDriver.findElement(By.cssSelector('.bg s_ipt_wr new-pmd quickdelete-wrap'));
// XPath
WebElement element = webDriver.findElement(By.xpath("//*[@id=\"kw\"]"));
// 输入软件测试
element.sendKeys("软件测试");
// 找到“百度一下”按钮
// 点击
webDriver.findElement(By.cssSelector("#su")).click();
sleep(3000);
// 校验
// 找到搜索结果
List<WebElement> elements = webDriver.findElements(By.cssSelector("a em"));
for (int i = 0; i < elements.size(); i++) {
System.out.println(elements.get(i).getText());
// 如果返回的结果都有软件测试,则证明测试通过,否则不通过
if (!elements.equals("软件测试")) {
System.out.println("测试不通过");
}else {
System.out.println("测试不通过");
}
}
}
}
clear:清除对象输入的文本内容
public static void test3() throws InterruptedException {
ChromeOptions options = new ChromeOptions();
options.addArguments("--remote-allow-origins=*");
WebDriver webDriver = new ChromeDriver(options);
webDriver.get("https://www.baidu.com");
// 找到输入框,输入内容
webDriver.findElement(By.cssSelector("#kw")).sendKeys("内容");
// 点击搜索
webDriver.findElement(By.cssSelector("#su")).click();
sleep(3000);
//清空输入框
webDriver.findElement(By.cssSelector("#kw")).clear();
}
submit:提交,如果点击的元素放在form标签中,此时使用submit实现的效果和click是一样的,如果点击的元素放在非form标签中,此时使用submit报错。
示例:submit()
public static void test4() {
ChromeOptions options = new ChromeOptions();
options.addArguments("--remote-allow-origins=*");
WebDriver webDriver = new ChromeDriver(options);
webDriver.get("https://www.baidu.com");
webDriver.findElement(By.xpath("//*[@id=\"s-top-left\"]/a[1]")).submit();
}
示例:click()
public static void test4() {
ChromeOptions options = new ChromeOptions();
options.addArguments("--remote-allow-origins=*");
WebDriver webDriver = new ChromeDriver(options);
webDriver.get("https://www.baidu.com");
webDriver.findElement(By.xpath("//*[@id=\"s-top-left\"]/a[1]")).click();
}
text:用于获取元素的文本信息
getAttribute():获取属性值
public static void test5() {
ChromeOptions options = new ChromeOptions();
options.addArguments("--remote-allow-origins=*");
WebDriver webDriver = new ChromeDriver(options);
webDriver.get("https://www.baidu.com");
String butten_value = webDriver.findElement(By.cssSelector("#su")).getAttribute("value");
// WebElement element = webDriver.findElement(By.cssSelector("#su"));
// String butten_value = element.getAttribute("value");
System.out.println(butten_value);
}
1.5.3 等待
如果等待3天时间,强制等待一直等待,等待三天时间。
隐式等待最长等待三天时间,如果在三天时间内获取到页面上的元素,此时执行下面代码,如果等待三天时间还是没有找到这个元素,此时报错
-
sleep强制等待
-
智能等待
- 隐式等待
- 显式等待
1.5.4 浏览器的操作
- 浏览器前进
- 浏览器后退
- 浏览器刷新
public static void test7() throws InterruptedException {
ChromeOptions options = new ChromeOptions();
options.addArguments("--remote-allow-origins=*");
WebDriver webDriver = new ChromeDriver(options);
webDriver.get("https://www.baidu.com");
webDriver.findElement(By.cssSelector("#kw")).sendKeys("319");
webDriver.findElement(By.cssSelector("#su")).click();
// 浏览器后退
webDriver.navigate().back();
sleep(3000);
// 浏览器刷新
webDriver.navigate().refresh();
sleep(3000);
// 浏览器前进
webDriver.navigate().forward();
sleep(3000);
}
- 浏览器滚动条操作
public static void test7() throws InterruptedException {
ChromeOptions options = new ChromeOptions();
options.addArguments("--remote-allow-origins=*");
WebDriver webDriver = new ChromeDriver(options);
webDriver.get("https://www.baidu.com");
webDriver.findElement(By.cssSelector("#kw")).sendKeys("319");
webDriver.findElement(By.cssSelector("#su")).click();
sleep(3000);
// 将webDriver强制转换JavascriptExecutor类型,执行JS代码
((JavascriptExecutor)webDriver).executeScript("document.documentElement.scrollTop=10000");
// 窗口最大化
webDriver.manage().window().maximize();
sleep(3000);
// 全屏展示
webDriver.manage().window().fullscreen();
sleep(3000);
// 设置窗口大小
webDriver.manage().window().setSize(new Dimension(800, 1000));
}
1.5.5 键盘操作
public static void test8() throws InterruptedException {
ChromeOptions options = new ChromeOptions();
options.addArguments("--remote-allow-origins=*");
WebDriver webDriver = new ChromeDriver(options);
webDriver.get("https://www.baidu.com");
webDriver.findElement(By.cssSelector("#kw")).sendKeys("123");
sleep(2000);
// CRL + A
webDriver.findElement(By.cssSelector("#kw")).sendKeys(Keys.CONTROL, "a");
sleep(2000);
// CRL + X
webDriver.findElement(By.cssSelector("#kw")).sendKeys(Keys.CONTROL, "x");
sleep(2000);
// CRL + V
webDriver.findElement(By.cssSelector("#kw")).sendKeys(Keys.CONTROL, "v");
}
1.5.6 打印信息
示例:
public static void test6() {
ChromeOptions options = new ChromeOptions();
options.addArguments("--remote-allow-origins=*");
WebDriver webDriver = new ChromeDriver(options);
webDriver.get("https://www.baidu.com");
String url = webDriver.getCurrentUrl();
String title = webDriver.getTitle();
if (title.equals("百度一下,你就知道") && url.equals("https://www.baidu.com/")){
System.out.println("测试通过");
}else {
System.out.println("测试失败");
System.out.println(title);
System.out.println(url);
}
}
1.5.7 鼠标操作
public static void test9() throws InterruptedException {
ChromeOptions options = new ChromeOptions();
options.addArguments("--remote-allow-origins=*");
WebDriver webDriver = new ChromeDriver(options);
webDriver.get("https://www.baidu.com");
webDriver.findElement(By.cssSelector("#kw")).sendKeys("selenium");
webDriver.findElement(By.cssSelector("#su")).click();
sleep(3000);
// 找到图片按钮
WebElement webElement = webDriver.findElement(By.cssSelector("#s_tab > div > a.s-tab-item.s-tab-item_1CwH-.s-tab-pic_p4Uej.s-tab-pic"));
// 鼠标右击
Actions actions = new Actions(webDriver);
sleep(1000);
actions.contextClick(webElement).perform();
sleep(1000);
}
1.5.8 定位一组元素
public static void test10() {
ChromeOptions options = new ChromeOptions();
options.addArguments("--remote-allow-origins=*");
WebDriver webDriver = new ChromeDriver(options);
webDriver.get("xxxxxxxxxxxxxxxxxxxxxxxxxx");
webDriver.manage().timeouts().implicitlyWait(3,TimeUnit.DAYS);
List<WebElement> webElements = webDriver.findElements(By.cssSelector("input"));
for (int i = 0;i < webElements.size(); i++) {
// 如果每个元素type值等于checkbox进行点击
// getAttribute("type") 获取元素的type属性值
if (webElements.get(i).getAttribute("type").equals("checkbox")) {
webElements.clear();
}else {
}
}
}
1.5.9 定位frame标签内的元素
1.5.10 定位下拉框中的选项
1.5.11 上传文件
1.5.12 关闭浏览器
- quit关闭了整个浏览器,清空缓存
- close只关闭了页面,不清空缓存
2. 单元测试
注解:
- @Test
- @Disabled
- @AfterAll
- @BeforeEach
- @BeforeAll
- @AfterEach
-
参数化:
-
引入parameterized依赖
- 单参数:@ValueSource()
@ParameterizedTest @ValueSource(ints = {1,2,3}) void Test(int num) { System.out.println(num); }
@ParameterizedTest @ValueSource(strings = {"1","2", "3"}) void Test2(String str) { System.out.println(str); }
- 多参数
- CSV获取参数
@ParameterizedTest @CsvFileSource(resources = {"test1.csv"}) void Test3(String name) { System.out.println(name); }
- 方法获取参数
public static Stream<Arguments> Generator() { return Stream.of(Arguments.arguments(1,"张三"), Arguments.arguments(2,"李四"), Arguments.arguments(3,"王五") ); } @ParameterizedTest @MethodSource("Generator") void Test4(int num,String str) { System.out.println(num+","+str); }
-
-
测试套件
- 通过class运行测试用例
- 通过包运行测试用例
1.1 配置测试用例执行顺序
示例:设置顺序
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.TestMethodOrder;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class Order {
@ParameterizedTest
@ValueSource(ints = {1,2,3})
@org.junit.jupiter.api.Order(2)
void Test1(int num) {
System.out.println("Test1");
System.out.print(num);
}
@ParameterizedTest
@ValueSource(strings = {"1","2", "3"})
@org.junit.jupiter.api.Order(1)
void Test2(String str) {
System.out.println("Test2");
System.out.print(str);
}
}
示例:随即执行
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
@TestMethodOrder(MethodOrderer.Random.class)
public class Order {
@Test
void Test1() {
System.out.println("Test1");
}
@Test
void Test2() {
System.out.println("Test2");
}
}
1.2 断言
- 断言相等
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
public class AssertTest {
@ParameterizedTest
@ValueSource(ints = {1})
void Test (int num){
System.out.println(num);
// 判断 num == 1 ?
Assertions.assertEquals(num,1);
}
}
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
public class AssertTest {
@ParameterizedTest
@ValueSource(ints = {1})
void Test (int num){
System.out.println(num);
// 判断 num == 1 ?
Assertions.assertEquals(num,2);
}
}
2. 断言不相等
1.3 Suite
- 指定Class
import org.junit.platform.suite.api.SelectClasses;
import org.junit.platform.suite.api.Suite;
@Suite
@SelectClasses({AssertTest.class,Main.class,Order.class})
// 依次执行 AssertTest.class、Main.class、Order.class 三个类中的测试方法
public class RunSuite {
}
2. 指定package