软件设计程序基础-Junit入门篇

本文介绍了Junit的基本概念,如编写原则、特征和框架构成,展示了如何使用Junit编写测试用例,包括使用@Test注解、断言方法和时间限制。内容涵盖了编写测试函数testSub(),以及如何设置超时测试以防执行过长。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

第1关:第一个Junit测试程序

  • 任务要求
  • 参考答案
  • 评论

任务描述

请学员写一个名为testSub()的测试函数,来测试给定的减法函数是否正确。

相关知识
Junit编写原则

1、简化测试的编写,这种简化包括测试框架的学习和实际测试单元的编写。 2、测试单元保持持久性。 3、利用既有的测试来编写相关的测试。

Junit特征

1、使用断言方法判断期望值和实际值差异,返回Boolean值。 2、测试驱动设备使用共同的初始化变量或者实例。 3、测试包结构便于组织和集成运行。 4、支持图形交互模式和文本交互模式。

Junit框架的组成

1、测试用例(TestCase):对测试目标进行测试的方法与过程的集合 2、测试包(TestSuite):测试用例的集合,可容纳多个测试用例(TestCase)。 3、测试结果(TestResult):测试结果的描述与记录。 4、测试监听(TestListener):测试过程中事件的监听者。 5、测试失败元素(TestFailure):每一个测试方法所发生的与预期不一致状况的描述。 6、测试框架出错异常(AssertionFailedError):junit执行测试时所抛出的异常。

Junit作用介绍

  通常我们写完代码想要测试这段代码的正确性,那么必须新建一个类,然后创建一个 main() 方法,之后再编写测试代码。如果需要测试的代码很多呢?那么要么就会建很多main() 方法来测试,要么将其全部写在一个main()方法里面。这也会大大的增加测试的复杂度,降低程序员的测试积极性。而 Junit 能很好的解决这个问题,简化单元测试,写一点测一点,在之后的代码改动中如果发现问题可以较快的追踪到问题的原因,减小回归错误的纠错难度。

如何编写Junit测试

首先,我们将介绍一个测试类:Calculate.java

 
  1. //Calculate.java
  2. package com.trustie.junitest;
  3. public class Calculate {
  4. public int sum(int var1, int var2) {
  5. return var1 + var2;
  6. }
  7. }

  在上面的代码中,我们可以看到,Calculate类有一个公共的方法sum(), 它接收输入两个整数,将它们相加并返回结果。在这里,我们将测试这个方法。为了这个目的,我们将创建另一个类及其方法,将测试之前的类(在此情况下,我们只有一个方法进行测试)中的方法,这是使用的最常见的方式。当然,如果一个方法非常复杂且要扩展,我们可以用多个试验方法来对其进行测试。创建测试用例的详细信息将显示在下面的部分。下面,有一个类是:CalculateTest.java,它具有我们的测试类的角色的代码:

 
  1. //CalculateTest.java
  2. package com.trustie.test;
  3. import org.junit.Test;
  4. import static org.junit.Assert.assertEquals;
  5. import com.trustie.junitest.Calculate;
  6. public class CalculateTest {
  7. Calculate calculation = new Calculate();
  8. int sum = calculation.sum(2, 5);
  9. int testSum = 7;
  10. @Test
  11. public void testSum() {
  12. assertEquals(sum, testSum);
  13. }
  14. }

先来解释一下上面的代码。首先,我们可以看到,有一个@Test的注解在 testSum()方法的上方。 这个注释指示该方法它所附着的代码可以做为一个测试用例。因此,testSum()方法将用于测试公开方法 sum() 。 我们再观察一个方法 assertEquals(sum, testsum)assertEquals ([String message], object expected, object actual) 方法持有两个对象作为输入,并断言这两个对象相等。

然后在Bash执行:

 
  1. javac -d . Calculate.java
  2. javac -d . CalculateTest.java
  3. java org.junit.runner.JUnitCore com.trustie.test.CalculateTest

就可以看到:

 
  1. JUnit version 4.12
  2. .
  3. Time: 0.003
  4. OK (1 test)

这里首先打印出了JUnit版本号,然后输出了耗时和测试结果。在这里,我们的测试结果是OK,证明测试通过,原函数功能正确。

编程要求

本关的编程任务是在JunitSubTest.java中的补全测试函数testSub(),具体要求:用subtestSub作为参数,来验证JunitSub.javasub函数是否正确的是否正确。

本关涉及的代码文件JunitSub.java的代码如下:

 
  1. package step1;
  2. public class JunitSub {
  3. public int sub(int var1, int var2) {
  4. return var1 - var2;
  5. }
  6. }

本关涉及的代码文件JunitSubTest.java的代码如下:

 
  1. package step1;
  2. import org.junit.Test;
  3. import static org.junit.Assert.assertEquals;
  4. import step1.JunitSub;
  5. public class JunitSubTest {
  6. //引入JunitSub对象
  7. JunitSub js = new JunitSub();
  8. int sub = js.sub(5,2);
  9. int testSub = 3;
  10. /*
  11. 请在下面的Begin/End内写一个测试函数,
  12. 来验证JunitSub中的sub函数编写是否正确
  13. */
  14. /***********************Begin**************************/
  15. /************************End***************************/
  16. }
评测说明

本关卡的测试文件是TestRunner.java,该文件进行了函数封装且学员不可见,用于验证学员的Junit测试代码是否正确。

具体测试过程如下:

1.平台自动编译生成TestRunner.exe; 2.平台运行TestRunner.exe; 3.获取TestRunner.exe输出,并将其输出与预期输出对比:如果一致则测试通过,否则测试失败。

预期输入: 预期输出:true

友情提示

1.请不要直接println最终输出,否则平台发现此类情况后,将一律扣掉本关经验值,并且追加处罚措施。

2.学员答题时请尽量手敲代码,请勿从实训讲解代码片段中复制代码段粘贴到答题区域作答,复制的内容会保留一些格式和字符,导致编译失败。

开始你的任务吧,祝你成功!

package step1;
 
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import step1.JunitSub;
 
public class JunitSubTest {
     //引入JunitSub对象
     JunitSub js = new JunitSub();
     int sub = js.sub(5,2);
     int testSub = 3;
 
     /*
     请在下面的Begin/End内写一个测试函数,
     来验证JunitSub中的sub函数编写是否正确
     */
     /***********************Begin**************************/
 
     @Test
     public void testSubFunction() {
          assertEquals(testSub, sub);
     }
     /************************End***************************/
 
}

第2关:Junit注解

  • 任务要求
  • 参考答案
  • 评论

任务描述

给出一个带有注解的Junit代码及其代码打印输出,要求学员修改注解位置,让输出结果变为逆序。

相关知识
Junit注解

Java注解((Annotation)的使用方法是"@ + 注解名" 。借助注解,我们可以在编程中通过简单的注解来实现一些功能。在junit中常用的注解有 @Test、@Ignore、@BeforeClass、@AfterClass、@Before、@After 下表列出了这些注释的概括:

具体解释如下:

1、@Test,表明此方法为测试方法。

2、@Before,用此注解修饰的方法在每个test方法运行前执行

3、@BeforeClass,用此注解修饰的方法将在所有方法运行前被执行,是一个static方法,只执行一次。

4、@After,用此注解修饰的方法在每个test方法运行后执行

5、@AfterClass,用此注解修饰的方法将在所有方法运行后被执行,也是一个static方法,只执行一次。

6、@Ignore,用此注解修饰的方法会被Junit忽略。

代码示例

这里新建一个JunitAnnotation.java,把上面所讲的注解全部加到某个测试函数之前,这些注解的作用一目了然:

 
  1. package com.trustie.junittest;
  2. import static org.junit.Assert.*;
  3. import java.util.*;
  4. import org.junit.*;
  5. public class AnnotationsTest {
  6. private ArrayList testList;
  7. @BeforeClass
  8. public static void onceExecutedBeforeAll() {
  9. System.out.println("@BeforeClass: onceExecutedBeforeAll");
  10. }
  11. @Before
  12. public void executedBeforeEach() {
  13. testList = new ArrayList();
  14. System.out.println("@Before: executedBeforeEach");
  15. }
  16. @AfterClass
  17. public static void onceExecutedAfterAll() {
  18. System.out.println("@AfterClass: onceExecutedAfterAll");
  19. }
  20. @After
  21. public void executedAfterEach() {
  22. testList.clear();
  23. System.out.println("@After: executedAfterEach");
  24. }
  25. @Test
  26. public void EmptyCollection() {
  27. assertTrue(testList.isEmpty());
  28. System.out.println("@Test: EmptyArrayList");
  29. }
  30. @Test
  31. public void OneItemCollection() {
  32. testList.add("oneItem");
  33. assertEquals(1, testList.size());
  34. System.out.println("@Test: OneItemArrayList");
  35. }
  36. @Ignore
  37. public void executionIgnored() {
  38. System.out.println("@Ignore: This execution is ignored");
  39. }
  40. }

如果我们运行上面的测试,控制台输出将是下面:

 
  1. @BeforeClass: onceExecutedBeforeAll
  2. @Before: executedBeforeEach
  3. @Test: EmptyArrayList
  4. @After: executedAfterEach
  5. @Before: executedBeforeEach
  6. @Test: OneItemArrayList
  7. @After: executedAfterEach
  8. @AfterClass: onceExecutedAfterAll
编程要求

本关的编程任务是在JunitAnnotation.java中修改测试函数对应的注解,使得原代码输出结果变为逆序。

本关涉及的代码文件JunitAnnotation.java的代码如下:

 
  1. package step2;
  2. import org.junit.After;
  3. import org.junit.AfterClass;
  4. import org.junit.Before;
  5. import org.junit.BeforeClass;
  6. import org.junit.Ignore;
  7. import org.junit.Test;
  8. public class JunitAnnotation {
  9. /*
  10. *以下Junit测试程序的输出结果为:
  11. *in before class
  12. *in before
  13. *in test
  14. *in after
  15. *in after class
  16. *请修改下面Begin/End内各个测试函数的注解,使输出结果逆序
  17. */
  18. /***********************Begin**************************/
  19. //execute before class
  20. @BeforeClass
  21. public static void beforeClass() {
  22. System.out.println("in before class");
  23. }
  24. //execute after class
  25. @AfterClass
  26. public static void afterClass() {
  27. System.out.println("in after class");
  28. }
  29. //execute before test
  30. @Before
  31. public void before() {
  32. System.out.println("in before");
  33. }
  34. //execute after test
  35. @After
  36. public void after() {
  37. System.out.println("in after");
  38. }
  39. //test case
  40. @Test
  41. public void test() {
  42. System.out.println("in test");
  43. }
  44. /************************End***************************/
  45. }
评测说明

本关卡的测试文件是TestRunner.java,该文件进行了函数封装且学员不可见,用于验证学员的Junit测试代码是否正确。

具体测试过程如下:

1.平台自动编译生成TestRunner.exe; 2.平台运行TestRunner.exe; 3.获取TestRunner.exe输出,并将其输出与预期输出对比:如果一致则测试通过,否则测试失败。

预期输入: 预期输出:

 
  1. in after class
  2. in after
  3. in test
  4. in before
  5. in before class
  6. true

友情提示

1.请不要直接println最终输出,否则平台发现此类情况后,将一律扣掉本关经验值,并且追加处罚措施。

2.学员答题时请尽量手敲代码,请勿从实训讲解代码片段中复制代码段粘贴到答题区域作答,复制的内容会保留一些格式和字符,导致编译失败。

开始你的任务吧,祝你成功!

package step2;
 
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
 
public class JunitAnnotation {
    /*
     *以下Junit测试程序的输出结果为:
     *in before class
     *in before
     *in test
     *in after
     *in after class
     *请修改下面Begin/End内各个测试函数的注解,使输出结果逆序
     */
     /***********************Begin**************************/
 
  
   @BeforeClass
   public static void afterClass() {
      System.out.println("in after class");
   }
 
   //execute after test
   
   @Before
   public void after() {
      System.out.println("in after");
   }
 
   //execute before test
   @After
   public void before() {
      System.out.println("in before");
   }
 
   //execute after class
   @AfterClass
   public static void beforeClass() {
      System.out.println("in before class");
   }
 
   //test case
   @Test
   public void test() {
      System.out.println("in test");
   }
 
   //execute before class
   
    /************************End***************************/
}

 

第3关:Junit断言

  • 任务要求
  • 参考答案
  • 评论

任务描述

给定一个断言测试类AssertionsTest.java,请按要求补全代码,写出相应的断言测试。

相关知识
Junit断言

Junit的断言方法允许检查测试方法的期望结果值和真实返回值。Junit的org.junit.Assert类提供了各种断言方法来写junit测试,这些方法被用来检查方法的真实结果值和期望值。

代码示例

创建一个文件名为 TestAssertions.java 的类,如下:

 
  1. package com.trustie.junittest;
  2. import org.junit.Test;
  3. import static org.junit.Assert.*;
  4. public class TestAssertions {
  5. @Test
  6. public void testAssertions() {
  7. //test data
  8. String str1 = new String ("abc");
  9. String str2 = new String ("abc");
  10. String str3 = null;
  11. String str4 = "abc";
  12. String str5 = "abc";
  13. int val1 = 5;
  14. int val2 = 6;
  15. String[] expectedArray = {"one", "two", "three"};
  16. String[] resultArray = {"one", "two", "three"};
  17. //Check that two objects are equal
  18. assertEquals(str1, str2);
  19. //Check that a condition is true
  20. assertTrue (val1 < val2);
  21. //Check that a condition is false
  22. assertFalse(val1 > val2);
  23. //Check that an object isn't null
  24. assertNotNull(str1);
  25. //Check that an object is null
  26. assertNull(str3);
  27. //Check if two object references point to the same object
  28. assertSame(str4,str5);
  29. //Check if two object references not point to the same object
  30. assertNotSame(str1,str3);
  31. //Check whether two arrays are equal to each other.
  32. assertArrayEquals(expectedArray, resultArray);
  33. }
  34. }

在以上类中我们可以看到,这些断言方法是可以工作的。

  • assertEquals() 如果比较的两个对象是相等的,此方法将正常返回;否则失败显示在JUnit的窗口测试将中止。

  • assertSame() 和 assertNotSame() 方法测试两个对象引用指向完全相同的对象。

  • assertNull() 和 assertNotNull() 方法测试一个变量是否为空或不为空(null)。

  • assertTrue() 和 assertFalse() 方法测试if条件或变量是true还是false。

  • assertArrayEquals() 将比较两个数组,如果它们相等,则该方法将继续进行不会发出错误。否则失败将显示在JUnit窗口和中止测试。

编程要求

本关的编程任务是给定一个断言测试类AssertionsTest.java,请按要求补全代码,写出相应的断言测试。

具体要求如下:

1.断言obj1和obj2相等; 2.断言obj3和obj4指向完全相同的对象; 3.断言obj2和obj4指向不同的对象; 4.断言obj1对象不为空; 5.断言obj5对象为空; 6.断言var1小于var2; 7.断言arithmetic1和arithmetic2两个数组相等。

本关涉及的代码文件AssertionsTest.java的代码如下:

 
  1. package step3;
  2. import static org.junit.Assert.*;
  3. import org.junit.Test;
  4. public class AssertionsTest {
  5. String obj1 = "junit";
  6. String obj2 = "junit";
  7. String obj3 = "test";
  8. String obj4 = "test";
  9. String obj5 = null;
  10. int var1 = 1;
  11. int var2 = 2;
  12. int[] arithmetic1 = { 1, 2, 3 };
  13. int[] arithmetic2 = { 1, 2, 3 };
  14. @Test
  15. public void test() {
  16. //请在下面的Begin/End内写添加断言测试的代码,不要改动其他地方的代码
  17. /***********************Begin**************************/
  18. /************************End***************************/
  19. }
  20. }
评测说明

本关卡的测试文件是TestRunner.java,该文件进行了函数封装且学员不可见,用于验证学员的Junit测试代码是否正确。

具体测试过程如下:

1.平台自动编译生成TestRunner.exe; 2.平台运行TestRunner.exe; 3.获取TestRunner.exe输出,并将其输出与预期输出对比:如果一致则测试通过,否则测试失败。

预期输入: 预期输出:true

友情提示

1.请不要直接println最终输出,否则平台发现此类情况后,将一律扣掉本关经验值,并且追加处罚措施。

2.学员答题时请尽量手敲代码,请勿从实训讲解代码片段中复制代码段粘贴到答题区域作答,复制的内容会保留一些格式和字符,导致编译失败。

开始你的任务吧,祝你成功!

package step3;
 
import static org.junit.Assert.*;
import org.junit.Test;
 
public class AssertionsTest {
    String obj1 = "junit";
    String obj2 = "junit";
    String obj3 = "test";
    String obj4 = "test";
    String obj5 = null;
    int var1 = 1;
    int var2 = 2;
    int[] arithmetic1 = { 1, 2, 3 };
    int[] arithmetic2 = { 1, 2, 3 };
 
    @Test
    public void test() {
        //请在下面的Begin/End内写添加断言测试的代码,不要改动其他地方的代码
        /***********************Begin**************************/
       
        assertEquals(obj1,obj2); // 判断两个字符串是否相等
        assertSame(obj3,obj4); // 判断两个对象引用是否指向同一个对象
        assertNotSame(obj2,obj4); // 判断两个对象引用是否不指向同一个对象
        assertNotNull(obj1); // 判断对象引用是否不为空
        assertNull(obj5); // 判断对象引用是否为空
        assertTrue (var1 < var2); // 判断一个整数是否小于另一个整数
        assertArrayEquals(arithmetic1,arithmetic2); // 判断两个数组是否相等
		/************************End***************************/
    }
}

第4关:Junit时间测试

  • 任务要求
  • 参考答案
  • 评论

任务描述

要求学员实现一个Junit时间测试:超过1000毫秒未执行结束就判定测试未通过。

相关知识
Junit时间测试

Junit 提供了一个暂停的方便选项。如果一个测试用例比起指定的毫秒数花费了更多的时间,那么Junit 将自动将它标记为失败。timeout 参数和@Test注释一起使用。现在让我们看看活动中的 @Test(timeout)

代码示例
 
  1. import org.junit.*;
  2. /**
  3. * JUnit TimeOut Test
  4. */
  5. public class JunitTest {
  6. @Test(timeout = 50000) //单位是毫秒
  7. public void infinity() {
  8. while (true);
  9. }
  10. }

在上面的例子中,infinity() 方法将不会返回,因此JUnit引擎将其标记为失败,并抛出一个异常。

java.lang.Exception:test timed out after 50000 milliseconds

编程要求

本关的编程任务是在TestTimeOut.java中实现一个Junit时间测试,超过1000毫秒未执行结束就判定测试未通过。

本关涉及的代码文件TestTimeOut.java的代码如下:

 
  1. package step4;
  2. import org.junit.Test;
  3. public class TestTimeOut {
  4. //请在下面的Begin/End内补全test()超时测试函数,要求如果超过1000毫秒执行未结束,就判定测试未通过
  5. /***********************Begin**************************/
  6. @Test()
  7. public void test() {
  8. while(true){}
  9. }
  10. /************************End***************************/
  11. }
评测说明

本关卡的测试文件是TestRunner.java,该文件进行了函数封装且学员不可见,用于验证学员的Junit测试代码是否正确。

具体测试过程如下:

1.平台自动编译生成TestRunner.exe; 2.平台运行TestRunner.exe; 3.获取TestRunner.exe输出,并将其输出与预期输出对比:如果一致则测试通过,否则测试失败。

预期输入: 预期输出:

 
  1. test(step4.TestTimeOut): test timed out after 1000 milliseconds
  2. false

友情提示

1.请不要直接println最终输出,否则平台发现此类情况后,将一律扣掉本关经验值,并且追加处罚措施。

2.学员答题时请尽量手敲代码,请勿从实训讲解代码片段中复制代码段粘贴到答题区域作答,复制的内容会保留一些格式和字符,导致编译失败。

开始你的任务吧,祝你成功!

package step4;
 
 
import org.junit.Test;
 
 
public class TestTimeOut {
 
     //请在下面的Begin/End内补全test()超时测试函数,要求如果超过1000毫秒执行未结束,就判定测试未通过
    /***********************Begin**************************/
    @Test(timeout = 1000)
    public void test() {
        while(true){}
    }
    /************************End***************************/
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值