网站绝对路径,wordpress文章点赞,设计网站公司搜索y湖南岚鸿知名,网站建设教程搭建芽嘱湖南岚鸿信赖JUnit是一个开源的 Java 单元测试框架#xff0c;它使得组织和运行测试代码变得非常简单#xff0c;利用JUnit可以轻松地编写和执行单元测试#xff0c;并且可以清楚地看到哪些测试成功#xff0c;哪些失败
JUnit 还提供了生成测试报告的功能#xff0c;报告不仅包含测试…JUnit是一个开源的 Java 单元测试框架它使得组织和运行测试代码变得非常简单利用JUnit可以轻松地编写和执行单元测试并且可以清楚地看到哪些测试成功哪些失败
JUnit 还提供了生成测试报告的功能报告不仅包含测试的成功率还能统计被测试代码的覆盖率。通过进行单元测试我们可以确保每个方法按照预期正确运行。
如果我们修改了某个方法的代码只需要确保相应的单元测试通过就可以认为修改是正确的。此外测试代码本身也可以作为示例代码用于演示如何调用该方法。
几乎所有的IDE工具都集成了JUnit我们这里使用IDEA
参考 编写JUnit测试 - 廖雪峰的官方网站 (liaoxuefeng.com)
目录
编写JUnit单元测试
使用Fixture自动执行代码
异常测试
条件测试
参数化测试 编写JUnit单元测试
用递推的方法写一个计算n的阶乘的Java方法。 我们可以针对刚刚写的Java编写一个对应的测试代码对其进行测试在IDEA中可以直接右击点击生成Junit测试。 点击确定生成一个FactorialTest.java文件。 这是JUnit会把带有Test的方法识别为测试方法因此需要给测试方法加上Test注解测试方法内部用assertEquals(1, Factorial.fact(1))表示期望Factorial.fact(1)返回1。 运行这个测试程序JUnit就会给出成功的测试和失败的测试还可以生成测试报告不仅包含测试的成功率还可以统计测试的代码覆盖率即被测试的代码本身有多少经过了测试。 Factorial.java
public class Factorial {public static long fact(long n) {long r 1;for (long i 1; i n; i) {r r * i;}return r;}
}FactorialTest.java
import static org.junit.jupiter.api.Assertions.*;import org.junit.jupiter.api.Test;public class FactorialTest {Testvoid testFact() {assertEquals(1, Factorial.fact(1));assertEquals(2, Factorial.fact(2));assertEquals(6, Factorial.fact(3));assertEquals(3628800, Factorial.fact(10));assertEquals(2432902008176640000L, Factorial.fact(20));}}使用Fixture自动执行代码
Fixture是JUnit提供的编写测试前准备、测试后清理的固定代码可以用于测试前和测试后自动执行代码。
先编写一个简单的实现加减法功能的Calculator代码。 但是测试的时候需要先初始化对象可以使用BeforeEach和AfterEach标记的方法BeforeEach标记的方法会在执行每个Test的方法之前调用而AfterEach标记的方法会在执行每个Test的方法之后调用这样就可以通过BeforeEach和AfterEach标记来自动实现对象的生成和销毁。 然后再编写我们的测试代码。 运行测试代码可以看到测试结果。 如果需要在所有Test方法运行前后仅运行一次那么可以使用BeforeAll和AfterAll对方法进行标记。 Calculator.java
public class Calculator {private long n 0;public long add(long x) {n n x;return n;}public long sub(long x) {n n - x;return n;}
}CalculatorTest.java
import static org.junit.jupiter.api.Assertions.*;import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;public class CalculatorTest {Calculator calculator;BeforeEachpublic void setUp() {this.calculator new Calculator();}AfterEachpublic void tearDown() {this.calculator null;}Testvoid testAdd() {assertEquals(100, this.calculator.add(100));assertEquals(150, this.calculator.add(50));assertEquals(130, this.calculator.add(-20));}Testvoid testSub() {assertEquals(-100, this.calculator.sub(100));assertEquals(-150, this.calculator.sub(50));assertEquals(-130, this.calculator.sub(-20));}
}
异常测试
对于可能抛出的异常进行测试是测试的重要环节因此在编写JUnit测试的时候除了正常的输入输出还要特别针对可能导致异常的情况进行测试。
在计算阶乘的方法中增加对参数n的检查如果n为负数则直接抛出异常IllegalArgumentException。 在测试代码中我们可以编写一个Test方法专门测试异常JUnit提供assertThrows函数来期望捕获一个指定的异常。 运行测试代码可以看到测试结果。 Factorial.java
public class Factorial {public static long fact(long n) {if (n 0) {throw new IllegalArgumentException();}long r 1;for (long i 1; i n; i) {r r * i;}return r;}
}FactorialTest.java
import static org.junit.jupiter.api.Assertions.*;import org.junit.jupiter.api.Test;public class FactorialTest {Testvoid testFact() {assertEquals(1, Factorial.fact(1));assertEquals(2, Factorial.fact(2));assertEquals(6, Factorial.fact(3));assertEquals(3628800, Factorial.fact(10));assertEquals(2432902008176640000L, Factorial.fact(20));}Testvoid testNegative() {assertThrows(IllegalArgumentException.class, () - {Factorial.fact(-1);});}
}条件测试
条件测试可以在满足某种条件下执行某些测试方法不执行某些测试方法。
编写一个程序该程序中的方法在Windows上跑和在Linux上跑的代码路径不同。 编写测试代码的时候用EnableOnOs标记方法指定只有在特定系统下才执行该测试方法。 用DisabledOnOs标记方法表示不在某个系统上执行该方法。 用DisabledOnJre标记方法表示只能在高于特定Java版本的测试。 用EnabledIfSystemProperty(named os.arch, matches .*64.*)标记表示只能在64位操作系统上执行的测试。 用EnabledIfEnvironmentVariable标记方法表示需要传入环境变量DEBUGtrue才能执行的测试。 运行测试代码可以看到测试结果。 Config.java
public class Config {public String getConfigFile(String filename) {String os System.getProperty(os.name).toLowerCase();if (os.contains(win)) {return C:\\ filename;}if (os.contains(mac) || os.contains(linux) || os.contains(unix)) {return /usr/local/ filename;}throw new UnsupportedOperationException();}
}ConfigTest.java
import static org.junit.jupiter.api.Assertions.*;import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.*;public class ConfigTest {Config config;BeforeEachpublic void setUp() {this.config new Config();}AfterEachpublic void tearDown() {this.config null;}TestEnabledOnOs(OS.WINDOWS)void testWindows() {assertEquals(C:\\test.ini, config.getConfigFile(test.ini));}TestEnabledOnOs({OS.LINUX, OS.MAC})void testLinuxAndMac() {assertEquals(/usr/local/test.cfg, config.getConfigFile(test.cfg));}TestDisabledOnOs(OS.WINDOWS)void testOnNonWindowsOs() {// TODO: this test is disabled on windows}TestDisabledOnJre(JRE.JAVA_8)void testOnJava9OrAbove() {// TODO: this test is disabled on java 8}TestEnabledIfSystemProperty(named os.arch, matches .*64.*)void testOnlyOn64bitSystem() {// TODO: this test is only run on 64 bit system}TestEnabledIfEnvironmentVariable(named DEBUG, matches true)void testOnlyOnDebugMode() {// TODO: this test is only run on DEBUGtrue}
}
参数化测试
JUnit提供了一个ParameterizedTest注解用来进行参数化测试。参数化测试和普通测试稍微不同的地方在于一个测试方法需要接收至少一个参数然后传入一组参数反复运行。
编写一个方法该方法把字符串的第一个字母变为大写后续字母变为小写。 在编写测试代码的时候需要给出输入和预期输出可以通过MethodSource注解它允许我们编写一个同名的静态方法来提供测试参数编写一个静态方法testCapitalize返回了一组测试参数每个参数都包含两个String作为测试方法的两个参数传入。 还可以使用CsvSource标记传入测试参数的方法它的每一个字符串表示一行一行包含的若干参数用 , 分隔。 如果测试数据很多可以把测试数据提到一个独立的CSV文件中标注上CsvFileSource表示从CSV文件中读取数据。 由于JUnit只在classpath中查找指定的CSV文件因此test-capitalize.csv这个文件要放到src/main/resources目录下内容格式如下图所示。 运行测试程序测试结果如下图所示。 StringUtils.java
public class StringUtils {public static String capitalize(String s) {if (s.length() 0) {return s;}return Character.toUpperCase(s.charAt(0)) s.substring(1).toLowerCase();}
}StringUtilsTest.java
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvFileSource;import static org.junit.jupiter.api.Assertions.*;public class StringUtilsTest {
// ParameterizedTest
// MethodSource
// void testCapitalize(String input, String result) {
// assertEquals(result, StringUtils.capitalize(input));
// }
//
// static ListArguments testCapitalize() {
// return List.of( // arguments:
// Arguments.of(abc, Abc), //
// Arguments.of(APPLE, Apple), //
// Arguments.of(gooD, Good));
// }// ParameterizedTest
// CsvSource({abc, Abc, APPLE, Apple, gooD, Good})
// void testCapitalize(String input, String result) {
// assertEquals(result, StringUtils.capitalize(input));
// }ParameterizedTestCsvFileSource(resources {test_capitalize.csv})void testCapitalizeUsingCsvFile(String input, String result) {assertEquals(result, StringUtils.capitalize(input));}
}