1、为什么要用单元测试呢?
从最基本的说起。假设我们有这样一个类
public class Calculator{
public int add(int one, int another){
return one + another;
}
public int multiply(int one, int another){
return one * another;
}
}
如果不用单元测试的话估计要这么写测试代码了
public class CalculatorTest{
public static void main(String[] args){
Calculator mCalculator = new Calculator();
int sum = mCalculator.add(1, 2);
if(sum == 3){
Log.e("123", "add works");
}else{
Log.e("123", "add not works");
}
int product = mCalculator.multiply(2, 4);
if(product == 8){
Log.e("123", "multiply works");
}else{
Log.e("123", "multiply not works");
}
}
}
最后在运行这个CalculatorTest的main方法,在控制台输出结果,如果我们有很多类,每个类都有很多方法,那么就要写一堆代码。如果用Junit的话,我们可以按照如下的方式写测试代码。
public class CalculatorTest{
@Test
public void testAdd() throws Exception{
Calculator mCalculator = new Calculator();
int sum = mCalculator.add(1, 2);
Assert.assertEquals(3, sum);
}
@Test
public void testMultiply() throws Exception{
Calculator mCalculator = new Calculator();
int product = mCalculator.mutiply(2, 4);
Assert.assertEquals(8, product);
}
}
一个测试方法包括三个部分
1、setUp
2、执行操作。
3、验证结果
在上面的代码中,testAdd()和testMultiply()都有相同的setUp:也就是初始化Calculator mCalculator = new Calculator();,可以通过@Before来实现。
public class CalculatorTest {
Calculator mCalculator;
@Before
public void setup() {
mCalculator = new Calculator();
}
@Test
public void testAdd() throws Exception {
int sum = mCalculator.add(1, 2);
assertEquals(3, sum); //为了简洁,往往会static import Assert里面的所有方法。
}
@Test
public void testMultiply() throws Exception {
int product = mCalculator.multiply(2, 4);
assertEquals(8, product);
}
}
@Before:
如果一个方法被@Before修饰过,那么在每个测试方法调用前,这个方法都会得到调用。在testAdd()调用之前,setUp()会被调用一次。
@After:
每个测试方法运行结束之后,会得到运行的方法,比如关闭文件的操作等等。
@BeforeClass:
在跑一个测试类的所有测试方法之前,会执行一次被@BeforeClass修饰的方法。
@AfterClass:
执行完所有测试方法之后,会执行一遍被@AfterClass修饰的方法。
注意后两个方法修饰的方法必须是静态的。
@Ignore:
让某些方法在测试的时候不需要跑,要达到这个目的就是在忽略测试的方法面前加上@Ignore就可以了。
验证方法抛出异常:
比如被除数是0.
public class CalculatorTest {
Calculator mCalculator;
@Before
public void setup() {
mCalculator = new Calculator();
}
// Omit testAdd() and testMultiply() for brevity
@Test(expected = IllegalArgumentException.class)
public void test() {
mCalculator.divide(4, 0);
}
}
JUnit为我们提供了Assert方法:
1、assertEquals(expected, actual)
验证expected的值跟actual是一样的,如果是一样的话,测试通过,不然就测试失败,如果传入的是Object,那么这里的对比用的是equals()
2、assertEquals(expected, actual, tolerance);
这里传入的expected和actual是float或者double类型的,计算机表示浮点数据都有一定的偏差,所以哪怕理论上他们是相等的,在计算机表示出来则可能不是,所以这里传入一个偏差值。如果两个数差异在这个偏差值之内,则通过,否则测试失败
3、assertTrue(boolean condition)
验证contidion的值是true
4、assertFalse(boolean condition)
验证contidion的值是false
5、assertNull(Object obj)
验证obj的值是null
6、assertNotNull(Object obj)
验证obj的值不是null
7、assertSame(expected, actual)
验证expected和actual是同一个对象,即指向同一个对象
8、assertNotSame(expected, actual)
验证expected和actual不是同一个对象,即指向不同的对象
9、fail()
让测试方法失败
注意:上面的每一个方法,都有一个重载的方法,可以在前面加一个String类型的参数,表示如果验证失败的话,将用这个字符串作为失败的结果报告。
比如:
assertEquals("Current user Id should be 1", 1, currentUser.id());
当currentUser.id()的值不是1的时候,在结果报道里面将显示"Current user Id should be 1",这样可以让测试结果更具有可读性,更清楚错误的原因是什么。
比较有意思的是最后一个方法,fail(),你或许会好奇,这个有什么用呢?其实这个在很多情况下还是有用的。你可以验证你的测试代码真的是跑了的。
在Android中利用单元测试。
现在的Android开发又了Android studio变得便捷了许多,简单的单元测试已经集成好了,在新建mudule的时候在src/java下会看到androidTest、main和test包。
1、在main下创建一个类:Calculator
public class Calculator {
public int add(int a, int b){
return a + b;
}
}
2、在androidTest包下新建一个CalculatorTest:
public class CalculatorTest {
private Calculator mCalculator;
@Before
public void setup(){
mCalculator = new Calculator();
}
@Test
public void testAdd(){
int add = mCalculator.add(1, 11);
Assert.assertEquals(12, add);
}
}
3、点击运行
Paste_Image.png4、在控制台查看结果
Paste_Image.png绿色表示成功了,红色表示就是错误。
这就是简单的单元测试。
网友评论