Table of Contents
简介
JUnit-Test API简介
JUnit - 测试套件
JUnit - 忽略测试
JUnit - 时间测试
JUnit - 异常测试
JUnit - 参数化测试
本文讲解Android Junit Test 的使用
在项目目录下的build.gradle文件的dependencies中添加
testImplementation 'junit:junit:4.12'
常用api
1 |
void assertEquals(boolean expected, boolean actual) 检查两个变量或者等式是否平衡 |
2 |
void assertTrue(boolean expected, boolean actual) 检查条件为真 |
3 |
void assertFalse(boolean condition) 检查条件为假 |
4 |
void assertNotNull(Object object) 检查对象不为空 |
5 |
void assertNull(Object object) 检查对象为空 |
6 |
void assertSame(boolean condition) assertSame() 方法检查两个相关对象是否指向同一个对象 |
7 |
void assertNotSame(boolean condition) assertNotSame() 方法检查两个相关对象是否不指向同一个对象 |
8 |
void assertArrayEquals(expectedArray, resultArray) assertArrayEquals() 方法检查两个数组是否相等
|
JUnit 中的注释的列表以及他们的含义:
1 |
@Test 这个注释说明依附在 JUnit 的 public void 方法可以作为一个测试案例。 |
2 |
@Before 有些测试在运行前需要创造几个相似的对象。在 public void 方法加该注释是因为该方法需要在 test 方法前运行。 |
3 |
@After 如果你将外部资源在 Before 方法中分配,那么你需要在测试运行后释放他们。在 public void 方法加该注释是因为该方法需要在 test 方法后运行。 |
4 |
@BeforeClass 在 public void 方法加该注释是因为该方法需要在类中所有方法前运行。 |
5 |
@AfterClass 它将会使方法在所有测试结束后执行。这个可以用来进行清理活动。 |
6 |
@Ignore 这个注释是用来忽略有关不需要执行的测试的。 |
JUnite 执行过程:
beforeClass() 方法首先执行,并且只执行一次。
afterClass() 方法最后执行,并且只执行一次。
before() 方法针对每一个测试用例执行,但是是在执行测试用例之前。
after() 方法针对每一个测试用例执行,但是是在执行测试用例之后。
在 before() 方法和 after() 方法之间,执行每一个测试用例。
测试套件意味着捆绑几个单元测试用例并且一起执行他们。在 JUnit 中,@RunWith 和 @Suite 注释用来运行套件测试。这个教程将向您展示一个例子,其中含有两个测试样例 TestJunit1 & TestJunit2 类,我们将使用测试套件一起运行他们。
使用 Test Suite 类
创建一个 java 类。
在类中附上 @RunWith(Suite.class) 注释。
使用 @Suite.SuiteClasses 注释给 JUnit 测试类加上引用。
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
@RunWith(Suite.class)
@Suite.SuiteClasses({
TestJunit1.class,
TestJunit2.class
})
public class JunitTestSuite {
}
有时可能会发生我们的代码还没有准备好的情况,这时测试用例去测试这个方法或代码的时候会造成失败。@Ignore 注释会在这种情况时帮助我们。
一个含有 @Ignore 注释的测试方法将不会被执行。
如果一个测试类有 @Ignore 注释,则它的测试方法将不会执行。
现在我们用例子来学习 @Ignore。
import org.junit.Ignore;
import static org.junit.Assert.assertEquals;
public class TestJunit {
String message = "Robert";
MessageUtil messageUtil = new MessageUtil(message);
@Ignore
@Test
public void testPrintMessage() {
System.out.println("Inside testPrintMessage()");
message = "Robert";
assertEquals(message,messageUtil.printMessage());
}
@Test
public void testSalutationMessage() {
System.out.println("Inside testSalutationMessage()");
message = "Hi!" + "Robert";
assertEquals(message,messageUtil.salutationMessage());
}
}
TestJunit 在类级别上使用 @Ignore 来忽略所有的测试用例
import org.junit.Test;
import org.junit.Ignore;
import static org.junit.Assert.assertEquals;
@Ignore
public class TestJunit {
String message = "Robert";
MessageUtil messageUtil = new MessageUtil(message);
@Test
public void testPrintMessage() {
System.out.println("Inside testPrintMessage()");
message = "Robert";
assertEquals(message,messageUtil.printMessage());
}
@Test
public void testSalutationMessage() {
System.out.println("Inside testSalutationMessage()");
message = "Hi!" + "Robert";
assertEquals(message,messageUtil.salutationMessage());
}
}
Junit 提供了一个方便选项。如果一个测试用例比起指定的毫秒数花费了更多的时间,那么 Junit 将自动将它标记为失败。timeout 参数和 @Test 注释一起使用。现在让我们看看代码中 @test(timeout)。
import org.junit.Test;
import org.junit.Ignore;
import static org.junit.Assert.assertEquals;
public class TestJunit {
String message = "Robert";
MessageUtil messageUtil = new MessageUtil(message);
@Test(timeout=1000)
public void testPrintMessage() {
System.out.println("Inside testPrintMessage()");
messageUtil.printMessage();
}
@Test
public void testSalutationMessage() {
System.out.println("Inside testSalutationMessage()");
message = "Hi!" + "Robert";
assertEquals(message,messageUtil.salutationMessage());
}
}
Junit 用代码处理提供了一个追踪异常的选项。你可以测试代码是否它抛出了想要得到的异常。expected 参数和 @Test 注释一起使用。现在让我们看看活动中的 @Test(expected)。
import org.junit.Test;
import org.junit.Ignore;
import static org.junit.Assert.assertEquals;
public class TestJunit {
String message = "Robert";
MessageUtil messageUtil = new MessageUtil(message);
@Test(expected = ArithmeticException.class)
public void testPrintMessage() {
System.out.println("Inside testPrintMessage()");
messageUtil.printMessage();
}
@Test
public void testSalutationMessage() {
System.out.println("Inside testSalutationMessage()");
message = "Hi!" + "Robert";
assertEquals(message,messageUtil.salutationMessage());
}
}
Junit 4 引入了一个新的功能参数化测试。参数化测试允许开发人员使用不同的值反复运行同一个测试。你将遵循 5 个步骤来创建参数化测试。
用 @RunWith(Parameterized.class) 来注释 test 类。
创建一个由 @Parameters 注释的公共的静态方法,它返回一个对象的集合(数组)来作为测试数据集合。
创建一个公共的构造函数,它接受和一行测试数据相等同的东西。
为每一列测试数据创建一个实例变量。
用实例变量作为测试数据的来源来创建你的测试用例。
一旦每一行数据出现测试用例将被调用。让我们看看活动中的参数化测试。
import java.util.Arrays;
import java.util.Collection;
import org.junit.Test;
import org.junit.Before;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import org.junit.runner.RunWith;
import static org.junit.Assert.assertEquals;
@RunWith(Parameterized.class)
public class PrimeNumberCheckerTest {
private Integer inputNumber;
private Boolean expectedResult;
private PrimeNumberChecker primeNumberChecker;
@Before
public void initialize() {
primeNumberChecker = new PrimeNumberChecker();
}
// 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 PrimeNumberCheckerTest(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@Testpublic void testPrimeNumberChecker() {
System.out.println("Parameterized Number is : " + inputNumber);
assertEquals(expectedResult,
primeNumberChecker.validate(inputNumber));
}
}
一旦它会将所有的数组中的参数全部运行,Object[][] 每一行代表一组数据,一组中第一个代表参数第二个代表预期结果。
运行测试
./gradlew --info test clean
或可以点击类中两个运行按钮