目录
- 1. 注解
- @Test 注解
- @BeforeEach @BeforeAll
- @AfterEach @AfterAll
 
- 2. 断言 assert
- assertequals
- assertTrue assertFalse
- assertNull assertNotNull
 
- 3. 用例执行顺序
- 方法排序,通过 @Order 注解来排序
 
- 4. 测试套件 Suite
- 5. 参数化单参数
- strings
- ints
 
- 6. 参数化多参数
- @CsvSource
- @CsvFileSource
 
- 7. 动态参数
- 动态参数单参数
- 动态参数多参数
 
● 实现自动化测试需要 selenium基本语法+Junit单元测试框架才能完成自动化测试
Junit是一个开源的Java语言的单元测试框架,Junit是Java方向使用最广泛的单元测试框架,使用Java开发者都应当学习Junit并且掌握单元测试的编写
selenium和Junit:假如要实现一个灯泡,selenium就是灯泡,Junit就是电源
首先需要在pom文件中引入Junit依赖:
    <dependencies>
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-java</artifactId>
            <version>4.0.0</version>
        </dependency>
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.6</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/junit/junit -->
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter</artifactId>
            <version>5.8.2</version>
            <scope>test</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.junit.platform/junit-platform-launcher -->
        <!-- https://mvnrepository.com/artifact/org.junit.platform/junit-platform-suite-api -->
        <dependency>
            <groupId>org.junit.platform</groupId>
            <artifactId>junit-platform-suite</artifactId>
            <version>1.8.2</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.platform</groupId>
            <artifactId>junit-platform-reporting</artifactId>
            <version>1.8.2</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
1. 注解
@Test 注解
@Test 能够表示一个方法/用例
 在不引入注解的情况下执行测试方法需要在Java main方法中去执行,使用注解之后只需要在要执行的测试方法上面加上 @Test 注解即可直接进行测试方法的执行:
public class JunitAutoTest {
   private final ChromeDriver chromeDriver=new ChromeDriver();
   public void start(){
       chromeDriver.get("https://www.baidu.com/");
   }
   @Test
    public void zhujieTest() throws InterruptedException {
       start();
       chromeDriver.findElement(By.cssSelector("#kw")).sendKeys("junit");
       chromeDriver.findElement(By.cssSelector("#su")).click();
       Thread.sleep(3000);
       end();
    }
    public void end(){
       chromeDriver.quit();
    }
}
不需要再次创建一个runtest类来执行,大大加快了测试执行;
@BeforeEach @BeforeAll
@BeforeEach :表示被注解的方法应该在其他方法执行之前都执行一遍
public class JunitAutoTest {
    @BeforeEach
    public void aaa(){
        System.out.println("pre");
    }
    @Test
    public void bbb(){
        System.out.println("bbb");
    }
    @Test
    public void ccc(){
        System.out.println("ccc");
    }
    
}
在 aaa 方法上加了 @BeforeEach 注解表示在执行 bbb,ccc方法之前都会各自执行一次aaa方法,打印 pre:
 
 @BeforeAll :表示在其他方法执行之前只需要执行一遍
 ● 使用 @BeforeAll 注解的方法必须定义为static静态方法
public class JunitAutoTest {
    @BeforeAll // 必须定义为static方法,否则报错
    public static void aaa(){
        System.out.println("pre");
    }
    @Test
    public void bbb(){
        System.out.println("bbb");
    }
    @Test
    public void ccc(){
        System.out.println("ccc");
    }
}
在执行 bbb ccc 方法之前先执行一遍 aaa 方法,只打印一次 pre:
 
@AfterEach @AfterAll
用法和之前的 @BeforeEach 和 @BeforeAll 类似,表示注解的方法应该在其他方法执行之后执行:
 @AfterEach:表示被注解的方法应该在其他方法执行之后都执行一遍:
public class JunitAutoTest {
    @AfterEach
    public  void aaa(){
        System.out.println("pre");
    }
    @Test
    public void bbb(){
        System.out.println("bbb");
    }
    @Test
    public void ccc(){
        System.out.println("ccc");
    }
}

 @AfterAll:表示在其他方法执行之后只需要执行一遍
 ● 使用 @AfterAll 注解的方法必须定义为static静态方法
public class JunitAutoTest {
    @AfterAll
    public  static void aaa(){
        System.out.println("pre");
    }
    @Test
    public void bbb(){
        System.out.println("bbb");
    }
    @Test
    public void ccc(){
        System.out.println("ccc");
    }
}

2. 断言 assert
写自动化测试,结果分为成功或者失败的,怎么评判结果是成功还是失败,就需要用到 assert 断言操作
assertequals
● assertequals(expect,actual)
public class AssertTest {
    private final ChromeDriver chromeDriver=new ChromeDriver();
    /**
     * 测试百度首页元素是否正确
     */
    @Test
    void equalsTest(){
        chromeDriver.get("https://www.baidu.com/");
        String value = chromeDriver.findElement(By.cssSelector("#su")).getAttribute("value");
        Assertions.assertEquals("百度一下",value);
    }
}
断言成功:
 
 断言失败:
 
 同理还可以判断不相等:assertNotEquals
    @Test
    void equalsTest(){
        chromeDriver.get("https://www.baidu.com/");
        String value = chromeDriver.findElement(By.cssSelector("#su")).getAttribute("value");
        Assertions.assertNotEquals("百s度一下",value);
        chromeDriver.quit();
    }
此时不相等,断言成功:
 
assertTrue assertFalse
assertTrue assertFalse 参数是表达式,也就是Boolean类型的
  @Test
    void assertTrueTest(){
        chromeDriver.get("https://www.baidu.com/");
        String value = chromeDriver.findElement(By.cssSelector("#su")).getAttribute("value");
        Assertions.assertTrue(value.equals("百度一下")); // true 执行通过
        chromeDriver.quit();
    }
assertFalse 同理
assertNull assertNotNull
   @Test
    void assertNull(){
        String a=null;
        Assertions.assertNull(a);
    }
a是null,执行通过
 @Test
    void assertNull(){
        String a=null;
        Assertions.assertNotNull(a);
    }
a是null,执行不通过
 
3. 用例执行顺序
Junit默认执行顺序是不确定的,官方文档没有明确给出
 官方文档地址:https://junit.org/junit5/
 但是我们仍然可以使用Junit里提供的方法来手动设置用例的执行顺序
 文档中给出的排序方法非常多,诸如方法的排序,标签的排序。。。。
方法排序,通过 @Order 注解来排序
当多个测试用例之间没有解耦,存在前后关联关系,就需要手动指定用例的执行顺序,否则就无法控制用例的执行先后顺序出现错误
@TestMethodOrder(MethodOrderer.OrderAnnotation.class) // 标注当前类使用方法来进行排序
public class RunOrderTest {
    @Test
    @Order(1) // 明确标注具体执行顺序
    void print(){
        System.out.println("aaa");
    }
    @Test
    @Order(2)
    void show(){
        System.out.println("bbb");
    }
    @Test
    @Order(3)
    void dayin(){
        System.out.println("ccc");
    }
    @Test
    @Order(4)
    void shuchu(){
        System.out.println("ddd");
    }
}
所以在编写测试用例时候尽量保持测试用例的独立性,如果存在关联关系记得手动指定用例的执行顺序
 ● @TestMethodOrder(MethodOrderer.OrderAnnotation.class) +
 @Order(顺序)
4. 测试套件 Suite
平时执行一次单元测试只能执行一个类,要是想一次性执行多个类中的测试用例方法,就需要用到测试套件
- 指定类,添加到套件中并执行
  
 打包执行成功:
  
- 选择指定的包,添加到套件中执行
 ● 使用指定的包来添加套件的前提,所有的文件都需要以Test,tests命名(包含),同时我们的用例都必须要加上 @Test 注解
  
  
 包里面的类命名要带上 test 才能够被识别到
 打包执行成功:
  
5. 参数化单参数
参数化用到的注解: @Parameterizetest 标注方法类型为参数化
 强调参数的来源:
 需要添加参数的来源:
 @ValueSource(类型={参数1,参数2,…}) (类型:ints,String,floats ,… 使用原生类型)
 valuesource中支持的类型:
 
 参数化举列:
strings
public class ParameterizdTest {
    @ParameterizedTest // 不需要添加 @test 注解,否则方法会多执行一遍
    @ValueSource(strings = {"昕上","萌萌","旺财","咪咪"})
    void myTest(String name){
        System.out.println(name);
    }
}

ints
  @ParameterizedTest
    @ValueSource(ints = {10,20,30,40})
    void printAge(int age){
        System.out.println(age);
    }

6. 参数化多参数
@CsvSource
用到的核心注解: @CsvSource(value={“心上,20”,“萌萌,10”,“旺财,70”,“咪咪,99”})
 默认的分隔符是逗号“,”
 @ParameterizedTest
    @CsvSource(value = {"心上,20","萌萌,10","旺财,70","咪咪,99"})
    void printNameAndAge(String name,int age){
        System.out.println("name:"+name+","+"age:"+age);
    }
如果觉得逗号不好看,也可以自定义分隔符,通过 delimiterString = “xx” 进行设置:
  @ParameterizedTest
    @CsvSource(value = {"心上-20","萌萌-10","旺财-70","咪咪-99"},delimiterString = "-")
    void printNameAndAge(String name,int age){
        System.out.println("name:"+name+","+"age:"+age);
    }

 如果遇到赋值的值包含了分隔符的特殊情况,需要使用单引号 ‘’ 来进行转义,否则会报错:
 
 加上单引号:
 @ParameterizedTest
    @CsvSource(value = {"'心,上',20","萌萌,10","旺财,70","咪咪,99"})
    void printNameAndAge(String name,int age){
        System.out.println("name:"+name+","+"age:"+age);
    }

 正确赋值,执行通过
@CsvFileSource
如果参数非常的多,在代码中编写不太好看,就可以借助文件注入的方法来添加;
 @CsvFileSource(指定文件路径)
    @ParameterizedTest
    @CsvFileSource(resources = "/my.csv")
    void csvFileSource(String name,int age){
        System.out.println("name:"+name+","+"age:"+age);
    }
指定文件路径为当前项目下resources文件夹中的.csv文件:
 
 读取成功,成功赋值:
 
 也可以读取本地目录下的任意csv文件:
 
  @ParameterizedTest
    @CsvFileSource(files = "D:\\code\\file.csv")
    void csvFileSource2(String name,int age){
        System.out.println("name:"+name+","+"age:"+age);
    }
读取成功:
 
 
 同时也可以赋null值,也就是对应的位置不填写值即可:
   @ParameterizedTest
    @CsvSource(value = {",20","萌萌,10","旺财,70","咪咪,99"})
    void printNameAndAge(String name,int age){
        System.out.println("name:"+name+","+"age:"+age);
    }

 数字类型的参数必须有值,否则导致用例执行失败
7. 动态参数
动态参数单参数
核心注解:@MethodSource(“”)
 参数为数据来源的方法名
   // 动态参数
    @ParameterizedTest // 参数化注解
    @MethodSource("getName") // 提供参数数据的方法,双引号内填写具体方法名
    void dongtaiParamet(String name){
        System.out.println(name);
    }
    // 提供数据的方法,返回值可以是stream流
    static Stream<String> getName(){
        return Stream.of("心上","萌萌","旺财");
    }
需要注意提供参数数据的方法返回值可以是 stream流,stream流里面设置填写返回值:
 
 ● 同时需要设置返回数据的方法是静态方法,static
 获取成功:
 
 同样,也可以不进行具体获取参数值方法名称设置,只需要获取参数值的方法名称和测试方法名称保持一致即可识别:
 
 获取成功:
 
动态参数多参数
返回多参数使用 Arguments.arguments(参数1,参数2) …
  @ParameterizedTest
    @MethodSource
    void dongtaiParamsTest(String name,int age){
        System.out.println("name:"+name+","+"age:"+age);
    }
    // 返回多参数使用 Arguments.arguments(参数1,参数2) ...
    static Stream<Arguments> dongtaiParamsTest() {
        return Stream.of(Arguments.arguments("心上",10),Arguments.arguments("萌萌",20));
    }
参数获取成功
 
- Junit5 over ~



















