软件测试复习之单元测试

发布于:2025-07-03 ⋅ 阅读:(20) ⋅ 点赞:(0)

一、单元测试基础概念

在这里插入图片描述

1. 定义与核心目标

  • 定义:对软件中的最小可测试单元(如函数、类方法)进行正确性验证的测试活动。
  • 核心目标:确保单元功能符合设计要求,发现代码逻辑错误、边界条件缺陷等。

2. 单元划分原则(作业手册单元4简答题)

  • 划分依据
    • 程序模块的独立性(如单个函数、类的方法)。
    • 详细设计说明书中的模块划分。
  • 示例
    • 函数int add(int a, int b)可作为一个单元。
    • Calculator中的sqrt(double x)方法可独立测试。

3. 单元测试与其他测试阶段的区别

测试阶段 测试对象 测试方法 实施者
单元测试 单个模块 白盒测试为主 开发人员
集成测试 模块间接口 灰盒测试 测试工程师
系统测试 完整系统 黑盒测试 测试团队

二、单元测试实施基础

1. 测试依据与准备

  • 依据文档
    • 详细设计说明书(模块功能规格说明)。
    • 源代码清单(模块逻辑结构)。
  • 测试环境
    • 单元测试框架(如JUnit)、测试驱动程序(模拟调用单元的代码)。

2. 单元测试主要任务(作业手册单元4简答题)

  1. 模块接口测试:验证输入/输出参数的正确性(如参数类型、数量、顺序)。
  2. 局部数据结构测试:检查变量初始化、赋值、作用域是否正确。
  3. 边界条件测试:测试模块在边界值(如数组越界、空值)下的处理。
  4. 独立路径测试:覆盖模块内的所有逻辑路径(结合白盒覆盖法)。
  5. 错误处理测试:验证异常情况(如输入非法数据)的处理逻辑。

3. 单元测试目标(作业手册单元4简答题)

  • 确保模块功能正确实现,符合设计规格。
  • 发现模块内的编码错误、逻辑缺陷和边界问题。
  • 为后续集成测试提供可靠的单元模块。

三、JUnit框架核心技术(重点实践)

模块1:JUnit基础组件

1. 核心注解与类
  • @Test:标注测试方法,表明该方法为一个测试用例。
  • Assert类:包含断言方法(如assertEqualsassertThat),用于验证实际结果与预期结果。
  • TestCase类:测试类的基类,提供测试环境初始化(setUp)和清理(tearDown)方法。
2. 测试流程方法
  • setUp():在每个测试方法执行前初始化资源(如创建被测对象)。
  • tearDown():在每个测试方法执行后释放资源(如关闭连接)。
  • 示例
    public class CalculatorTest {
        private Calculator calculator;
        
        @Before
        public void setUp() {
            calculator = new Calculator();
        }
        
        @Test
        public void testAdd() {
            assertEquals(5, calculator.add(2, 3));
        }
        
        @After
        public void tearDown() {
            calculator = null;
        }
    }
    

模块2:断言与测试用例设计

1. 常用断言方法
  • assertEquals(expected, actual):验证两值相等(适用于基本类型和对象)。
  • assertThat(actual, matcher):结合匹配器(如startsWithcontainsString)验证复杂逻辑。
  • 示例(作业手册单元4操作题):
    @Test
    public void testLogin() {
        String result = userService.login("abc123", "123456");
        assertThat(result, startsWith("登录成功"));
    }
    
2. 基于逻辑覆盖的测试用例设计
  • 判定覆盖:覆盖模块内所有判定的真假分支(如ifwhile的真假情况)。
  • 示例(考试.docx第三单元代码):
    // 被测方法
    public String tst(int x, int y) {
        if(x>60 && y<35) {
            // j1路径
        } else if(x==25 && y>50) {
            // j3路径
        } else {
            // j2路径
        }
    }
    
    // 测试用例(判定覆盖):
    @Test public void testJ1Path() { tst(61, 34); }  // 覆盖x>60&&y<35为真
    @Test public void testJ3Path() { tst(25, 60); }  // 覆盖x==25&&y>50为真
    @Test public void testJ2Path() { tst(60, 35); }  // 覆盖两个条件均为假
    

四、单元测试综合实践(必考题型)

1. 单元测试步骤(作业手册单元4简答题)

  1. 分析模块规格:明确模块功能、输入输出、边界条件。
  2. 设计测试用例:基于白盒覆盖法(如判定覆盖、路径覆盖)设计用例。
  3. 编写测试代码:使用JUnit框架编写测试类,调用被测模块。
  4. 执行测试:运行测试用例,记录结果。
  5. 分析结果:对比预期与实际结果,追踪缺陷。

2. 参数化测试(@Parameters)

应用场景
  • 同一测试逻辑需要多组数据输入时(如不同边界值测试)。
示例(考试.docx题目4):
@RunWith(Parameterized.class)
public class StringProcessorTest {
    private StringProcessor processor = new StringProcessor();
    private String input;
    private String expected;
    
    @Parameters
    public static Collection<Object[]> testData() {
        return Arrays.asList(new Object[][] {
            {"abfdf", "替换前缀后的字符串为:effdf"},  // 前缀ab
            {"cdsddscd", "替换cd后的字符串为:ghsddsgh"},  // 后缀cd
            {"dfdsdf", "大写字母的字符串为:DFDSDF"}  // 其他情况
        });
    }
    
    public StringProcessorTest(String input, String expected) {
        this.input = input;
        this.expected = expected;
    }
    
    @Test
    public void testProcess() {
        assertEquals(expected, processor.process(input));
    }
}

3. 单元测试与白盒覆盖结合

例题:三角形判断模块(考试.docx题目2)
// 被测方法:判断三边能否组成三角形并分类
public String test(int a, int b, int c) {
    if (a<=0 || b<=0 || c<=0 || a>10 || b>10 || c>10) {
        return "输入边值不在范围内";
    }
    if (a+b<=c || b+c<=a || a+c<=b) {
        return "输入边值不能组成三角形";
    }
    if (a==b && b==c) {
        return "能组成等边三角形";
    } else if (a==b || b==c || a==c) {
        return "能组成等腰三角形";
    } else {
        return "能组成普通三角形";
    }
}
测试用例设计(判定覆盖):
  1. 输入边值不在范围内:a=0, b=1, c=1 → 预期结果“输入边值不在范围内”。
  2. 不能组成三角形:a=1, b=5, c=1 → 预期结果“输入边值不能组成三角形”。
  3. 等边三角形:a=3, b=3, c=3 → 预期结果“能组成等边三角形”。
  4. 等腰三角形:a=3, b=3, c=5 → 预期结果“能组成等腰三角形”。
  5. 普通三角形:a=4, b=2, c=5 → 预期结果“能组成普通三角形”。