相似还见面用到一个要多只单元测试框架。如果无用单元测试的语句量要如此形容测试代码了。

咱俩刻画单元测试,一般都见面就此到一个或者多单单元测试框架,在此处,我们介绍一下JUnit4此测试框架。这是Java界用的最为广,也是极其基础之一个框架,其他的不少框架,包括我们后面会盼底Robolectric,都是基于或兼容JUnit4的。
而是首先使缓解的题材是。。。

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);
    }

}

为何要下单元测试框架为

或者换句话说,单元测试框架能够为我们召开啊呢?
从今极度基本的起说自,假如我们有如此一个近似:

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 calculator = new Calculator();
        int sum = calculator.add(1, 2);
        if(sum == 3) {
            System.out.println("add() works!")
        } else {
            System.out.println("add() does not works!")
        }

        int product = calculator.multiply(2, 4);
        if (product == 8) {
            System.out.println("multiply() works!")
        } else {
            System.out.println("multiply() does not works!")
        }
    }
}

下一场我们再度通过某种方式,比如命令执行要IDE,运行是CalculatorTestmain道,在羁押在terminal的输出,才知测试是通过或者失败。想想一下,如果我们来很多底接近,每个接近都发生诸多艺术,那么就要写一堆这样的代码,每个接近对于一个含有main方法的test类,同时main方中会生出一样积聚代码。这样既写起来痛苦,跑起又痛苦,比如说,你什么一次性跑所有的测试类呢?所以,一个测试框架为我们开的极其核心的事务,就是允许我们循某种更简便的主意写测试代码,把各个一个测试单元写在一个测试方法里面,然后她会自行寻有富有的测试方法,并且根据你的用,运行具有的测试方法,或者是运行单个测试方法,或者是运作有测试方法等等。
对地方的Calculator事例,如果利用Junit的语,我们可按照如下的法门写测试代码:

public class CalculatorTest {

    @Test
    public void testAdd() throws Exception {
        Calculator calculator = new Calculator();
        int sum = calculator.add(1, 2);
        Assert.assertEquals(3, sum);
    }

    @Test
    public void testMultiply() throws Exception {
        Calculator calculator = new Calculator();
        int product = calculator.multiply(2, 4);
        Assert.assertEquals(8, product);
    }

}

列一个受测试的方(add(), multiply()),写一个对应的测试方法(testAdd(), testMultiply())。那JUnit怎么知道那些是测试方法,哪些不是也?这个是通过前的@Test诠释来表明的,只要出之注解,JUnit4就会作为是一个测试方法,方法名其实是足以无限制起底。当然,名字或者该由底双重起可读性一点,让丁一样看便清楚,这个测试方法是测试了给测的切近的死方式,或者是测试了很功能点等等。
除帮咱探寻有装有的测试方法,并且有利于运行意外,单元测试框架还拉扯咱做了外工作。在本条系列之首先首文章中我们关系,一个测试方法主要包括三独片:

  1. setup
  2. 实施操作
  3. 证明结果

而一个单元测试框架,可以让咱还有利之刻画点的各个一样步的代码,尤其是第一步和老三部。比如说,在面的CalculatorTest中,testAdd()testMultiply()且发平等的setup:
Calculator calculator = new Calculator();,如果Calculator尚产生外的章程吧,这行代码就得再更频繁,这种duplication是无必要之。绝大多数单元测试框架考虑到了就一点,它们理解一个测试类的多测试方法可能得平等的setup,所以也我们提供了便民方式。对于JUnit4,是透过@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修饰了了,那么当每个测试方法调用之前,这个法还见面博得调用。所以地方的例子中,testAdd()受运行前,setup()会面于调用一次等,把mCalculator实例化,接着运行testAdd()testMultiply()叫周转前,setup()还要见面被调用一次于,把mCalculator重复实例化,接着运行testMultiply()。如果还产生任何的测试方法,则盖此类推。
对应于@Before的,有一个@After,作用估计你吧猜得到,那即便是每个测试方法运行了以后,会赢得周转的法子。比如一个测试文件操作的好像,那么以其的测试接近吃,可能@Before其中待去开拓一个文件,而每个测试方法运行了之后,都急需去close这个文件。这个时段便可把文件close的操作放在@After内部,让她自动去实施。
类似的,还有@BeforeClass@AfterClass@BeforeClass的打算是,在飞一个测试类的备测试方法之前,会尽同一差受@BeforeClass修饰的方法,执行了所有测试方法之后,会履行同样尽被@AfterClass修饰的主意。这点儿独章程可就此来setup和release一些官的资源,需要注意的是,被立有限只annotation修饰的法必须是静态的。

前面说的是单元测试框架对于一个测试方法的首先步“setup”,为咱做的业务。而对于第三总理“验证结果”,则一般是通过有些assert方法来成功的。JUnit为咱提供的assert方法,多数且在Assert其一近乎中。最常用之那些如下:

assertEquals(expected, actual)
验证expected的值跟actual是一样的,如果是一样的话,测试通过,不然的话,测试失败。如果传入的凡object,那么这里的对立统一用之是equals()

assertEquals(expected, actual, tolerance)
此处流传的expected和actual是float或double类型的,大家了解计算机表示浮点型数据都产生自然之差,所以即使理论及他们是等的,但是用计算机表示出则可能无是,所以这边运行传入一个偏差值。如果简单只数的歧异在这偏差值之内,则测试通过,否者测试失败。

assertTrue(boolean condition)
验证contidion的值是true

assertFalse(boolean condition)
验证contidion的值是false

assertNull(Object obj)
验证obj的值是null

assertNotNull(Object obj)
验证obj的值不是null

assertSame(expected, actual)
验证expected和actual是和一个目标,即针对同一个靶

assertNotSame(expected, actual)
验证expected和actual不是与一个对象,即针对不同之目标

fail()
吃测试方法失败

专注:上面的各国一个法,都出一个重载的办法,可以于头里加一个String类型的参数,表示如果证实失败以来,将故这字符串作为黄的结果告知。
比如:
assertEquals("Current user Id should be 1", 1, currentUser.id());
currentUser.id()的价不是1底早晚,在结果报道里用显示”Current user
Id should be
1″,这样好让测试结果又有着可读性,更明亮错误的由是什么。
较有趣的凡最终一个法,fail(),你也许会奇怪,这个来啊用吧?其实是在广大场面下或管用之,比如最鲜明的一个意向就是是,你得证明你的测试代码真的是走了的。
除此以外,它还有另外一个第一作用,那便是证明某个被测试的方法会正确的扔来异常,不过这点好经下说到之不二法门,更便利之得,所以即使不讲话了。
顿时有相对来说还是特别好明的,不做了多讲。

@Before:

苟一个办法给@Before修饰过,那么以每个测试方法调用前,这个措施都见面博得调用。在testAdd()调用之前,setUp()会叫调用一不好。

JUnit的别样功能

@After:

每个测试方法运行了之后,会获周转的措施,比如关闭文件之操作等等。

Ignore一些测试方法

多时节,因为某些原因(比如正式代码还未曾落实等),我们或想为JUnit忽略某些方法,让它们以飞所有测试方法的当儿绝不走者测试方法。要高达这目的吗蛮简单,只需要在如受忽略的测试方法前面加上@Ignore就好了,如下:

public class CalculatorTest {
    Calculator mCalculator;

    @Before
    public void setup() {
        mCalculator = new Calculator();
    }

    // Omit testAdd() and testMultiply() for brevity

    @Test
    @Ignore("not implemented yet")
    public void testFactorial() {
    }
}

@BeforeClass:

每当飞一个测试类的装有测试方法之前,会尽同一潮受@BeforeClass修饰的措施。

说明方法会抛出某些老

有的上,抛来好是一个方对工作的一样部分。比如一个除法函数,当除数是0的下,它当抛出异常,告诉外界,传入的为除数是0,示例代码如下:

public class Calculator {

    // Omit testAdd() and testMultiply() for brevity

    public double divide(double divident, double dividor) {
        if (dividor == 0) throw new IllegalArgumentException("Dividor cannot be 0");

        return divident / dividor;
    }}

这就是说如何测试当传入的除数是0的时刻,这个法子应该抛出IllegalArgumentException异常呢?
以Junit中,可以透过给@Test
annotation传入一个expected参数来达成这目的,如下:

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);
    }

}

@Test(expected = IllegalArgumentException.class)意味着验证这个测试方法将抛出IllegalArgumentException特别,如果没抛弃来之讲话,则测试失败。

@AfterClass:

行完毕所有测试方法之后,会实行同样全被@AfterClass修饰的法子。
在意后少只点子修饰的点子要是静态的。

每当Android项目中用JUnit

于Android项目里面用JUnit是老简短的,你独自需要拿JUnit这个library加到公的dependencies里面。
testCompile 'junit:junit:4.12'
而你通过AndroidStudio创建一个路,这个dependency默认是丰富了的,所以你还就步都得以省略。
除此以外,你待拿测试代码放到src/test/java 目录下面。
联网下去关于什么运行测试代码,怎么样看结果,请参考这个系列的首先首稿子的有关部分,因为贪图于多,这边就未还了。
这里被大家看一下周转的结果是啊体统的,其中起一个受挫的测试用例是蓄意的。如果您一直当AndroidStudio里面跑者的测试类CalculatorTest的享有测试方法的说话,会看到如下的结果:

左手可以观看有的测试方法,以及每个方法跑出来的结果,绿色代表测试通过的测试方法,黄色的感叹号或红色的象征测试失败的。第三个老有条纹的球球表示于忽视的测试方法。
使是通过terminal跑的语句,则会盼如下的测试结果:

眼看首文章的相干代码可以于github的这个project看到。

@Ignore:

深受某些方法以测试的时光不需要跑,要达标这个目的就是于不经意测试的点子面前加上@Ignore就好了。

小结

随即首文字大概简单介绍了JUnit的施用,相对来说是比较简单,也是于好掌握的,希望能够帮到大家。其中Assert部分,可以协助咱作证一个术的回到结果。然而,这些只能帮助我们测试出返回值的那些方法。在第一首文章里我们谈了,一个好像的点子分点儿种,一凡产生返回值的主意,这些可通过我们今天言的JUnit来举行测试。而除此以外一种没有返回值的方,即void方法,则只要透过另外一个框架,Mockito,来说明其的正确性。至于怎么验证void方法的没错,以及Mockito的运用,请关注下同样首文章。

取最新篇章或纪念加盟安卓单元测试交流群,请关注人世公众号

呼救!!!我亲婶婶,肝移植需要30万,还不同10万横,求大家帮拉,求支持中转,有闲钱的语句求捐一点!感谢谢!!!

参考:
http://junit.org/junit4/
http://www.vogella.com/tutorials/JUnit/article.html

说明措施抛来特别:

按部就班吃除数是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、点击运行

图片 1

Paste_Image.png

4、在控制台查看结果

图片 2

Paste_Image.png

绿色代表成功了,红色代表虽是荒唐。

顿时便是简简单单的单元测试。

相关文章