jUnit学习笔记
- 要不要做单元测试的思考
- jUnit的使用
- jUnit的一些注意事项
- 注解
- Assert断言
- JUnitCore
- TestCase
- TestResult
- TestSuite 测试套件
- 忽略测试
- 时间测试
- 异常测试
- 参数化测试
- jUnit中遇到的问题
- 1.多线程测试时,jUnit自动退出了?
- 2.测试入库的数据时,执行成功了数据却没有入库?
- 3.idea中打包去掉test。
- 4.idea如何根据类生成测试类?
要不要做单元测试的思考
单元测试又称模块测试,是对最小单元的程序模块进行正确性检测。
单元测试本身可以提高代码质量,不过要不要做单元测试,需要从功能的复杂度和功能性质来考虑。
(1)编写的工具类不建议在主程序中出现test的方法,所以可以采用单元测试,这样不会打包到主程序中。
(2)根据功能复杂度考虑单元测试,复杂的功能尽量拆到最小单元,不要让单元测试加重编码负担。
java主要用jUnit单元测试,后面记录下jUnit的使用。
jUnit的使用
maven引入junit包
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>自己找一个版本</version>
<scope>test</scope>
</dependency>
jUnit的一些注意事项
- 测试方法必须使用 @Test 修饰。
- 测试方法必须使用 public void 进行修饰,不能带参数。
- 使用单元测试会新建一个 test 目录存放测试代码,在生产部署的时候不引入 test 目录下代码。
- 测试代码的包应该和被测试代码包结构保持一致。
- 测试单元中的每个方法必须可以独立测试,方法间不能有任何依赖。
- 测试类一般使用 Test 作为类名的后缀。
- 测试方法使一般用 test作为方法名的前缀。
注解
- @Test:将一个普通方法修饰成一个测试方法。@Test(excepted=xx.class):xx.class表示异常类,表示测试的方法抛出此异常时,认为是正常的测试通过。@Test(timeout = 毫秒数) :测试方法执行时间是否符合预期。
- @BeforeClass: 会在所有的方法执行前被执行,static 方法 (全局只会执行一次,而且是第一个运行)。
- @AfterClass:会在所有的方法执行之后进行执行,static 方法 (全局只会执行一次,而且是最后一个运行)。
- @Before:会在每一个测试方法被运行前执行一次。
- @After:会在每一个测试方法运行后被执行一次。
- @Ignore:所修饰的测试方法会被测试运行器忽略。
- @RunWith:可以更改测试运行器 org.junit.runner.Runner。
Assert断言
Assert.assertFalse("连接失败!",Objects.isNull(db));
Assert.assertEquals("匹配失败!",2,3);
JUnitCore
测试用例是使用 JUnitCore 类来执行的,每个单元测试类都可以作为测试用例。
JUnitCore 是运行测试的外观类,可通过循环打印错误信息。
public class TestRunner {
public static void main(String[] args) {
Result result = JUnitCore.runClasses(TestJunit.class);
for (Failure failure : result.getFailures()) {
System.out.println(failure.toString());
}
System.out.println(result.wasSuccessful());
}
}
TestCase
测试样例定义了运行多重测试的固定格式。例如:
public class DBTestCase extends TestCase {
public void test(){
int i =this.countTestCases();
String name=this.getName();
}
}
TestResult
TestResult收集所有执行测试案例的结果,是收集参数层面的一个实例。它区分失败和错误,失败是可以预料的并且可以通过假设来检查,错误是不可预料的问题比如异常。
public class DBTestResult extends TestResult {
public synchronized void addError(Test test, Throwable t) {
super.addError((junit.framework.Test) test, t);
}
}
TestSuite 测试套件
可以运行很多测试用例。
public static void main(String[] args) {
//测试套件
TestSuite suite = new TestSuite(DbTest.class, DBTestCase.class, DBTestResult.class );
TestResult testResult = new TestResult();
suite.run(testResult);
System.out.println("测试数量 = " + testResult.runCount());
}
测试套件的类
@RunWith(Suite.class)
@Suite.SuiteClasses({ DbTest.class, DemoTest.class })
public class AllTest {
//此处不写代码,写了也不会执行
}
忽略测试
@Ignore这个注解可以忽略测试,可放到类上也可以放到方法上。
时间测试
@Test(timeout=1000)给测试方法添加了暂停时间,超时会测试停止,并不通过。
异常测试
@Test(expected = XxxxxException.class)为追踪异常的选项,可以测试代码是否它抛出了想要得到的异常。
参数化测试
参数化测试允许开发人员使用不同的值反复运行同一个测试。直接附上官方的代码吧,例子是将预设的参数数据和validate方法进行断言判断是否正确。
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import java.util.Arrays;
import java.util.Collection;
import static org.junit.Assert.assertEquals;
@RunWith(Parameterized.class)
public class ParameterTest {
private Integer inputNumber;
private Boolean expectedResult;
// Each parameter should be placed as an argument here
// Every time runner triggers, it will pass the arguments
// from parameters we defined in primeNumbers() method
public ParameterTest(Integer inputNumber,
Boolean expectedResult) {
this.inputNumber = inputNumber;
this.expectedResult = expectedResult;
}
@Parameterized.Parameters
public static Collection primeNumbers() {
return Arrays.asList(new Object[][] {
{ 2, true },
{ 6, false },
{ 19, true },
{ 22, false },
{ 23, true }
});
}
// This test will run 4 times since we have 5 parameters defined
@Test
public void testPrimeNumberChecker() {
System.out.println("Parameterized Number is : " + inputNumber);
assertEquals(expectedResult,
validate(inputNumber));
}
public Boolean validate(final Integer primeNumber) {
for (int i = 2; i < (primeNumber / 2); i++) {
if (primeNumber % i == 0) {
return false;
}
}
return true;
}
}
jUnit中遇到的问题
1.多线程测试时,jUnit自动退出了?
jUnit执行完主程序会自动结束,就一起将子线程也断掉了。解决这种情况需要用到计数器CountDownLatch。
@Test
public void testThread() throws InterruptedException {
TestClass testClass = new TestClass();
//同步计数器
int count = 20;
CountDownLatch countDownLatch = new CountDownLatch(count);
for (int i = 1; i <= count; i++) {
new Thread(() -> {
//业务处理
testClass.write(path, "writeString");
countDownLatch.countDown();
}).start();
}
countDownLatch.await();
}
2.测试入库的数据时,执行成功了数据却没有入库?
由于junit不会将数据真是存入数据库,想要真实入库需要自己加commit提交。
3.idea中打包去掉test。
图中图标可去掉test。
4.idea如何根据类生成测试类?
光标放到类名上,alt+enter,选择create test,即可在test目录下得到测试类。