跳转至

最后更新:2026-09-04 01:19

实验25 国赛备赛:单元测试(JUnit)

25.1 实验目的

  1. 熟悉 2023 全国职业院校技能大赛 GZ304 软件测试赛项"任务二 单元测试"的题型与要求;
  2. 掌握用 JUnit 框架编写测试类,设计最少的测试数据满足语句覆盖
  3. 掌握 JUnit 常用断言(startsWith、assertThat + equalTo、assertEquals)与参数化测试(@Parameters)
  4. 掌握单元测试报告(A4 模板)的编写。

25.2 实验环境

  1. 操作系统:Windows 10 / Windows 11;
  2. 工具:JDK + Eclipse(国赛指定)或 IntelliJ IDEA,JUnit 框架;
  3. 参考报告模板:A4-单元测试报告模板。

25.3 实验重难点

重点:语句覆盖的最小测试数据设计;JUnit 断言写法;参数化测试(@Parameters + 特殊运行器)。

难点:题目4 参数化测试的四个组成部分(变量声明与特殊运行器、@Parameters 公共静态方法、公共构造函数、测试方法);"最少测试数据满足语句覆盖"的设计思路。

25.4 实验内容

25.4.1 国赛"任务二 单元测试"概览

1. 任务描述 了解单元测试的评分点与报告要求。

2. 实验步骤

  • 步骤 1:任务分值:任务二单元测试共 10 分,每道题含"程序源代码 / 测试数据和测试方法代码 / JUnit Test 执行结果截图"三部分评分。

  • 步骤 2:报告要求:根据单元测试情况,参考 A4 模板,将 Java 源代码、测试类代码及截图粘贴到模板,完成单元测试报告。

  • 步骤 3:通用要求:

    • 每个题目用 JUnit 框架编写测试类;
    • 测试类中设计最少的测试数据满足语句覆盖
    • 每条测试数据需要在测试类中编写一个测试方法;
    • 使用指定断言判断期望与实际是否一致。

为什么要设计最少的测试数据?

语句覆盖只要求每行代码都被执行到一次。用最少的数据把所有分支走完,既满足评分要求,又不浪费时间——数据堆得多,不等于覆盖得好。

常见错误与排错

  • 报告三件套不齐:每题必须有"程序源代码 + 测试数据和测试方法代码 + JUnit Test 执行结果截图",缺一样就丢分。

25.4.2 题目1:根据流程图编写程序 + startsWith 断言

1. 任务描述 实现计算并返回 x 值的程序,用 JUnit 测试,断言用 startsWith。

2. 实验步骤

  • 步骤 1:题目要求:根据流程图编写程序实现相应分析处理并显示结果,返回文字与 x 值:

题目1程序流程图

图 25-1:题目1程序流程图
1
2
3
4
- 返回文字 "x=a*a*b的值:" 和 x 的值;
- 返回文字 "x=a-b的值:" 和 x 的值;
- 返回文字 "x=a+b的值:" 和 x 的值;
- 变量 a、b 均须为整型。
  • 步骤 2:编写程序代码(Java 方法实现)。

  • 步骤 3:编写测试类:设计最少的测试数据满足语句覆盖,每条测试数据写一个测试方法,使用 startsWith 判断期望返回文字和实际返回文字是否一致:

1
2
3
4
5
@Test
public void test01() {
    String result = demo.method(2, 3);
    Assert.assertTrue(result.startsWith("x=a*a*b的值:"));
}

startsWith 断言像什么?

startsWith 就像核对快递单号开头是不是"SF"——只检查返回文字的开头对不对,不必整个字符串逐字比对。

常见错误与排错

  • 返回文字必须一字不差(含中文冒号":"),如 x=a*a*b的值:
  • 流程图每条分支都要有测试数据走到,漏一条分支,语句覆盖就不达标。

25.4.3 题目2:根据年份月份判断天数 + assertThat 断言

1. 任务描述 实现月份天数判断程序,断言用 assertThat + equalTo。

2. 实验步骤

  • 步骤 1:题目要求:根据输入的年份和月份判断月份的天数:
  • 月份不在有效范围 → 提示"月份输入不正确。";
  • 月份不为 2 月 → 输出对应月份天数;
  • 月份为 2 月 → 根据年份判断:普通闰年 / 世纪闰年 / 非闰年,分别输出 2 月正确天数;
  • 返回格式:"year年month月份的天数是days天。";
  • 变量 year、month 均须为正整数。

  • 步骤 2:编写程序代码。

  • 步骤 3:编写测试类,设计最少数据满足语句覆盖,每条数据一个测试方法,使用 assertThat + equalTo

1
2
3
4
5
6
7
8
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;

@Test
public void test01() {
    String result = demo.getDays(2020, 2);
    assertThat(result, equalTo("2020年2月份的天数是29天。"));
}

为什么 2 月的天数要单独分支判断?

2 月是唯一"看年份脸色"的月份:普通闰年、世纪闰年、非闰年结果不同,程序必须单独立分支,测试数据也要把这几条分支全部覆盖到。

常见错误与排错

  • 期望字符串必须与返回格式一致:"year年month月份的天数是days天。",如 2020年2月份的天数是29天。
  • "月份输入不正确"(如 13 月)也是一条分支,别忘了设计对应测试数据。

25.4.4 题目3:邮箱注册校验 + assertThat 断言

1. 任务描述 实现邮箱地址与密码校验程序,断言用 assertThat + equalTo。

2. 实验步骤

  • 步骤 1:题目要求:邮箱注册填写邮箱地址和密码:
  • 邮箱格式"登录名@主机名.域名":登录名为 5 个字母,主机名固定为 163 或 126,域名为 com 或 com.cn;
  • 密码为 6 个(含 6)以上数字组成;
  • 填写正确提示"信息正确",否则提示"不符合要求"(为邮箱地址或密码)。

  • 步骤 2:编写程序代码。

  • 步骤 3:编写测试类,设计最少数据满足语句覆盖,每条数据一个测试方法,使用 assertThat + equalTo 判断输出文字期望值与实际返回值是否一致。

邮箱校验为什么要把格式拆成三段看?

登录名(5 个字母)、主机名(163/126)、域名(com/com.cn)各有各的规则,像核对快递地址要分别看省、市、门牌号——拆开检查,才能设计出覆盖全部分支的测试数据。

常见错误与排错

  • 别只测正确邮箱:位数不足的登录名、错误主机名、错误域名、不足 6 位的密码都要有测试数据覆盖;
  • 提示文字"**不符合要求"中的 ** 要替换成实际出错的邮箱地址或密码。

25.4.5 题目4:参数化测试(@Parameters)

1. 任务描述 用 JUnit 参数化测试完成测试,断言用 assertEquals。

2. 实验步骤

  • 步骤 1:题目要求:根据流程图编写程序,使用 JUnit 框架编写测试类,测试类使用参数化测试(@Parameters)完成测试,使用 assertEquals 判断输入数据测试方法期望结果值和实际返回值是否一致。

  • 步骤 2:参数化测试类的四个组成部分

  • 测试类变量声明以及特殊运行器代码:声明测试数据和期望结果变量,指定特殊运行器 @RunWith(Parameterized.class)
  • 初始化测试数据的公共静态方法代码:由 @Parameters 注释的公共静态方法,初始化需要测试的数据;
  • 公共的构造函数部分代码:测试类中公共的构造函数;
  • 测试类中测试方法代码:包含断言等。

  • 步骤 3:结构示例:

@RunWith(Parameterized.class)
public class TestDemo {
    private int a;   // 输入
    private int b;
    private int expected;  // 期望结果

    // @Parameters 公共静态方法初始化测试数据
    @Parameters
    public static Collection<Object[]> data() {
        return Arrays.asList(new Object[][] {
            {1, 2, 3},
            {3, 1, 2},
            {2, 5, 10}
        });
    }

    // 公共构造函数
    public TestDemo(int a, int b, int expected) {
        this.a = a; this.b = b; this.expected = expected;
    }

    // 测试方法,含断言
    @Test
    public void testCalc() {
        assertEquals(expected, demo.calc(a, b));
    }
}
  • 步骤 4:运行测试,查看 JUnit Test 执行结果。

参数化测试为什么必须配特殊运行器?

普通 JUnit 不认识 @Parameters 里的数据表。@RunWith(Parameterized.class) 就像指定"按表格逐行喂数据"的送餐员——没有它,表格再全也送不进测试方法。

常见错误与排错

  • 四个组成部分缺一不可:漏掉构造函数或 @Parameters 方法,运行直接报错;
  • 数据数组 {输入, 期望结果} 的顺序要与构造函数参数一一对应,写反了断言全错。

25.4.6 编写单元测试报告(A4 模板)

1. 任务描述 按 A4 模板完成单元测试报告。

2. 实验步骤

  • 步骤 1:按题目 1~4 分别填写:
  • 程序源代码:粘贴 Java 程序代码;
  • 测试数据和测试方法代码:粘贴测试类中每条数据的测试方法(含数据、断言等);
  • JUnit Test 执行结果截图:截取 JUnit Test 执行结果。

  • 步骤 2:题目4 额外填写四个部分:测试类变量声明以及特殊运行器代码 / 初始化测试数据的公共静态方法代码 / 公共的构造函数部分代码 / 测试类中测试方法代码。

常见错误与排错

  • 题目4 别只贴截图:报告里要单独写出参数化测试四个部分的代码,漏写即扣分。

25.5 实验总结

本次实验完成了国赛"任务二 单元测试"的备赛训练:掌握四道典型题(流程图程序 + startsWith、月份天数 + assertThat/equalTo、邮箱校验 + assertThat/equalTo、参数化测试 + assertEquals),核心是"设计最少测试数据满足语句覆盖"与"每条数据一个测试方法"的规范,以及参数化测试(@RunWith(Parameterized.class) + @Parameters + 构造函数 + 测试方法)的写法,并按 A4 模板完成报告。单元测试分值为 10 分,是拿分最稳的环节之一。

25.6 作业提交

  1. 提交地点:吾爱作业网
  2. 提交资料:
  3. 题目1~3 程序源代码与测试类截图、JUnit Test 执行结果截图;
  4. 题目4 参数化测试四个部分代码截图。
  5. 不会做时填写"心得感悟"(1~50 字)。

25.7 知识检测

  • [ ] (填空)国赛"任务二 单元测试"共 10 分,每道题含"程序源代码 / 测试数据和测试方法代码 / JUnit Test 执行结果截图"三部分评分。
  • [ ] (填空)单元测试设计测试数据的核心要求:用最少的测试数据满足语句覆盖,每条测试数据编写一个测试方法。
  • [ ] (选择)判断返回文字是否以指定内容开头的断言是( )。
  • A. assertEquals B. assertTrue(result.startsWith("...")) C. assertNull D. fail()
查看解析

正确答案:B。题目1 要求使用 startsWith 判断期望返回文字和实际返回文字是否一致。

  • [ ] (选择)参数化测试的四个组成部分不包括( )。
  • A. 变量声明以及特殊运行器 B. @Parameters 公共静态方法 C. 公共构造函数 D. CSV 数据文件
查看解析

正确答案:D。四部分为变量声明与特殊运行器、@Parameters 公共静态方法、公共构造函数、测试方法;CSV 数据文件属于自动化测试的数据驱动。

  • [ ] (填空)参数化测试类必须在类上标注 @RunWith(Parameterized.class),并用 @Parameters 注解公共静态方法初始化测试数据。

本课相关资源

序号 资源名称 类型 说明
1 新建 DOCX 文档.docx 任务文档 四道题目要求
2 A4-单元测试报告模板.docx 报告模板 报告结构
3 评分标准.docx 评分标准 任务二评分细则

实验素材下载

点击下方链接获取本节课全部资源(含课件、任务清单、安装包等): 🔗 夸克网盘

本站总访问 次 | 访客 人 | 本页阅读