Espresso 测试框架 - JUnit概述



本章我们将了解JUnit的基础知识,这是一个由Java社区开发的流行单元测试框架,Espresso测试框架就是基于它构建的。

JUnit是Java应用程序单元测试的实际标准。尽管它流行于单元测试,但它也完全支持和提供仪表测试。Espresso测试库扩展了必要的JUnit类以支持基于Android的仪表测试。

编写简单的单元测试

让我们创建一个Java类,Computation (Computation.java),并编写简单的数学运算,SummationMultiplication。然后,我们将使用JUnit编写测试用例,并通过运行测试用例来检查它。

  • 启动Android Studio。

  • 打开上一章中创建的HelloWorldApp

  • app/src/main/java/com/tutorialspoint/espressosamples/helloworldapp/中创建一个文件,Computation.java,并编写两个函数 - SumMultiply,如下所示:

package com.tutorialspoint.espressosamples.helloworldapp;
public class Computation {
   public Computation() {}
   public int Sum(int a, int b) {
      return a + b;
   }
   public int Multiply(int a, int b) {
      return a * b;
   }
}
  • 在app/src/test/java/com/tutorialspoint/espressosamples/helloworldapp中创建一个文件,ComputationUnitTest.java,并编写单元测试用例来测试Sum和Multiply功能,如下所示:

package com.tutorialspoint.espressosamples.helloworldapp;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class ComputationUnitTest {
   @Test
   public void sum_isCorrect() {
      Computation computation = new Computation();
      assertEquals(4, computation.Sum(2,2));
   }
   @Test
   public void multiply_isCorrect() {
      Computation computation = new Computation();
      assertEquals(4, computation.Multiply(2,2));
   }
}

这里,我们使用了两个新术语 - @TestassertEquals。一般来说,JUnit使用Java注解来识别类中的测试用例以及如何执行测试用例的信息。@Test是一种这样的Java注解,它指定特定函数是JUnit测试用例。assertEquals是一个函数,用于断言第一个参数(预期值)和第二个参数(计算值)相等。JUnit为不同的测试场景提供许多断言方法。

  • 现在,通过右键单击该类并调用“运行'ComputationUnitTest'”选项(如上一章所述),在Android Studio中运行ComputationUnitTest。这将运行单元测试用例并报告成功。

计算单元测试的结果如下所示:

Computation Unit Test

注解

JUnit框架广泛使用注解。一些重要的注解如下:

  • @Test

  • @Before

  • @After

  • @BeforeClass

  • @AfterClass

  • @Rule

@Test注解

@TestJUnit框架中非常重要的注解。@Test用于区分普通方法和测试用例方法。一旦用@Test注解修饰了一个方法,那么该方法就被认为是一个测试用例,并将由JUnit Runner运行。JUnit Runner是一个特殊的类,用于查找和运行Java类中可用的JUnit测试用例。目前,我们使用Android Studio的内置选项来运行单元测试(这反过来又运行JUnit Runner)。示例代码如下:

package com.tutorialspoint.espressosamples.helloworldapp;
import org.junit.Test;
import static org.junit.Assert.assertEquals;

public class ComputationUnitTest {
   @Test
   public void multiply_isCorrect() {
      Computation computation = new Computation();
      assertEquals(4, computation.Multiply(2,2));
   }
}

@Before

@Before注解用于引用一个方法,该方法需要在运行特定测试类中可用的任何测试方法之前调用。例如,在我们的示例中,可以在单独的方法中创建Computation对象并用@Before注解,以便它将在sum_isCorrectmultiply_isCorrect测试用例之前运行。完整代码如下:

package com.tutorialspoint.espressosamples.helloworldapp;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.assertEquals;

public class ComputationUnitTest {
   Computation computation = null;
   @Before
   public void CreateComputationObject() {
      this.computation = new Computation();
   }
   @Test
   public void sum_isCorrect() {
      assertEquals(4, this.computation.Sum(2,2));
   }
   @Test
   public void multiply_isCorrect() {
      assertEquals(4, this.computation.Multiply(2,2));
   }
}

@After

@After类似于@Before,但是用@After注解的方法将在每个测试用例运行后被调用或执行。示例代码如下:

package com.tutorialspoint.espressosamples.helloworldapp;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.assertEquals;

public class ComputationUnitTest {
   Computation computation = null;
   @Before
   public void CreateComputationObject() {
      this.computation = new Computation();
   }
   @After
   public void DestroyComputationObject() {
      this.computation = null;
   }
   @Test
   public void sum_isCorrect() {
      assertEquals(4, this.computation.Sum(2,2));
   }
   @Test
   public void multiply_isCorrect() {
      assertEquals(4, this.computation.Multiply(2,2));
   }
}

@BeforeClass

@BeforeClass类似于@Before,但是用@BeforeClass注解的方法只会在运行特定类中的所有测试用例之前调用或执行一次。它对于创建数据库连接对象等资源密集型对象很有用。这将减少执行一系列测试用例的时间。为了正常工作,此方法需要是静态的。在我们的示例中,我们可以在运行所有测试用例之前创建一次计算对象,如下所示:

package com.tutorialspoint.espressosamples.helloworldapp;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.assertEquals;

public class ComputationUnitTest {
   private static Computation computation = null;
   @BeforeClass
   public static void CreateComputationObject() {
      computation = new Computation();
   }
   @Test
   public void sum_isCorrect() {
      assertEquals(4, computation.Sum(2,2));
   }
   @Test
   public void multiply_isCorrect() {
      assertEquals(4, computation.Multiply(2,2));
   }
}

@AfterClass

@AfterClass类似于@BeforeClass,但是用@AfterClass注解的方法只会在运行特定类中的所有测试用例之后调用或执行一次。此方法也需要是静态的才能正常工作。示例代码如下:

package com.tutorialspoint.espressosamples.helloworldapp;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.assertEquals;

public class ComputationUnitTest {
   private static Computation computation = null;
   @BeforeClass
   public static void CreateComputationObject() {
      computation = new Computation();
   }
   @AfterClass
   public static void DestroyComputationObject() {
      computation = null;
   }
   @Test
   public void sum_isCorrect() {
      assertEquals(4, computation.Sum(2,2));
   }
   @Test
   public void multiply_isCorrect() {
      assertEquals(4, computation.Multiply(2,2));
   }
}

@Rule

@Rule注解是JUnit的亮点之一。它用于向测试用例添加行为。我们只能注解TestRule类型的字段。它实际上提供了@Before@After注解提供的功能集,但以一种高效且可重用的方式。例如,我们可能需要一个临时文件夹来在测试用例期间存储一些数据。通常,我们需要在运行测试用例之前创建一个临时文件夹(使用@Before@BeforeClass注解),并在测试用例运行后销毁它(使用@After@AfterClass注解)。相反,我们可以使用JUnit框架提供的TemporaryFolderTestRule类型)类为所有测试用例创建一个临时文件夹,并且将在运行测试用例时删除临时文件夹。我们需要创建一个新的TemporaryFolder类型变量,并用@Rule注解,如下所示:

package com.tutorialspoint.espressosamples.helloworldapp;

import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import java.io.File;
import java.io.IOException;
import static junit.framework.TestCase.assertTrue;
import static org.junit.Assert.assertEquals;

public class ComputationUnitTest {
   private static Computation computation = null;
   @Rule
   public TemporaryFolder folder = new TemporaryFolder();
   @Test
   public void file_isCreated() throws IOException {
      folder.newFolder("MyTestFolder");
      File testFile = folder.newFile("MyTestFile.txt");
      assertTrue(testFile.exists());
   }
   @BeforeClass
   public static void CreateComputationObject() {
      computation = new Computation();
   }
   @AfterClass
   public static void DestroyComputationObject() {
      computation = null;
   }
   @Test
   public void sum_isCorrect() {
      assertEquals(4, computation.Sum(2,2));
   }
   @Test
   public void multiply_isCorrect() {
      assertEquals(4, computation.Multiply(2,2));
   }
}

执行顺序

JUnit中,用不同注解注解的方法将按特定顺序执行,如下所示:

  • @BeforeClass

  • @Rule

  • @Before

  • @Test

  • @After

  • @AfterClass

断言

断言是检查测试用例的预期值是否与测试用例结果的实际值匹配的一种方式。JUnit为不同的场景提供断言;下面列出了一些重要的断言:

  • fail() - 显式地使测试用例失败。

  • assertTrue(boolean test_condition) - 检查test_condition是否为真

  • assertFalse(boolean test_condition) - 检查test_condition是否为假

  • assertEquals(expected, actual) - 检查两个值是否相等

  • assertNull(object) - 检查对象是否为null

  • assertNotNull(object) - 检查对象是否不为null

  • assertSame(expected, actual) - 检查两者是否引用同一个对象。

  • assertNotSame(expected, actual) - 检查两者是否引用不同的对象。

广告