我们主要学习的是 Junit5.
1. selenium 和 Junit 之间的关系
selenium 和 Junit 之间的关系 就像 Java 和 JavaScript 之间的关系,也就是没有关系。
为什么学习了 selenium 还要学习 Junit 呢?
举个例子,如果 Selenium 编写的自动化测试用例是灯,Junit 则是控制灯如何让去亮等。
通过 Junit 来管理测试用例。
2. 常用的注解
2.1 添加依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>org.example</groupId><artifactId>TestCode</artifactId><version>1.0-SNAPSHOT</version><dependencies><dependency><groupId>org.seleniumhq.selenium</groupId><artifactId>selenium-java</artifactId><version>3.141.59</version></dependency><!-- https://mvnrepository.com/artifact/commons-io/commons-io --><dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.4</version></dependency><dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter-api</artifactId><version>5.9.2</version></dependency><dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter-params</artifactId><version>5.9.2</version></dependency><dependency><groupId>org.junit.platform</groupId><artifactId>junit-platform-suite</artifactId><version>1.9.1</version><scope>test</scope></dependency><dependency><groupId>org.junit.platform</groupId><artifactId>junit-platform-suite</artifactId><version>1.9.1</version></dependency><dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter-engine</artifactId><version>5.9.1</version><scope>test</scope></dependency></dependencies><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target></properties></project>
2.2 @Test
public class JunitTest {@Test// @Test 表明当前的方法是一个测试用例void test01(){WebDriver webDriver = new ChromeDriver();webDriver.get("https://www.baidu.com/");}
}
@Testvoid test02(){System.out.println("这是第二个测试用例");}
2.3 @BeforeAll @AfterAll
@BeforeAll// 当前所有的测试用例执行之前执行这个方法static void setUp(){System.out.println("开始执行 @BeforeAll 修饰的方法");}@AfterAll// 当前所有的测试用例执行之后执行这个方法static void tearDown(){System.out.println("开始执行 @AfterAll 修饰的方法");}
2.4 @BeforeEach @AfterEach
@BeforeEach// 当前每个测试用例执行之前执行这个方法void boforeTest(){System.out.println("开始执行 @BeforeEach 修饰的方法");}@AfterEach// 当前每个测试用例执行之后执行这个方法void afterTest(){System.out.println("开始执行 @AfterEach 修饰的方法");}
2.5 @Disabled
@Disabled// 忽略当前测试用例(当前这个测试用例不执行)@Test// @Test 表明当前的方法是一个测试用例void test01(){WebDriver webDriver = new ChromeDriver();webDriver.get("https://www.baidu.com/");}@Testvoid test02(){System.out.println("这是第二个测试用例");}
3. Junit 测试用例的执行顺序
是从上到下执行测试用例吗?
我们先来看以下的测试用例的执行情况:
public class JunitTest {@Disabled// 忽略当前测试用例(当前这个测试用例不执行)@Test// @Test 表明当前的方法是一个测试用例void test01(){WebDriver webDriver = new ChromeDriver();webDriver.get("https://www.baidu.com/");}@Testvoid test02(){System.out.println("这是第2个测试用例");}@Testvoid test03(){System.out.println("这是第3个测试用例");}@Testvoid test04(){System.out.println("这是第4个测试用例");}
}
可以看到确实是从上往下执行的,那么此时我们改变一下测试用例的顺序:
public class JunitTest {@Testvoid test04(){System.out.println("这是第4个测试用例");}@Disabled// 忽略当前测试用例(当前这个测试用例不执行)@Test// @Test 表明当前的方法是一个测试用例void test01(){WebDriver webDriver = new ChromeDriver();webDriver.get("https://www.baidu.com/");}@Testvoid test02(){System.out.println("这是第2个测试用例");}@Testvoid test03(){System.out.println("这是第3个测试用例");}
}
可以看到依旧是从上往下执行的。
那么,我们如何根据指定的顺序来执行测试用例呢?
// 根据指定的顺序来执行测试用例
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class JunitTest {@Order(4)@Testvoid test04(){System.out.println("这是第4个测试用例");}@Disabled// 忽略当前测试用例(当前这个测试用例不执行)@Test// @Test 表明当前的方法是一个测试用例void test01(){WebDriver webDriver = new ChromeDriver();webDriver.get("https://www.baidu.com/");}@Order(2)@Testvoid test02(){System.out.println("这是第2个测试用例");}@Order(3)@Testvoid test03(){System.out.println("这是第3个测试用例");}
}
可以看到,我们是通过注解 @TestMethodOrder(MethodOrderer.OrderAnnotation.class) 设定为根据指定的顺序来执行测试用例,通过 @Order 来指定具体的测试用例执行的顺序,没有被 @Order修饰的测试用例默认最后执行 。
接下来,我们来了解一下通过随机的顺序来执行测试用例:
// 根据随机的顺序来执行测试用例
@TestMethodOrder(MethodOrderer.Random.class)
public class JunitTest {@Order(4)@Testvoid test04(){System.out.println("这是第4个测试用例");}@Disabled// 忽略当前测试用例(当前这个测试用例不执行)@Test// @Test 表明当前的方法是一个测试用例void test01(){WebDriver webDriver = new ChromeDriver();webDriver.get("https://www.baidu.com/");}@Order(2)@Testvoid test02(){System.out.println("这是第2个测试用例");}@Order(3)@Testvoid test03(){System.out.println("这是第3个测试用例");}
}
可以看到每次执行的测试用例顺序不同。
4. 参数化
参数化中有单参数、多参数、CSV、方法。
4.1 单参数
注意,以下两个注解不能同时用来修饰一个方法。
@ParameterizedTest@ValueSource(strings = {"1","2","3"})void test05(String str){System.out.println(str);}
4.2 多参数
4.2.1 CSV
@ParameterizedTest@CsvSource({"1,2","3,4"})void test06(String str,int num){System.out.println(str + " " + num);}
接下来,在 resources 中新建文件:
编写代码:
@ParameterizedTest@CsvFileSource(resources = "test01.csv")void test07(int id,String name){System.out.println("id" + id + ",name" + name);}
4.2.2 方法
编写方法:
public static Stream<Arguments> Generator(){return Stream.of(Arguments.arguments("1,小张","2,小李"));}
代码:
// 注册参数@ParameterizedTest// 注册的参数@MethodSource("Generator")void test08(String num,String name){System.out.println(num + " " + name);}
5. 断言
断言相等和断言不相等:
@ParameterizedTest@ValueSource(ints = {10})void test09(int num){// 断言相等Assertions.assertEquals(num,10);// 断言不相等Assertions.assertNotEquals(num,11);}
可以看到运行正确,此时我们修改代码:
@ParameterizedTest@ValueSource(ints = {10})void test09(int num){// 断言相等Assertions.assertEquals(num,10);// 断言不相等Assertions.assertNotEquals(num,10);}
可以看到此时报错,因为我们断言是不相等的,而实际是相等的。
断言为空和断言不为空:
@ParameterizedTest@ValueSource(strings = "1")void test10(String num){// 断言相等Assertions.assertEquals(num,"1");// 断言不相等Assertions.assertNotEquals(num,"11");// 断言为空Assertions.assertNull(num);}
@ParameterizedTest@ValueSource(strings = "1")void test10(String num){// 断言相等Assertions.assertEquals(num,"1");// 断言不相等Assertions.assertNotEquals(num,"11");// 断言为空
// Assertions.assertNull(num);// 断言不为空Assertions.assertNotNull(num);}
6. 测试套件
测试套件:通过一段代码直接将所有的测试用例跑起来。
@Suite
@SelectClasses({JunitTest.class,JunitTest02.class})
public class RunSuite {}
通过添加以上两个注解就可以将所有需要测试的类运行起来。
执行指定的包:
@Suite
// 按照指定的类执行
//@SelectClasses({JunitTest.class, JunitTest02.class})
// 按照指定的包执行
@SelectPackages({"Junitlearn","Junitlearn02"})
public class RunSuite {}