边界值分析法测试用例设计实例

简介: 边界值分析法是黑盒测试的重要方法,本文以一道数位DP算法题为例,自主测试黑盒测试用例,并采用JUnit5完成单元测试。

软件测试

题目描述

原题链接:洛谷 P2602 [ZJOI2010] 数字计数

输入两个正整数a,b,求在[a,b]中的所有整数中,每个数码(0\~9)各出现了多少次。

输入格式:

输入两个正整数a, b确定区间[a,b](0<a<b<10^13)。

输出格式:

在一行中输出0\~9每个数码在[a,b]区间内共出现多少次,用空格隔开。

输入样例1:

1 20

输出样例1:

2 12 3 2 2 2 2 2 2 2

输入样例2:

101 300

输出样例2:

40 139 140 41 40 40 40 40 40 40

输入样例3:

1 99

输出样例3:

9 20 20 20 20 20 20 20 20 20

实现代码

方法:数位DP。

public class DigitCount {

    private static final int DIGIT_NUM = 10, INIT_SIZE = 20;

    private static void solve(long x, long[] count, long[] ten, long[] dp) {
        int[] num = new int[INIT_SIZE];
        int len = 0;
        while (x > 0) {
            num[++len] = (int) (x % DIGIT_NUM);
            x = x / DIGIT_NUM;
        }
        for (int i = len; i >= 1; i--) {
            for (int j = 0; j <= DIGIT_NUM - 1; j++) {
                count[j] += dp[i - 1] * num[i];
            }
            for (int j = 0; j < num[i]; j++) {
                count[j] += ten[i - 1];
            }
            long num2 = 0;
            for (int j = i - 1; j >= 1; j--) {
                num2 = num2 * DIGIT_NUM + num[j];
            }
            count[num[i]] += num2 + 1;
            count[0] -= ten[i - 1];
        }
    }

    public static long[] digitCount(long a, long b) throws NumberOutOfBoundException, ANoLessThanBException {
        final long lowerBound = 0, upperBound = 10_000_000_000_000L;
        final int initDpSize = 15;
        if (a <= lowerBound || b <= lowerBound || a >= upperBound || b >= upperBound) {
            throw new NumberOutOfBoundException();
        }
        if (a >= b) {
            throw new ANoLessThanBException();
        }
        long[] result = new long[DIGIT_NUM];
        long[] ten = new long[INIT_SIZE];
        long[] dp = new long[INIT_SIZE];
        long[] countA = new long[INIT_SIZE];
        long[] countB = new long[INIT_SIZE];
        ten[0] = 1;
        for (int i = 1; i <= initDpSize; i++) {
            dp[i] = dp[i - 1] * DIGIT_NUM + ten[i - 1];
            ten[i] = DIGIT_NUM * ten[i - 1];
        }
        solve(a - 1, countA, ten, dp);
        solve(b, countB, ten, dp);
        for (int i = 0; i < DIGIT_NUM; i++) {
            result[i] = countB[i] - countA[i];
        }
        return result;
    }

}

设计测试用例

ID Input a Input b Output
1 1 1000000 488895, 600001, 600000, 600000, 600000, 600000, 600000, 600000, 600000, 600000
2 2 1000000 488895, 600000, 600000, 600000, 600000, 600000, 600000, 600000, 600000, 600000
3 1000000 999999999998 1088888400000, 1199999400000, 1199999400000, 1199999400000, 1199999400000, 1199999400000, 1199999400000, 1199999400000, 1199999400000, 1199999399988
4 1000000 999999999999 1088888400000, 1199999400000, 1199999400000, 1199999400000, 1199999400000, 1199999400000, 1199999400000, 1199999400000, 1199999400000, 1199999400000
5 1 2 0, 1, 1, 0, 0, 0, 0, 0, 0, 0
6 1 999999999998 1088888888889, 1200000000000, 1200000000000, 1200000000000, 1200000000000, 1200000000000, 1200000000000, 1200000000000, 1200000000000, 1199999999988
7 2 999999999998 1088888888889, 1199999999999, 1200000000000, 1200000000000, 1200000000000, 1200000000000, 1200000000000, 1200000000000, 1200000000000, 1199999999988
8 1 999999999999 1088888888889, 1200000000000, 1200000000000, 1200000000000, 1200000000000, 1200000000000, 1200000000000, 1200000000000, 1200000000000, 1200000000000
9 2 999999999999 1088888888889, 1199999999999, 1200000000000, 1200000000000, 1200000000000, 1200000000000, 1200000000000, 1200000000000, 1200000000000, 1200000000000
10 999999999998 999999999999 0, 0, 0, 0, 0, 0, 0, 0, 1, 23
11 0 1 NumberOutOfBoundException
12 0 2 NumberOutOfBoundException
13 0 1000000 NumberOutOfBoundException
14 0 999999999998 NumberOutOfBoundException
15 0 999999999999 NumberOutOfBoundException
16 0 10000000000000 NumberOutOfBoundException
17 1 10000000000000 NumberOutOfBoundException
18 2 10000000000000 NumberOutOfBoundException
19 1000000 10000000000000 NumberOutOfBoundException
20 999999999998 10000000000000 NumberOutOfBoundException
21 999999999999 10000000000000 NumberOutOfBoundException
22 1000000 1000000 ANoLessThanBException
23 999999999998 1000000 ANoLessThanBException
24 1 1 ANoLessThanBException
25 999999999998 2 ANoLessThanBException

执行测试用例

基于Maven引入JUnit5框架,主要基于org.junit.jupiter.api.Testorg.junit.jupiter.api.Assertions即可完成任务。

基本的测试思路:

  • 如果是正常情况:

    Assertions.assertDoesNotThrow(() -> {
        Assertions.assertArrayEquals(expectedArray, DigitCount.digitCount(a, b));
    });
  • 如果是异常情况:

    Assertions.assertThrows(XXXException.class, () -> DigitCount.digitCount(a, b));

正常情况可以套在一个确保非异常的Lambda表达式中执行;而异常情况则应该单测,防止一处异常全体异常。

美中不足的点是魔法数的大量引入。

测试代码:

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

public class DigitCountTest {

    @Test
    public void demoTest() {
        Assertions.assertDoesNotThrow(() -> {
            long[] expectedArray1 = new long[]{2, 12, 3, 2, 2, 2, 2, 2, 2, 2};
            long[] actualArray1 = DigitCount.digitCount(1, 20);
            Assertions.assertArrayEquals(expectedArray1, actualArray1);
            long[] expectedArray2 = new long[]{40, 139, 140, 41, 40, 40, 40, 40, 40, 40};
            long[] actualArray2 = DigitCount.digitCount(101, 300);
            Assertions.assertArrayEquals(expectedArray2, actualArray2);
        });
    }

    @Test
    public void normalTest() {
        Assertions.assertDoesNotThrow(() -> {
            Assertions.assertArrayEquals(new long[]{488895, 600001, 600000, 600000, 600000, 600000, 600000, 600000, 600000, 600000}, DigitCount.digitCount(1, 1000000));
            Assertions.assertArrayEquals(new long[]{488895, 600000, 600000, 600000, 600000, 600000, 600000, 600000, 600000, 600000}, DigitCount.digitCount(2, 1000000));
            Assertions.assertArrayEquals(new long[]{1088888400000L, 1199999400000L, 1199999400000L, 1199999400000L, 1199999400000L, 1199999400000L, 1199999400000L, 1199999400000L, 1199999400000L, 1199999399988L}, DigitCount.digitCount(1000000, 999999999998L));
            Assertions.assertArrayEquals(new long[]{1088888400000L, 1199999400000L, 1199999400000L, 1199999400000L, 1199999400000L, 1199999400000L, 1199999400000L, 1199999400000L, 1199999400000L, 1199999400000L}, DigitCount.digitCount(1000000, 999999999999L));
            Assertions.assertArrayEquals(new long[]{0, 1, 1, 0, 0, 0, 0, 0, 0, 0}, DigitCount.digitCount(1, 2));
            Assertions.assertArrayEquals(new long[]{1088888888889L, 1200000000000L, 1200000000000L, 1200000000000L, 1200000000000L, 1200000000000L, 1200000000000L, 1200000000000L, 1200000000000L, 1199999999988L}, DigitCount.digitCount(1, 999999999998L));
            Assertions.assertArrayEquals(new long[]{1088888888889L, 1199999999999L, 1200000000000L, 1200000000000L, 1200000000000L, 1200000000000L, 1200000000000L, 1200000000000L, 1200000000000L, 1199999999988L}, DigitCount.digitCount(2, 999999999998L));
            Assertions.assertArrayEquals(new long[]{1088888888889L, 1200000000000L, 1200000000000L, 1200000000000L, 1200000000000L, 1200000000000L, 1200000000000L, 1200000000000L, 1200000000000L, 1200000000000L}, DigitCount.digitCount(1, 999999999999L));
            Assertions.assertArrayEquals(new long[]{1088888888889L, 1199999999999L, 1200000000000L, 1200000000000L, 1200000000000L, 1200000000000L, 1200000000000L, 1200000000000L, 1200000000000L, 1200000000000L}, DigitCount.digitCount(2, 999999999999L));
            Assertions.assertArrayEquals(new long[]{0, 0, 0, 0, 0, 0, 0, 0, 1, 23}, DigitCount.digitCount(999999999998L, 999999999999L));
        });
    }

    @Test
    public void aNoLessThanBTest() {
        Assertions.assertThrows(ANoLessThanBException.class, () -> DigitCount.digitCount(1000000, 1000000));
        Assertions.assertThrows(ANoLessThanBException.class, () -> DigitCount.digitCount(999999999998L, 1000000));
        Assertions.assertThrows(ANoLessThanBException.class, () -> DigitCount.digitCount(1, 1));
        Assertions.assertThrows(ANoLessThanBException.class, () -> DigitCount.digitCount(999999999998L, 2));
    }

    @Test
    public void AOrBOutOfBoundTest() {
        Assertions.assertThrows(NumberOutOfBoundException.class, () -> DigitCount.digitCount(0, 1));
        Assertions.assertThrows(NumberOutOfBoundException.class, () -> DigitCount.digitCount(0, 2));
        Assertions.assertThrows(NumberOutOfBoundException.class, () -> DigitCount.digitCount(0, 1000000));
        Assertions.assertThrows(NumberOutOfBoundException.class, () -> DigitCount.digitCount(0, 999999999998L));
        Assertions.assertThrows(NumberOutOfBoundException.class, () -> DigitCount.digitCount(0, 999999999999L));
        Assertions.assertThrows(NumberOutOfBoundException.class, () -> DigitCount.digitCount(0, 10000000000000L));
        Assertions.assertThrows(NumberOutOfBoundException.class, () -> DigitCount.digitCount(1, 10000000000000L));
        Assertions.assertThrows(NumberOutOfBoundException.class, () -> DigitCount.digitCount(2, 10000000000000L));
        Assertions.assertThrows(NumberOutOfBoundException.class, () -> DigitCount.digitCount(1000000, 10000000000000L));
        Assertions.assertThrows(NumberOutOfBoundException.class, () -> DigitCount.digitCount(999999999998L, 10000000000000L));
        Assertions.assertThrows(NumberOutOfBoundException.class, () -> DigitCount.digitCount(999999999999L, 10000000000000L));
    }

}
相关文章
|
5天前
|
测试技术 数据安全/隐私保护
深入理解与应用软件测试中的边界值分析法
【4月更文挑战第23天】在软件测试的诸多技术中,边界值分析法因其简洁性和高效性而备受青睐。本文旨在探讨边界值分析法的核心原理及其在实际测试场景中的应用。通过对边界条件进行系统的识别、分类和测试,该方法能够有效地发现软件缺陷。我们将详细讨论如何确定边界值,设计测试用例,以及如何处理复杂数据类型的边界情况。此外,文章还将展示通过案例研究来验证边界值分析法在提升测试覆盖率和发现潜在错误方面的实际效益。
|
2月前
|
存储 弹性计算 运维
阿里云服务器ECS经济型e实例详细介绍_性能测试和租用价格
阿里云服务器ECS经济型e实例详细介绍_性能测试和租用价格,阿里云服务器ECS推出经济型e系列,经济型e实例是阿里云面向个人开发者、学生、小微企业,在中小型网站建设、开发测试、轻量级应用等场景推出的全新入门级云服务器,CPU采用Intel Xeon Platinum架构处理器,支持1:1、1:2、1:4多种处理器内存配比,e系列性价比优选
|
3月前
|
人工智能 自然语言处理 安全
【AI 现况分析】AI 如何帮助开发者完成自动化测试
【1月更文挑战第27天】【AI 现况分析】AI 如何帮助开发者完成自动化测试
|
4月前
|
测试技术 API 容器
|
2月前
|
计算机视觉
Google Earth Engine(GEE)——使用MODIS数据单点测试SG滤波和harmonics method 滤波的差异分析
Google Earth Engine(GEE)——使用MODIS数据单点测试SG滤波和harmonics method 滤波的差异分析
50 0
|
3月前
|
监控 数据可视化 Java
jvm性能调优实战 - 31从测试到上线_如何分析JVM运行状况及合理优化
jvm性能调优实战 - 31从测试到上线_如何分析JVM运行状况及合理优化
53 1
|
1月前
|
jenkins 测试技术 持续交付
提升软件测试效率与准确性的策略分析
【2月更文挑战第28天】 在快速迭代的软件发展周期中,高效的测试流程是确保产品质量和用户满意度的关键。本文旨在探讨提高软件测试效率和准确性的策略,包括自动化测试工具的选择、测试用例的优化设计以及持续集成的实践。通过分析当前软件测试领域面临的挑战,提出了相应的解决方案,并通过案例分析来展示这些策略的实际应用效果。文章的目的是为软件测试工程师提供实用的指导和参考,帮助他们在保证测试质量的同时,缩短测试周期,降低成本。
44 1
|
10天前
R语言估计多元标记的潜过程混合效应模型(lcmm)分析心理测试的认知过程
R语言估计多元标记的潜过程混合效应模型(lcmm)分析心理测试的认知过程
31 0
|
16天前
|
Web App开发 前端开发 Java
框架分析(11)-测试框架
框架分析(11)-测试框架
|
27天前
|
机器学习/深度学习 人工智能 算法
提升软件测试效率与质量的策略分析
在快速发展的信息技术时代,软件产品已成为日常生活和工作的核心组成部分。随着软件系统的复杂度日益增加,确保其功能性、稳定性及安全性的软件测试工作变得尤为重要。本文针对如何提升软件测试的效率与质量进行了深入探讨,分析了当前软件测试面临的挑战,并提出了一系列创新策略。这些策略包括采用自动化测试工具、实施持续集成和持续部署(CI/CD)、利用人工智能进行测试用例生成以及强化测试团队的技能培训等。通过综合运用这些策略,可以显著提高软件测试的质量和效率,减少人工成本,同时加速产品的上市时间。

热门文章

最新文章