单元测试框架——Junit5

文章目录

  • Junit
    • 1. 注解
    • 2.断言
    • 3.测试用例执行顺序
    • 4.测试套件Suite
      • 1) 指定多个类
      • 2) 指定包
    • 5. 参数化
      • 1) 单参数
      • 2) 多参数
      • 3) 文件注入
    • 6.动态参数


Junit

Junit是一个开源的用于Java语言的单元测试框架,也是Java方向使用最广泛的单元测试框架。

在pom.xml中引入Junit5相关依赖

<dependency>
    <groupId>org.junit.jupitergroupId>
    <artifactId>junit-jupiterartifactId>
    <version>5.8.2version>
    <scope>testscope>
dependency>
<dependency>
    <groupId>org.junit.platformgroupId>
    <artifactId>junit-platform-suiteartifactId>
    <version>1.8.2version>
    <scope>testscope>
dependency>

1. 注解

  • @Test:表示一个方法/用例
  • BeforeEach:表示被注解的方法在其它所有方法执行前都要执行一遍,也就是说其它方法有3个它就要执行3遍
  • @BeforeAll:表示被注解的方法在其它方法之前执行(使用该注解的方法必须定义成static)
  • @AfterEach:表示被注解的方法应该在其它方法执行后都要执行一遍,其它方法有4个就执行4遍
  • @AfterAll:表示被注解的方法在其它方法后执行一遍就可以了(使用该注解的方法必须定义成static)
public class JunitDemo {
    private static ChromeOptions options;
    private static ChromeDriver driver;
    @BeforeAll
    public static void init() {
        options = new ChromeOptions();
        options.addArguments("--remote-allow-origins=*");
        driver = new ChromeDriver(options);
        driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(2));//隐式等待两秒
    }

    @Test
    public void test1() {
        driver.get("https://www.baidu.com");
        driver.findElement(By.cssSelector("#kw")).sendKeys("Junit");
        driver.findElement(By.cssSelector("#su")).click();
    }

    @AfterAll
    public static void quit() throws InterruptedException {
        driver.quit();
    }
}

前后执行代码

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

public class JunitDemo2 {

    @BeforeEach
    public void BeforeEach() {
        System.out.println("@BeforeEach");
    }
    @AfterEach
    public void AfterEach() {
        System.out.println("@AfterEach");
    }

    @Test
    public void test1() {
        System.out.println("test1");
    }
    @Test
    public void test2() {
        System.out.println("test2");
    }
    @Test
    public void test3() {
        System.out.println("test3");
    }
}

运行结果

@BeforeEach
test1
@AfterEach


@BeforeEach
test2
@AfterEach


@BeforeEach
test3
@AfterEach

2.断言

很多编程语言都有断言C语言和Java都是有断言功能的,但断言一遍是出现在测试阶段,如果在生产环境使用断言,只要一旦触发断言程序就会立即终止。

在Junit中提供了一些断言方法

  • Assertions.assertEquals(预期值,实际值):如果预期和实际值不相同就会触发断言
  • Assertions.assertNotEquals(预期值,实际值):如果预期值和实际值匹配就会触发断言
public class AssertDemo {
    private static ChromeOptions options;
    private static ChromeDriver driver;

    @BeforeAll
    public static void init() {
        options = new ChromeOptions();
        options.addArguments("--remote-allow-origins=*");
        driver = new ChromeDriver(options);
        driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(2));
    }

    @Test
    public void test1() {
        driver.get("https://www.baidu.com");
        WebElement element = driver.findElement(By.cssSelector("#su"));
        String button = element.getAttribute("value");
        Assertions.assertEquals("百度一下",button);
    }

    @AfterAll
    public static void quit() {
        driver.quit();
    }
}
  • Assertions.assertTrue():如果括号里的表达式值为False就会触发断言
  • Assertions.assertFalse():如果括号里的表达式值为True就会触发断言
  • Assertions.assertNull():如果括号里的表达式的值不为null就会触发断言
  • Assertions.assertNotNull():如果括号里的表达式的值为null就会触发断言

3.测试用例执行顺序

Junit的默认执行顺序是不确定的,官网文档中也没有给出明确的执行顺序。但我们可以使用Junit里提供的方法来手动设置用例的执行顺序,文档中给出了很多的排序方法。

这里介绍方法的排序,通过@order注解来排序

@TestMethodOrder(MethodOrderer.OrderAnnotation.class)//标注当前类使用方法来进行排序
public class JunitOrderTest {
    @Test
    @Order(3)
    void test1() {
        System.out.println("aaa");
    }
    @Test
    @Order(2)
    void test2() {
        System.out.println("bbb");
    }
    @Test
    @Order(1)
    void test3() {
        System.out.println("ccc");
    }
}

运行结果

ccc


bbb


aaa

4.测试套件Suite

1) 指定多个类

通过测试套件可以将多个类的测试用例一起执行,通过@Suite@SelectClasses注解配合实现

/**
 * 指定类来添加到套件中执行
 */
@Suite
@SelectClasses({JunitDemo.class,JunitDemo2.class})
public class RunAllSuite {
    @Test
    void test() {
        System.out.println("@Suite");
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2l2hiYHS-1687426352214)(assets/1686037273126.png)]

运行结果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PM40kyR6-1687426352215)(assets/1686037306028.png)]

2) 指定包

指定包,添加到套件中执行,需要注意的是执行包下面所有Test命名的文件中的所有@Test注解的用例。

这里指定的是junit包下的Test命名的类

@Suite
@SelectPackages("junit")//指定包下所有以Test命名的类中所有被@Test注解的用例
public class runAllSuite {
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xeLXmbwZ-1687426352216)(assets/1686037970420.png)]

5. 参数化

有的时候我们的测试方法需要传递参数,而有多个参数写多个方法又比较麻烦,所以需要使用Junit的参数化。通过@ParameterizedTest注解标注类型参数化。

1) 单参数

单参数通过@ValueSource注解来实现,@ValueSource(类型={参数1,参数2,…})

@ValueSource中支持的类型有:

  • short
  • byte
  • int
  • long
  • float
  • double
  • char
  • boolean
  • Stirng
  • Class

在对应的类型使用后面+s使用

public class ParameterTest {
    @ParameterizedTest
    @ValueSource(strings = {"张三","李四","王五"})
    void test1(String name) {
        System.out.println("name:"+name);
    }
}

运行结果

name:张三

name:李四

name:王五

2) 多参数

多参数使用@CsvSource注解,@CsvSource(value={“张三,18”,“李四,20”,…})

public class ParameterTest {
    /**
     * 多参数
     * @param name
     * @param age
     */
    @ParameterizedTest
    @CsvSource(value = {"张三,18","李四,20","王五,25"})
    void test2(String name,Integer age) {
        System.out.println("name:"+name+"age:"+age);
    }
}

运行结果

name:张三

name:李四

name:王五

多参数可以指定分割符,通过delimiterString属性设置

public class ParameterTest {
    @ParameterizedTest
    @CsvSource(value = {"张三-18","李四-20","王五-25"},delimiterString = "-")
    void test3(String name,Integer age) {
        System.out.println("name:"+name+"age:"+age);
    }
}

如果参数里包含逗号就要使用单引号做转义字符

@ParameterizedTest
    @CsvSource(value = {"'张,三',18","李四,20","王五,25"})
    void test2(String name,Integer age) {
        System.out.println("name:"+name+"age:"+age);
    }

3) 文件注入

如果参数非常多,在代码中编写不太友好,就可以借助文件注入的方式来添加,通过@CsvFileSource来指定

指定读取resources目录

@ParameterizedTest
@CsvFileSource(resources = "/test.txt",delimiterString = " ") //指定文件中参数以空格分割
void test4(String name,int age) {
    System.out.println("name:"+name+"age:"+age);
}

test.txt文件内容

张三 18
李四 20
王五 25
赵六 30

指定读取本机文件

@ParameterizedTest
    @CsvFileSource(files = "C:\\Users\\HeHanYu\\Desktop\\code\\Java\\JavaCode\\spring\\ssm_blog_system\\src\\test\\java\\file\\test.txt",delimiterString = " ")
    void test5(String name,int age) {
        System.out.println("name:"+name+"age:"+age);
    }

6.动态参数

单参数

通过@MethodSource指定方法的返回值为动态参数,返回值可以是Stream流,List、Set等

public class ParameterTest {


    @ParameterizedTest
    @MethodSource("demo")
    void test6(String name) {
        System.out.println(name);
    }
    static Stream<String> demo() {
        return Stream.of("张三","李四");
    }
    static List<String> createV() {
        List<String> list = new ArrayList<>();
        list.add("张三");
        list.add("李四");
        list.add("王五");

        return list;
    }
    static Set<String> createValue() {
      Set<String> set = new HashSet<>();
      set.add("张三");
      set.add("李四");
      set.add("王五");

      return set;
    }
}

多参数

使用Arguments可以实现多参数

public class ParameterTest {

    @ParameterizedTest
    @MethodSource("multiparameter")
    void test7(String name,int age) {
        System.out.println(name+":"+age);
    }

    static Stream<Arguments> multiparameter() {
        return Stream.of(Arguments.arguments("张三",18),Arguments.arguments("李四",25));
    }
}

你可能感兴趣的:(测试,单元测试,junit)