【软件工程】黑盒测试——等价类划分法

黑盒测试——等价类划分法


图:封面

开发语言及实现平台或实验环境

在 Windows 7 或 Windows 10 操作系统上,使用 C,C++,C#或 Java 语言 及对应的开发环境(IDE)

实验目的

  1. 认识黑盒测试方法中等价类划分测试方法原理 2. 掌握黑盒测试方法中等价类划分测试方法过程

实验要求

  1. 要求学生理解并掌握弱一般等价类测试和强一般等价类测试方法、原理 和测试过程
  2. 具体为每一组,每组二——五人,根据实验题目编写出对应的 c 语言或 c++语言程序,组间相互交换程序,按黑盒测试的方法进行测试。

实验原理

对编写的实验内容,采用等价类划分测试方法进行黑盒测试。

实验材料

  1. 三角形问题
    问题描述:三角形问题接受三个整数,a、b 和 c 作为输入,用作三角
    形的边。程序的输出是由这三条边确定的三角形类型:等边三角形、等腰 三角形、不等边三角形或非三角形。
    作为输入:三角形的三条边必须满足如下条件: C1:1<=a<=100
    C2:1<=b<=100
    C3:1<=c<=100
    C4:a<b+c C5:b<a+c C6:c<a+b
  2. NextDate 函数
    问题描述:NextDate 是一个由三个变量(月份、日期和年份)的函数。
    函数返回输入日期后边的那个日期。 作为输入:变量月份、日期和年都具有整数值,满足以下条件。 C1:1<=月份<=12
    C2:1<=日期<=31
    C3:1912<=年<=2050
  3. 佣金问题 问题描述:前亚利桑那洲境内的一位步枪销售商销售密苏里州制造商
    制造的步枪机(lock)、枪托(stock)和枪管(barrel)。
    枪机卖 45 美元,枪托卖 30 美元,枪管卖 25 美元。 销售商每月至少要售出一支完整的步枪, 且生产限额是大多数销售商在一个月内可销售 70 个枪机、80 个枪托和
    90 个枪管。 每访问一个镇子后,销售商都给密苏里州步枪制造商发出一份很短的
    电报,通知几个枪机被售出。这样步枪制造商就知道当月的销售情况,并 计算销售商的佣金如下:
    不到(含)1000 美元的部分为 10%; 1000(不含)~1800(含)美元的部分为 15%;
    超过 1800 美元的部分为 20%。 佣金程序生成月份销售报告,汇总售出的枪机、枪托和枪管总数,销
    售商的总销售额以及佣金。

实验步骤

  1. 预习相关课堂和实验内容,了解测试对象。
  2. 编写实验材料源代码。
  3. 划分等价类,设计测试用例。
  4. 根据问题需要建立桩模块和驱动模块。
  5. 测试。
  6. 填写试验报告。

实验代码

三角形问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
package procs;

import java.util.InputMismatchException;
import java.util.Scanner;

public class TriangleProc {

public int sideA = 0;
public int sideB = 0;
public int sideC = 0;

public TriangleProc() {

}

/**
* 函数:验证三角形边的长度范围
*
* @param side
* @return
*/
public boolean verifyLengthRange(int side) {
if ((side >= 1) && (side <= 100)) {
return true;
} else {
System.out.println(String.format("边长 %1d 不满足大于等于1且小于等于 100", side));
System.out.println("=========请重新输入=========");
return false;
}

}

/**
* 函数:验证三角形两边之和大于第三边
*
* @param triangleProc
* @return
*/
public boolean verifyFormPrinciple(TriangleProc triangleProc) {

if ((triangleProc.sideA + triangleProc.sideB <= triangleProc.sideC)
|| (triangleProc.sideA + triangleProc.sideC <= triangleProc.sideB)
|| (triangleProc.sideB + triangleProc.sideC <= triangleProc.sideA)) {
System.out.println(String.format("边长组合为 %1d %2d %3d不满足两边之和大于第三边,是非三角形",
triangleProc.sideA, triangleProc.sideB, triangleProc.sideC));
System.out.println("=========请重新输入=========");
return false;
} else {
System.out.println("边长组合满足两边之和大于第三边");
return true;
}
}


public String judgeTriangleType(TriangleProc triangleProc) {
if (triangleProc.sideA == triangleProc.sideB || triangleProc.sideA == triangleProc.sideC
|| triangleProc.sideB == triangleProc.sideC) {
if (triangleProc.sideA == triangleProc.sideB && triangleProc.sideB == triangleProc.sideC) {
String triangleType = "等边三角形";
return triangleType;
} else {
String triangleType = "等腰三角形";
return triangleType;
}
} else {
String triangleType = "非等边三角形";
return triangleType;
}
}

public void inputEdge(Scanner scanner, TriangleProc triangleProc) {
int tempSideA = 0;
int tempSideB = 0;
int tempSideC = 0;

// System.out.println("Welcome to triangle judge program!!!d");
System.out.println("Please input the side A");

if (scanner.hasNext()) {
tempSideA = scanner.nextInt();
triangleProc.sideA = tempSideA;
System.out.println(String.format("Edge A is %1d. Please input side B", tempSideA));
tempSideB = scanner.nextInt();
triangleProc.sideB = tempSideB;
System.out.println(String.format("Edge B is %1d. Please input side C", tempSideB));
tempSideC = scanner.nextInt();
triangleProc.sideC = tempSideC;
System.out.println(String.format("Edge C is %1d. The input is finished\n\n", tempSideC));

}

boolean stopFlag = false;

while (!stopFlag) {
if (verifyLengthRange(triangleProc.sideA) && verifyLengthRange(triangleProc.sideB)
&& verifyLengthRange(triangleProc.sideC)) {
if (verifyFormPrinciple(triangleProc)) {
stopFlag = true;
String triangleType = judgeTriangleType(triangleProc);
System.out.println(String.format("你输入的三角形类型为:%1s", triangleType));
System.out.println("========The End========");
} else {
inputEdge(scanner, triangleProc);
}

} else {
// 边长不满足两个条件,重新输入
inputEdge(scanner, triangleProc);
}
}
}


/**
* 主函数,同时也是测试函数
*
* @param args
*/
public static void main(String[] args) {
TriangleProc triangleProc = new TriangleProc();
Scanner scanner = new Scanner(System.in);
triangleProc.inputEdge(scanner, triangleProc);

}

}

NextDate

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
package procs;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Scanner;

public class NextDate {
public int year = 0;
public int month = 0;
public int day = 0;


/**
* 函数:根据指定的日期,计算下一天
* 注意:应该在进行日期检查之后再调用
* @param year
* @param month
* @param day
* @return
*/
public String nextDateFunction(int year, int month, int day){

Calendar calendar = Calendar.getInstance();

String yearString = Integer.toString(year);
String monthString = Integer.toString(month);
String dayString = Integer.toString(day);

String stringDate = yearString + '-' + monthString + '-' + dayString;

Date date = null;
try {
date = new SimpleDateFormat("yyyy-MM-dd").parse(stringDate);
} catch (ParseException e) {
e.printStackTrace();
}

calendar.setTime(date);

int dayBefore = calendar.get(Calendar.DATE);
calendar.set(Calendar.DATE, dayBefore + 1);

String dayAfter = new SimpleDateFormat("yyyy-MM-dd").format(calendar.getTime());
return dayAfter;

}


/**
* 函数:日期检查函数
* 检查指定的日期是否符合要求
* @param scanner
* @param nextDate
*/
public void dateCheckFunction(Scanner scanner, NextDate nextDate) {
System.out.println("Please Input Your Specific Day");

do {
System.out.println("Please Input the Year(1912 <= year <= 2050): ");
nextDate.year = scanner.nextInt();
} while (nextDate.year < 1912 || nextDate.year > 2050);

do {
System.out.println("Please Input the Month(1 <= month <= 12): ");
nextDate.month = scanner.nextInt();
} while (nextDate.month < 1 || nextDate.month > 12);

do {
System.out.println("Please Input the Day(1 <= day <= 31): ");
nextDate.day = scanner.nextInt();
} while (nextDate.day < 1 || nextDate.day > 31);

}

public static void main(String[] args) {

Scanner scanner = new Scanner(System.in);

NextDate nextDate = new NextDate();

// 检查输入的日期是否符合要求
nextDate.dateCheckFunction(scanner, nextDate);

// 根据nextDateFunction函数获取后一天的日期
String dayAfter = nextDate.nextDateFunction(nextDate.year, nextDate.month, nextDate.day);

System.out.println("The day after is " + dayAfter);


}

}

佣金问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
package procs;

import java.util.Scanner;


public class GunSale {
// 机枪
int part1 = 0;
int part1Price = 45;
// 枪托
int part2 = 0;
int part2Price = 30;
// 枪管
int part3 = 0;
int part3Price = 25;

// 销售数量总和
int amountSum = 0;
// 总销售额
int priceSum = 0;
// 佣金总和
double commissionSum = 0.00f;



// 枪部件输入、检查函数
private void amountInputAndCheck(Scanner scanner, GunSale gunSale) {
System.out.println("Please input the amount of a gun's every part");
System.out.println("----------------------------------------------");
System.out.println("------------机枪----枪托----枪管------------");
/**
* 输入的数量赋值给gunSale对象,且对其销售数量进行检查
*/
do {
System.out.printf("请输入机枪销售额:");
gunSale.part1 = scanner.nextInt();
} while (gunSale.part1 < 1 || gunSale.part1 > 70);

do {
System.out.printf("请输入枪托销售额:");
gunSale.part2 = scanner.nextInt();
} while (gunSale.part2 < 1 || gunSale.part1 > 80);

do {
System.out.printf("请输入枪管:");
gunSale.part3 = scanner.nextInt();
} while (gunSale.part3 < 1 || gunSale.part1 > 90);

}

// 销售数目总和
private int amountSumFunction(GunSale gunSale) {
int amount = gunSale.part1 + gunSale.part2 + gunSale.part3;
gunSale.amountSum = amountSum;
return amount;
}

// 总销售额
private int priceSumFunction(GunSale gunSale) {
int priceSum = gunSale.part1 * gunSale.part1Price + gunSale.part2 * gunSale.part2Price
+ gunSale.part3 * gunSale.part3Price;
gunSale.priceSum = priceSum;
return priceSum;
}

private double commissionSum(GunSale gunSale) {
double commissionSum = 0.00f;

if (gunSale.priceSum <= 1000) {
commissionSum = gunSale.priceSum * 0.1;
} else if (gunSale.priceSum <= 1800) {
commissionSum = (gunSale.priceSum - 1000) * 0.15 + 100;
} else {
commissionSum = (gunSale.priceSum - 1800) * 0.20 + 220;
}

gunSale.commissionSum = commissionSum;
return commissionSum;
}


public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
GunSale gunSale = new GunSale();
gunSale.amountInputAndCheck(scanner, gunSale);
int amountSum = gunSale.amountSumFunction(gunSale);
int priceSum = gunSale.priceSumFunction(gunSale);
double commissionSum = gunSale.commissionSum(gunSale);
System.out.println(String.format("=====销售总数是:%1d, 总销售额:%2d,佣金总和:%3f====="
, amountSum, priceSum, commissionSum));
System.out.println("----------------------------------------------");
}

}

测试用例设计

三角形问题:测试用例

使用弱健壮(Weak Robust)的等价类测试用例设计方法:

  1. 划分有效等价类和无效等价类(序号是每一个等价类唯一的编号)
输入条件 有效等价类 无效等价类
是否满足边长输入要求 1. 1<=a<=100
2. 1<=b<=100
3. 1<=c<=100
4. a<1 || a>100
5. b<1 || b>100
6. c<1 || c>100
是否为非三角形 7. a+b > c
8. a+c > b
9. b+c > a
10. a+b <= c
11. a+c <= b
12. b+c <= a
是否为等腰三角形 13. a=b
14. b=c
15. c=a
16. a!=b && b!=c && c!=a
是否为等边三角形 17. a=b && b=c && c=a 18. a != b
19. b != c
20. c != a

对有效等价类设计测试用例:

测试用例(a, b, c) 预期输出 覆盖编号
7, 8, 9 不等边三角形 1, 2, 3, 7, 8, 9
7, 7, 9
7, 8, 8
9, 8, 9
等腰三角形 1, 2, 3, 7, 8, 9
13
14
15
7, 7, 7 等边三角形 1, 2, 3, 7, 8, 9
13
14
15
17

对无效等价类设计测试用例:

测试用例(a, b, c) 预期输出 覆盖编号
0, 1, 1
1, 1, 101
1, 0, 1
1, 101, 1
1, 1, 0
非三角形 4
5
6
7, 8, 9 非等腰三角形 16

以上组成对三角形问题的弱健壮等价类测试用例设计。

NextDate:测试用例

  1. 划分有效等价类和无效等价类(序号是每一个等价类唯一的编号)
输入条件 有效等价类 无效等价类
是否满足月份输入要求 1. month >= 1
2. month <= 12
3. month < 1
4. month > 12
否满足日期输入要求 5. day >= 1
6. day <= 31
7. day<1
8. day>31
否满足年份输入要求 9. year>=1912
10. year<=2050
11. year<1912
12. year>2050

对有效等价类设计测试用例:

测试用例(year, month, day) 预期输出 覆盖编号
1981, 6, 15 1981-6-16 1, 2, 5, 6, 9, 10

对无效等价类设计测试用例:

测试用例(year, month, day) 预期输出 覆盖编号
1911, 6, 15 年份超出范围 11
2051, 6, 15 年份超出范围 12
1981, 0, 15 月份超出范围 3
1981, 13, 15 月份超出范围 4
1981, 6, 0 日期超出范围 7
1981, 6, 32 日期超出范围 8

以上组成对NextDate的弱健壮等价类测试用例设计。

佣金问题:测试用例

nLock: 步枪机的销量

nStock: 枪托的销量

nBarrel: 枪管的销量

  1. 划分有效等价类和无效等价类(序号是每一个等价类唯一的编号)
输入条件 有效等价类 无效等价类
是否满足最低销售数量要求 1. nLock >= 1
2. nStock >= 1
3. nBarrel >= 1
4. nLock < 1
5. nStock < 1
6. nBarrel < 1
步枪机是否满足生产限额 7. nLock <= 70 8. nLock > 70
枪托是否满足生产限额 9. nStock <= 80 10. nStock > 80
枪管是否满足生产限额 11. nBarrel <= 90 12. nBarrel > 90

对有效等价类设计测试用例:

测试用例(nLock, nStock, nBarrel) 预期输出 覆盖编号
35, 40, 45 销售总数是:120, 总销售额:3900,佣金总和:640.0 1, 2, 3, 7, 9, 13

对无效等价类设计测试用例:

测试用例(nLock, nStock, nBarrel) 预期输出 覆盖编号
0, 40, 45 步枪机不满足最低销售数量 4
35, 0, 45 枪托不满足最低销售数量 5
35, 40, 0 枪管不满足最低销售数量 6
75, 40, 45 步枪机数量超出生产限额 8
35, 85, 45 枪托数量超出生产限额 10
35, 40, 95 枪管数量超出生产限额 12

以上组成对佣金问题的弱健壮等价类测试用例设计。

测试代码及结果分析

三角形问题:测试代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
package exps;

import procs.TriangleProc;

public class TriangleTesting_two {

public void checkShape(int sideA, int sideB, int sideC) {
TriangleProc triangleProc = new TriangleProc();

triangleProc.sideA = sideA;
triangleProc.sideB = sideB;
triangleProc.sideC = sideC;

triangleProc.verifyLengthRange(triangleProc.sideA);
triangleProc.verifyLengthRange(triangleProc.sideB);
triangleProc.verifyLengthRange(triangleProc.sideC);

triangleProc.verifyFormPrinciple(triangleProc);

System.out.println("三角形类型为:" + triangleProc.judgeTriangleType(triangleProc));
}

public static void main(String[] args) {

TriangleTesting_two triangleTesting_two = new TriangleTesting_two();
// 对有效等价类的测试
// 不等边三角形
triangleTesting_two.checkShape(7, 8, 9);
// 等腰三角形(以下三个)
triangleTesting_two.checkShape(7, 7, 9);
triangleTesting_two.checkShape(7, 8, 8);
triangleTesting_two.checkShape(9, 8, 9);
// 等边三角形
triangleTesting_two.checkShape(7, 7, 7);
System.out.println("=====================================\n");
// 对无效等价类的测试
// 非三角形(以下5个)
triangleTesting_two.checkShape(0, 1, 1);
triangleTesting_two.checkShape(1, 1, 101);
triangleTesting_two.checkShape(1, 1, 1);
triangleTesting_two.checkShape(1, 101, 1);
triangleTesting_two.checkShape(1, 1, 0);
triangleTesting_two.checkShape(1, 1, 101);
// 非等腰三角形
triangleTesting_two.checkShape(7, 8, 9);

}

}

三角形问题:测试结果

以上为对三角形问题代码的弱健壮等价类测试,满足预期。

NextDate:测试代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
package exps;

import procs.NextDate;

import java.util.Scanner;

public class NextDateTesting_two {

/**
* 驱动模块
* 函数:dateCheckFunction
*
* @param nextDate
*/
public boolean dateCheckFunction(NextDate nextDate, int year, int month, int day) {

boolean flag = true;

if (year >= 1912 && year <= 2050) {
nextDate.year = year;
} else {
System.out.println("The YEAR is out of range");
flag = false;
}

if (month >= 1 && month <= 12) {
nextDate.month = month;
} else {
System.out.println("The MONTH is out of range");
flag = false;

}

if (day >= 1 && day <= 31) {
nextDate.day = day;
} else {
System.out.println("The DAY is out of range");
flag = false;

}

return flag;

}

public void checkNextDate(int year, int month, int day) {
NextDate nextDate = new NextDate();
NextDateTesting_two nextDateTesting_two = new NextDateTesting_two();

// 检查输入的日期是否符合要求
if (nextDateTesting_two.dateCheckFunction(nextDate, year, month, day)) {
// 根据nextDateFunction函数获取后一天的日期
String dayAfter = nextDate.nextDateFunction(nextDate.year,
nextDate.month, nextDate.day);

System.out.println("The day after is " + dayAfter);
}


}


public static void main(String[] args) {

NextDateTesting_two nextDateTesting_two = new NextDateTesting_two();
// 对有效等价类设计测试用例
nextDateTesting_two.checkNextDate(1981, 6, 15);

// 对无效等价类设计测试用例
nextDateTesting_two.checkNextDate(1911, 6, 15);
nextDateTesting_two.checkNextDate(2051, 6, 15);
nextDateTesting_two.checkNextDate(1981, 0, 15);
nextDateTesting_two.checkNextDate(1981, 13, 15);
nextDateTesting_two.checkNextDate(1981, 6, 0);
nextDateTesting_two.checkNextDate(1981, 6, 32);

}
}

NextDate:测试结果

以下为控制台中输出的测试结果:

符合测试预期。

佣金问题:测试代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
package exps;

import procs.GunSale;

public class GunSaleTesting_two {

// 驱动函数
// 枪部件输入、检查函数
public boolean amountInputAndCheck(GunSale gunSale ,int part1, int part2, int part3) {
boolean flag = true;
// System.out.println("Please input the amount of a gun's every part");
// System.out.println("----------------------------------------------");
// System.out.println("------------机枪----枪托----枪管------------");
/**
* 输入的数量赋值给gunSale对象,且对其销售数量进行检查
*/
gunSale.part1 = part1;
gunSale.part2 = part2;
gunSale.part3 = part3;


if (gunSale.part1 < 1) {
System.out.println("步枪机不满足最低销售数量");
flag = false;
} else if (gunSale.part2 < 1) {
System.out.println("枪托不满足最低销售数量");
flag = false;
} else if (gunSale.part3 < 1) {
System.out.println("枪管不满足最低销售数量");
flag = false;
}else if (gunSale.part1 > 70) {
System.out.println("步枪机数量超出生产限额");
flag = false;
}else if (gunSale.part2 > 80) {
System.out.println("枪托数量超出生产限额");
flag = false;
}else if (gunSale.part3 > 90) {
System.out.println("枪管数量超出生产限额");
flag = false;
}else {
System.out.println("===输入的数值范围正确===");
}
return flag;

}

public void checkGunSale(GunSaleTesting_two gunSaleTesting_two, GunSale gunSale ,int part1, int part2, int part3) {
if (gunSaleTesting_two.amountInputAndCheck(gunSale,part1, part2, part3)){
int amountSum = gunSale.amountSumFunction(gunSale);
int priceSum = gunSale.priceSumFunction(gunSale);
double commissionSum = gunSale.commissionSum(gunSale);
System.out.println(String.format("=====销售总数是:%1d, 总销售额:%2d,佣金总和:%3f====="
, amountSum, priceSum, commissionSum));
System.out.println("----------------------------------------------");
}

}

public static void main(String[] args) {
GunSaleTesting_two gST_two = new GunSaleTesting_two();
GunSale gS = new GunSale();
// 对有效等价类设计测试用例
gST_two.checkGunSale(gST_two, gS, 35, 40, 45);

// 对无效等价类设计测试用例
gST_two.checkGunSale(gST_two, gS, 0, 40, 45);
gST_two.checkGunSale(gST_two, gS, 35, 0, 45);
gST_two.checkGunSale(gST_two, gS, 35, 40, 0);
gST_two.checkGunSale(gST_two, gS, 75, 40, 45);
gST_two.checkGunSale(gST_two, gS, 35, 85, 45);
gST_two.checkGunSale(gST_two, gS, 35, 40, 95);

}
}

佣金问题: 测试结果

测试结果,符合预期。

##【实验总结】

等价类测试的一般测试步骤

  1. 按照输入条件建立有效等价类和无效等价类,列出所有划分出的等价类
  2. 为每一个等价类规定一个唯一的编号
  3. 设计一个新的测试用例,使其尽可能多地覆盖尚未被覆盖地有效等价类,重复这一步,直到所有的有效等价类都被覆盖为止
  4. 设计一个新的测试用例,使其仅覆盖一个尚未被覆盖的无效等价类,重复这一步,直到所有的无效等价类都被覆盖为止

划分等价类的方法

规定了取值范围或值的个数的情况下,可以确立一个有效等价类和两个无效等价类

e.g. 考试0 - 100, 大于100、小于0无效,[0,100]有效

  1. 规定了输入值的集合或规定了“必须如何”的条件下,可以确立一个有效等价类和一个无效等价类
  2. 输入条件是一个布尔量的情况下,可以确定一个有效等价类,
  3. 一组变量n, n个有效等价类
  4. 必须遵守,1个有效等价类,1个无效等价类
  5. 规定了必须遵守的,需要细分