实验一 黑盒测试

实验一   黑盒测试

一、实验目的

1、 掌握黑盒测试的基础知识;

2、 掌握黑盒测试的检查内容及测试目的;

3、 掌握黑盒测试的几种基本测试方法:等价类划分方法、边界值分析方法、因果图法和决策表法;

二、实验要求

1、 复习有关内容,理解黑盒测试;

2、 掌握等价类划分、边界值分析方法、因果图法和决策表法,并能设计出测试用例;

3、 对具体软件,能分别使用相应的黑盒测试方法设计测试用例,并实施测试、分析测试结果。

三、实验内容

1、设计函数实现输入日期显示星期几,并用等价类及边界值法测试

 

实验步骤:

① 设计程序

from flask import Flask, render_template, request
from datetime import datetime

app = Flask(__name__)


@app.route('/', methods=['GET', 'POST'])
def index():
    result = None
    test_cases = []
    test_results = []

    # 如果是POST请求,处理表单提交
    if request.method == 'POST':
        date_str = request.form.get('date')

        # 尝试解析日期
        try:
            date_obj = datetime.strptime(date_str, '%Y-%m-%d')
            # 获取星期几(0-6对应周一到周日)
            weekday = date_obj.weekday()
            # 转换为中文星期表示
            weekdays = ["星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日"]
            result = weekdays[weekday]

            # 生成测试用例(等价类划分法)
            test_cases = [
                {"id": "TC1", "input": "2023-10-05", "expected": "星期四"},
                {"id": "TC2", "input": "2023-02-28", "expected": "星期二"},
                {"id": "TC3", "input": "2020-02-29", "expected": "星期六"},
                {"id": "TC4", "input": "2023-04-31", "expected": "无效日期"},
                {"id": "TC5", "input": "2023/10/05", "expected": "日期格式错误"},
                {"id": "TC6", "input": "2023-13-01", "expected": "月份超出范围"}
            ]

            # 执行测试用例
            test_results = []
            for case in test_cases:
                try:
                    test_date = datetime.strptime(case["input"], '%Y-%m-%d')
                    test_weekday = test_date.weekday()
                    actual = weekdays[test_weekday]
                    status = "通过" if actual == case["expected"] else "失败"
                except ValueError:
                    actual = "无效日期"
                    status = "通过" if actual == case["expected"] else "失败"
                except Exception:
                    actual = "日期格式错误"
                    status = "通过" if actual == case["expected"] else "失败"

                test_results.append({
                    "id": case["id"],
                    "input": case["input"],
                    "expected": case["expected"],
                    "actual": actual,
                    "status": status
                })

        except ValueError:
            result = "无效日期"

        except Exception:
            result = "日期格式错误"

    return render_template('index.html', result=result, test_cases=test_cases, test_results=test_results)


if __name__ == '__main__':
    app.run(debug=True)

 

 

Index.Html

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>日期星期查询</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            max-width: 800px;
            margin: 0 auto;
            padding: 20px;
        }
        .container {
            
            padding: 20px;
            border-radius: 8px;
            margin-bottom: 20px;
        }
        .form-group {
            margin-bottom: 15px;
        }
        label {
            display: block;
            margin-bottom: 5px;
            font-weight: bold;
        }
        input[type="text"] {
            width: 100%;
            padding: 8px;
            box-sizing: border-box;
        }
        button {
            background-color: #4CAF50;
            color: white;
            padding: 10px 15px;
            border: none;
            border-radius: 4px;
            cursor: pointer;
        }
        button:hover {
            background-color: #45a049;
        }
        .result {
            margin-top: 20px;
            padding: 15px;
            background-color: #e9f7ef;
            border-radius: 4px;
        }
        table {
            width: 100%;
            border-collapse: collapse;
            margin-top: 20px;
        }
        th, td {
            border: 1px solid #ddd;
            padding: 8px;
            text-align: left;
        }
        th {
            background-color: #f2f2f2;
        }
        .pass {
            color: green;
            font-weight: bold;
        }
        .fail {
            color: red;
            font-weight: bold;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>日期星期查询</h1>
        <form method="post">
            <div class="form-group">
                <label for="date">请输入日期 (格式: YYYY-MM-DD):</label>
                <input type="text" id="date" name="date" required>
            </div>
            <button type="submit">查询星期</button>
        </form>

        {% if result %}
        <div class="result">
            <h3>查询结果:</h3>
            <p>{{ result }}</p>
        </div>
        {% endif %}

        <h2>等价类划分法测试用例</h2>
        {% if test_results %}
        <table>
            <thead>
                <tr>
                    <th>测试用例ID</th>
                    <th>输入日期</th>
                    <th>预期输出</th>
                    <th>实际输出</th>
                    <th>测试结果</th>
                </tr>
            </thead>
            <tbody>
                {% for case in test_results %}
                <tr>
                    <td>{{ case.id }}</td>
                    <td>{{ case.input }}</td>
                    <td>{{ case.expected }}</td>
                    <td>{{ case.actual }}</td>
                    <td class="{% if case.status == '通过' %}pass{% else %}fail{% endif %}">{{ case.status }}</td>
                </tr>
                {% endfor %}
            </tbody>
        </table>
        {% else %}
        <p>暂无测试结果</p>
        {% endif %}
    </div>
</body>
</html>

 

 

② 划分等价类,得到等价类表。等价类表格式如下:

输入条件

有效等价类

唯一标识

无效等价类

唯一标识

1900到2050内的闰年

(1)

Year<1900

(10)

 

1900到2050内的平年

(2)

Year>2050

(11)

 

 

 

非数字

(12)

1,3,5,7,8,10,12

(3)

Mouth<1

(13)

 

4,6,9,11

(4)

Mouth>12

(14)

 

2

(5)

非数字

(15)

1~28

(6)

Day<1

(16)

 

29

(7)

Day>31

(17)

 

30

(8)

Year为闰年且Mouth为2时,Day>29

(18)

 

31

(9)

Year为平年且Mouth为2时,Day>28

(19)

 

 

()

Mouth=1,3,5,7,8,10,12时,Day>31

(20)

 

 

()

Mouth=4,6,9,11时,Day>30

(21)

 

 

 

非数字

(22)

 

③ 运用等价类划分法设计测试用例,得到测试用例表。测试用例表格式如下:/-/*

 

序号

输入数据

覆盖等价类

输出

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

④ 运用边界值法设计测试用例。

2、找零钱最佳组合

   假设商店货品价格(R) 都不大于100元(且为整数),若顾客付款(P)100元内,现有一个程序能在每位顾客付款后给出找零钱的最佳组合(找给顾客货币张数最少)。 假定此商店的货币面值只包括:50(N50)10(N10) 5(N5)1(N1) 四种。

   请结合等价类划分法和边界值分析法为上述程序设计 出相应的测试用例。

实验步骤:

同上题

  1. 设计程序

change_calculator.py

from flask import Flask, render_template, request

app = Flask(__name__)


class ChangeCalculator:
    @staticmethod
    def find_change(price, payment):
        if payment < price:
            return None, "付款不足"
        if price < 0 or payment < 0:
            return None, "价格和付款不能为负数"
        if price > 100 or payment > 100:
            return None, "价格和付款不能超过100"

        change = payment - price
        if change == 0:
            return {"N50": 0, "N10": 0, "N5": 0, "N1": 0}, "无需找零"

        denominations = [50, 10, 5, 1]
        counts = {"N50": 0, "N10": 0, "N5": 0, "N1": 0}

        for denom in denominations:
            count = change // denom
            counts[f"N{denom}"] = count
            change %= denom

        return counts, f"找零: {payment - price}"


@app.route('/', methods=['GET', 'POST'])
def index():
    result = None
    message = ""
    test_cases = []
    test_results = []

    # 等价类划分测试用例
    equivalence_test_cases = [
        {"id": "EC1", "price": 10, "payment": 10, "expected": {"N50": 0, "N10": 0, "N5": 0, "N1": 0},
         "expected_msg": "无需找零"},
        {"id": "EC2", "price": 5, "payment": 15, "expected": {"N50": 0, "N10": 1, "N5": 0, "N1": 0},
         "expected_msg": "找零: 10"},
        {"id": "EC3", "price": 20, "payment": 10, "expected": None, "expected_msg": "付款不足"},
        {"id": "EC4", "price": 0, "payment": 5, "expected": None, "expected_msg": "付款不足"},
        {"id": "EC5", "price": 10, "payment": 0, "expected": None, "expected_msg": "价格和付款不能为负数"},
        {"id": "EC6", "price": 150, "payment": 200, "expected": None, "expected_msg": "价格和付款不能超过100"},
        {"id": "EC7", "price": 50, "payment": 200, "expected": None, "expected_msg": "价格和付款不能超过100"}
    ]

    # 边界值测试用例
    boundary_test_cases = [
        {"id": "BV1", "price": 0, "payment": 5, "expected": None, "expected_msg": "付款不足"},
        {"id": "BV2", "price": 100, "payment": 200, "expected": {"N50": 2, "N10": 0, "N5": 0, "N1": 0},
         "expected_msg": "找零: 100"},
        {"id": "BV3", "price": 5, "payment": 10, "expected": {"N50": 0, "N10": 1, "N5": 0, "N1": 0},
         "expected_msg": "找零: 5"},
        {"id": "BV4", "price": 1, "payment": 2, "expected": {"N50": 0, "N10": 0, "N5": 0, "N1": 1},
         "expected_msg": "找零: 1"},
        {"id": "BV5", "price": 10, "payment": 20, "expected": {"N50": 0, "N10": 1, "N5": 0, "N1": 0},
         "expected_msg": "找零: 10"},
        {"id": "BV6", "price": 50, "payment": 100, "expected": {"N50": 1, "N10": 0, "N5": 0, "N1": 0},
         "expected_msg": "找零: 50"},
        {"id": "BV7", "price": 99, "payment": 100, "expected": {"N50": 0, "N10": 0, "N5": 0, "N1": 1},
         "expected_msg": "找零: 1"},
        {"id": "BV8", "price": 1, "payment": 100, "expected": {"N50": 1, "N10": 5, "N5": 0, "N1": 0},
         "expected_msg": "找零: 99"}
    ]

    # 合并测试用例
    test_cases = equivalence_test_cases + boundary_test_cases

    # 执行测试用例
    for case in test_cases:
        calculator = ChangeCalculator()
        result_dict, msg = calculator.find_change(case["price"], case["payment"])

        if result_dict == case["expected"] and msg == case["expected_msg"]:
            status = "通过"
        else:
            status = "失败"

        test_results.append({
            "id": case["id"],
            "price": case["price"],
            "payment": case["payment"],
            "expected": case["expected"],
            "expected_msg": case["expected_msg"],
            "actual": result_dict,
            "actual_msg": msg,
            "status": status
        })

    # 处理表单提交
    if request.method == 'POST':
        price = int(request.form.get('price', 0))
        payment = int(request.form.get('payment', 0))
        calculator = ChangeCalculator()
        result, message = calculator.find_change(price, payment)

    return render_template('change_calculator.html', result=result, message=message, test_results=test_results)
if __name__ == '__main__':
    app.run(debug=True)

change_calculator.html

 

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>找零钱最佳组合</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            max-width: 800px;
            margin: 0 auto;
            padding: 20px;
        }
        .container {
            
            padding: 20px;
            border-radius: 8px;
            margin-bottom: 20px;
        }
        .form-group {
            margin-bottom: 15px;
        }
        label {
            display: block;
            margin-bottom: 5px;
            font-weight: bold;
        }
        input[type="number"] {
            width: 100%;
            padding: 8px;
            box-sizing: border-box;
        }
        button {
            background-color: #4CAF50;
            color: white;
            padding: 10px 15px;
            border: none;
            border-radius: 4px;
            cursor: pointer;
        }
        button:hover {
            background-color: #45a049;
        }
        .result {
            margin-top: 20px;
            padding: 15px;
            background-color: #e9f7ef;
            border-radius: 4px;
        }
        table {
            width: 100%;
            border-collapse: collapse;
            margin-top: 20px;
        }
        th, td {
            border: 1px solid #ddd;
            padding: 8px;
            text-align: left;
        }
        th {
            background-color: #f2f2f2;
        }
        .pass {
            color: green;
            font-weight: bold;
        }
        .fail {
            color: red;
            font-weight: bold;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>找零钱最佳组合</h1>
        <form method="post">
            <div class="form-group">
                <label for="price">商品价格 ():</label>
                <input type="number" id="price" name="price" min="0" max="100" required>
            </div>
            <div class="form-group">
                <label for="payment">顾客付款 ():</label>
                <input type="number" id="payment" name="payment" min="0" max="100" required>
            </div>
            <button type="submit">计算找零</button>
        </form>

        {% if message %}
        <div class="result">
            <h3>结果:</h3>
            <p>{{ message }}</p>
            {% if result %}
            <p>50: {{ result.N50 }}</p>
            <p>10: {{ result.N10 }}</p>
            <p>5: {{ result.N5 }}</p>
            <p>1: {{ result.N1 }}</p>
            {% endif %}
        </div>
        {% endif %}

        <h2>测试用例结果</h2>
        <table>
            <thead>
                <tr>
                    <th>测试用例ID</th>
                    <th>价格</th>
                    <th>付款</th>
                    <th>预期结果</th>
                    <th>实际结果</th>
                    <th>测试结果</th>
                </tr>
            </thead>
            <tbody>
                {% for case in test_results %}
                <tr>
                    <td>{{ case.id }}</td>
                    <td>{{ case.price }}</td>
                    <td>{{ case.payment }}</td>
                    <td>
                        {% if case.expected %}
                        {% if case.expected_msg %}{{ case.expected_msg }}{% else %}
                        50: {{ case.expected.N50 }},
                        10: {{ case.expected.N10 }},
                        5: {{ case.expected.N5 }},
                        1: {{ case.expected.N1 }}
                        {% endif %}
                        {% else %}
                        {{ case.expected_msg }}
                        {% endif %}
                    </td>
                    <td>
                        {% if case.actual %}
                        {% if case.actual_msg %}{{ case.actual_msg }}{% else %}
                        50: {{ case.actual.N50 }},
                        10: {{ case.actual.N10 }},
                        5: {{ case.actual.N5 }},
                        1: {{ case.actual.N1 }}
                        {% endif %}
                        {% else %}
                        {{ case.actual_msg }}
                        {% endif %}
                    </td>
                    <td class="{% if case.status == '通过' %}pass{% else %}fail{% endif %}">{{ case.status }}</td>
                </tr>
                {% endfor %}
            </tbody>
        </table>
    </div>
</body>
</html>

 

2.等价类划分

等价类表如下:

等价类编号

输入条件

有效/无效

描述

EC1

付款等于价格

有效

找零为0

EC2

付款大于价格

有效

正常找零

EC3

付款小于价格

无效

付款不足

EC4

价格为0

无效

无效价格

EC5

付款为0

无效

未付款

EC6

价格大于100

无效

价格超出范围

EC7

付款大于100

无效

付款超出范围

EC8

正常找零边界值

有效

找零为1元、5元、10元、50元等边界情况

3. 边界值分析

边界值测试用例:

测试用例ID

价格(R)

付款(P)

预期输出

边界情况

BV1

0

5

付款不足

价格最小值

BV2

100

200

50元:2张

价格最大值

BV3

5

10

5元:1张

找零为5元

BV4

1

2

1元:1张

找零为1元

BV5

10

20

10元:1张

找零为10元

BV6

50

100

50元:1张

找零为50元

BV7

99

100

1元:1张

找零最小非零

BV8

1

100

50元:1张, 10元:5张

找零最大值

测试用例结果

 

 

 

3、有一个饮料自动售货机(处理单价为5角钱)的控制处理软件,它的软件规格说明如下:

若投入5角钱的硬币,按下橙汁啤酒的按钮,则相应的饮料就送出来。若投入1元钱的硬币,同样也是按橙汁啤酒的按钮,则自动售货机在送出相应饮料的同时退回5角钱的硬币。

模拟程序如下:

 

因果图法测试该程序,并撰写实验报告。

实验步骤:

   ①编写程序

vending_machine.py

from flask import Flask, render_template, request
app = Flask(__name__)
class VendingMachine:
    def __init__(self):
        self.coins = []
        self.selection = None
    def insert_coin(self, coin):
        self.coins.append(coin)
    def select_product(self, product):
        self.selection = product
    def dispense(self):
        if not self.selection:
            return "请选择商品"
        total = sum(self.coins)
        if self.selection == "orange" and total >= 0.5:
            change = total - 0.5
            self.coins = []
            self.selection = None
            return f"橙汁已送出。找零:{change}"
        elif self.selection == "beer" and total >= 0.5:
            change = total - 0.5
            self.coins = []
            self.selection = None
            return f"啤酒已送出。找零:{change}"
        else:
            return "金额不足"
@app.route('/', methods=['GET', 'POST'])
def index():
    result = ""
    vending_machine = VendingMachine()
    if request.method == 'POST':
        coin = request.form.get('coin')
        product = request.form.get('product')
        if coin:
            vending_machine.insert_coin(float(coin))
        if product:
            vending_machine.select_product(product)
        result = vending_machine.dispense()
    return render_template('vending_machine.html', result=result)
if __name__ == '__main__':
    app.run(debug=True)

 

vending_machine.html

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>自动售货机</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            max-width: 800px;
            margin: 0 auto;
            padding: 20px;
        }
        .container {
            
            padding: 20px;
            border-radius: 8px;
            margin-bottom: 20px;
        }
        .form-group {
            margin-bottom: 15px;
        }
        label {
            display: block;
            margin-bottom: 5px;
            font-weight: bold;
        }
        input[type="radio"] {
            margin-right: 10px;
        }
        button {
            background-color: #4CAF50;
            color: white;
            padding: 10px 15px;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            margin-right: 10px;
        }
        button:hover {
            background-color: #45a049;
        }
        .result {
            margin-top: 20px;
            padding: 15px;
            background-color: #e9f7ef;
            border-radius: 4px;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>自动售货机</h1>
        <form method="post">
            <div class="form-group">
                <label>请投币:</label>
                <input type="radio" id="coin_1" name="coin" value="1.0">
                <label for="coin_1">1</label>
                <input type="radio" id="coin_0.5" name="coin" value="0.5">
                <label for="coin_0.5">5</label>
            </div>
            <div class="form-group">
                <label>请选择商品:</label>
                <input type="radio" id="product_orange" name="product" value="orange">
                <label for="product_orange">橙汁</label>
                <input type="radio" id="product_beer" name="product" value="beer">
                <label for="product_beer">啤酒</label>
            </div>
            <button type="submit" name="action" value="dispense">确定</button>
            <button type="submit" name="action" value="reset">复位</button>
        </form>

        {% if result %}
        <div class="result">
            <h3>结果:</h3>
            <p>{{ result }}</p>
        </div>
        {% endif %}
    </div>
</body>
</html>

 

②分析原因与结果

原因

投入5角钱(C1)

投入1元钱(C2)

选择橙汁(C3)

选择啤酒(C4)

结果

送出橙汁(E1)

送出啤酒(E2)

找零5角钱(E3)

③画出因果图

 

④转化为决策表

投入5角 (C1)

投入1元 (C2)

选择橙汁 (C3)

选择啤酒 (C4)

送出橙汁 (E1)

送出啤酒 (E2)

找零5角 (E3)

T

F

T

F

T

F

F

T

F

F

T

F

T

F

F

T

T

F

T

F

T

F

T

F

T

F

T

T

T

F

T

T

T

T

F

F

T

T

T

T

T

T

 

⑤根据决策表设计测试用例,得到测试用例表

测试用例ID

投入5角 (C1)

投入1元 (C2)

选择橙汁 (C3)

选择啤酒 (C4)

预期结果

TC1

T

F

T

F

送出橙汁,不找零

TC2

T

F

F

T

送出啤酒,不找零

TC3

F

T

T

F

送出橙汁,找零5角

TC4

F

T

F

T

送出啤酒,找零5角

TC5

T

F

T

T

送出橙汁和啤酒,不找零

TC6

F

T

T

T

送出橙汁和啤酒,找零5角

 

4、航空服务查询问题:根据航线,仓位,飞行时间查询航空服务。

假设一个中国的航空公司规定:

① 中国去欧美的航线所有座位都有食物供应,每个座位都可以播放电影。

② 中国去非欧美的国外航线都有食物供应,只有商务仓可以播放电影。

③ 中国国内的航班的商务仓有食物供应,但是不可以播放电影

④ 中国国内航班的经济仓只有当飞行时间大于2小时时才有食物供应,但是不可以播放电影。

请用程序实现上述功能,并用决策表法设计测试用例,再执行测试,撰写实验报告。

 

 

实验步骤:

① 编写程序

flight_services.py

from flask import Flask, render_template, request

app = Flask(__name__)


class FlightServiceChecker:
    def check_services(self, route, cabin, duration):
        food = False
        movie = False

        if route == "欧美":
            food = True
            movie = True
        elif route == "国外非欧美":
            food = True
            if cabin == "商务舱":
                movie = True
        elif route == "国内":
            if cabin == "商务舱":
                food = True
            elif cabin == "经济舱":
                if duration == "超过两小时":
                    food = True

        return food, movie


@app.route('/', methods=['GET', 'POST'])
def index():
    result = None
    food = None
    movie = None

    if request.method == 'POST':
        route = request.form.get('route')
        cabin = request.form.get('cabin')
        duration = request.form.get('duration')

        checker = FlightServiceChecker()
        food, movie = checker.check_services(route, cabin, duration)

        result = {
            "route": route,
            "cabin": cabin,
            "duration": duration,
            "food": "" if food else "",
            "movie": "" if movie else ""
        }

    return render_template('flight_services.html', result=result)


if __name__ == '__main__':
    app.run(debug=True)

 

flight_services.html

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>航空服务查询</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            max-width: 800px;
            margin: 0 auto;
            padding: 20px;
        }
        .container {
            background-color: #f5f5f5;
            padding: 20px;
            border-radius: 8px;
            margin-bottom: 20px;
        }
        .form-group {
            margin-bottom: 15px;
        }
        label {
            display: block;
            margin-bottom: 5px;
            font-weight: bold;
        }
        input[type="radio"] {
            margin-right: 10px;
        }
        button {
            background-color: #4CAF50;
            color: white;
            padding: 10px 15px;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            margin-right: 10px;
        }
        button:hover {
            background-color: #45a049;
        }
        .result {
            margin-top: 20px;
            padding: 15px;
            background-color: #e9f7ef;
            border-radius: 4px;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>航空服务查询</h1>
        <form method="post">
            <div class="form-group">
                <label>航线:</label>
                <input type="radio" id="route1" name="route" value="欧美">
                <label for="route1">欧美</label>
                <input type="radio" id="route2" name="route" value="国外非欧美">
                <label for="route2">国外非欧美</label>
                <input type="radio" id="route3" name="route" value="国内">
                <label for="route3">国内</label>
            </div>
            <div class="form-group">
                <label>舱位:</label>
                <input type="radio" id="cabin1" name="cabin" value="商务舱">
                <label for="cabin1">商务舱</label>
                <input type="radio" id="cabin2" name="cabin" value="经济舱">
                <label for="cabin2">经济舱</label>
            </div>
            <div class="form-group">
                <label>飞行时间:</label>
                <input type="radio" id="duration1" name="duration" value="两小时以内">
                <label for="duration1">两小时以内</label>
                <input type="radio" id="duration2" name="duration" value="超过两小时">
                <label for="duration2">超过两小时</label>
            </div>
            <button type="submit" name="action" value="query">查询</button>
            <button type="submit" name="action" value="exit">退出</button>
        </form>

        {% if result %}
        <div class="result">
            <h3>查询结果:</h3>
            <p>航线:{{ result.route }}</p>
            <p>舱位:{{ result.cabin }}</p>
            <p>飞行时间:{{ result.duration }}</p>
            <p>食物供应:{{ result.food }}</p>
            <p>播放电影:{{ result.movie }}</p>
        </div>
        {% endif %}
    </div>
</body>
</html>

 

 

② 构造决策表

航线 (C1)

舱位 (C2)

飞行时间 (C3)

食物供应 (E1)

播放电影 (E2)

欧美

商务舱

两小时以内

欧美

商务舱

超过两小时

欧美

经济舱

两小时以内

欧美

经济舱

超过两小时

国外非欧美

商务舱

两小时以内

国外非欧美

商务舱

超过两小时

国外非欧美

经济舱

两小时以内

国外非欧美

经济舱

超过两小时

国内

商务舱

两小时以内

国内

商务舱

超过两小时

国内

经济舱

两小时以内

国内

经济舱

超过两小时

 

③ 根据决策表设计测试用例,得到测试用例表

表格

复制

测试用例ID

航线 (C1)

舱位 (C2)

飞行时间 (C3)

预期结果

TC1

欧美

商务舱

两小时以内

食物供应:是,播放电影:是

TC2

欧美

经济舱

两小时以内

食物供应:是,播放电影:是

TC3

国外非欧美

商务舱

两小时以内

食物供应:是,播放电影:是

TC4

国外非欧美

经济舱

两小时以内

食物供应:是,播放电影:否

TC5

国内

商务舱

两小时以内

食物供应:是,播放电影:否

TC6

国内

经济舱

两小时以内

食物供应:否,播放电影:否

TC7

国内

经济舱

超过两小时

食物供应:是,播放电影:否

 

5、旅馆住宿系统中,旅馆业主可进行添加房间操作。

– 旅馆业主登录旅馆住宿系统后,可以请求添加房间;

– 待进入“房间管理”对话框,单击“添加”按钮可进行添加房间操作;

– 添加房间时,可以设定房间的房间编号、房间类型、房间描述信息;

– 添加房间信息不能缺失,若某一项未填写,要给出提示信息;

– 房间编号长度不超过5个字符;

– 房间描述长度不超过1000个字符;

– 房间信息不能重复,成功填写后,可进行保存或取消操作,之后返回“房间管理”对话框,结束添加房间流程。

实验步骤:

利用黑盒测试策略编写添加房间功能的测试用例。

设计程序

add_room。Py

from flask import Flask, render_template, request, redirect, url_for, flash

app = Flask(__name__)
app.secret_key = 'your_secret_key'

# 模拟数据库
rooms = []


class HotelRoomManager:
    def add_room(self, room_number, room_type, room_description):
        # 验证房间编号长度
        if len(room_number) > 5:
            return False, "房间编号长度不能超过5个字符"

        # 验证房间描述长度
        if len(room_description) > 1000:
            return False, "房间描述长度不能超过1000个字符"

        # 验证房间信息是否重复
        for room in rooms:
            if room['room_number'] == room_number:
                return False, "房间信息已存在"

        # 添加房间
        rooms.append({
            'room_number': room_number,
            'room_type': room_type,
            'room_description': room_description
        })

        return True, "房间添加成功"


@app.route('/', methods=['GET', 'POST'])
def index():
    if request.method == 'POST':
        room_number = request.form.get('room_number')
        room_type = request.form.get('room_type')
        room_description = request.form.get('room_description')

        if not room_number or not room_type or not room_description:
            flash("房间信息不能缺失")
            return redirect(url_for('index'))

        manager = HotelRoomManager()
        success, message = manager.add_room(room_number, room_type, room_description)

        if success:
            flash(message)
            return redirect(url_for('room_management'))
        else:
            flash(message)

    return render_template('add_room.html')


@app.route('/room_management')
def room_management():
    return render_template('room_management.html', rooms=rooms)


if __name__ == '__main__':
    app.run(debug=True)

add_room.html

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>添加房间</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            max-width: 800px;
            margin: 0 auto;
            padding: 20px;
        }
        .container {
            
            padding: 20px;
            border-radius: 8px;
            margin-bottom: 20px;
        }
        .form-group {
            margin-bottom: 15px;
        }
        label {
            display: block;
            margin-bottom: 5px;
            font-weight: bold;
        }
        input[type="text"], textarea {
            width: 100%;
            padding: 8px;
            box-sizing: border-box;
        }
        button {
            background-color: #4CAF50;
            color: white;
            padding: 10px 15px;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            margin-right: 10px;
        }
        button:hover {
            background-color: #45a049;
        }
        .message {
            color: red;
            margin-top: 10px;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>添加房间</h1>
        <form method="post">
            <div class="form-group">
                <label for="room_number">房间编号:</label>
                <input type="text" id="room_number" name="room_number" required>
            </div>
            <div class="form-group">
                <label for="room_type">房间类型:</label>
                <input type="text" id="room_type" name="room_type" required>
            </div>
            <div class="form-group">
                <label for="room_description">房间描述:</label>
                <textarea id="room_description" name="room_description" required></textarea>
            </div>
            <button type="submit">保存</button>
            <button type="reset">取消</button>
        </form>

        {% with messages = get_flashed_messages() %}
        {% if messages %}
        <div class="message">
            {% for message in messages %}
            <p>{{ message }}</p>
            {% endfor %}
        </div>
        {% endif %}
        {% endwith %}
    </div>
</body>
</html>

 

 

room_management.html

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>房间管理</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            max-width: 800px;
            margin: 0 auto;
            padding: 20px;
        }
        .container {
            
            padding: 20px;
            border-radius: 8px;
        }
        table {
            width: 100%;
            border-collapse: collapse;
            margin-top: 20px;
        }
        th, td {
            border: 1px solid #ddd;
            padding: 8px;
            text-align: left;
        }
        th {
            background-color: #f2f2f2;
        }
        button {
            background-color: #4CAF50;
            color: white;
            padding: 10px 15px;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            margin-right: 10px;
        }
        button:hover {
            background-color: #45a049;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>房间管理</h1>
        <table>
            <thead>
                <tr>
                    <th>房间编号</th>
                    <th>房间类型</th>
                    <th>房间描述</th>
                </tr>
            </thead>
            <tbody>
                {% for room in rooms %}
                <tr>
                    <td>{{ room.room_number }}</td>
                    <td>{{ room.room_type }}</td>
                    <td>{{ room.room_description }}</td>
                </tr>
                {% endfor %}
            </tbody>
        </table>
        <br>
        <a href="{{ url_for('index') }}">
            <button>添加房间</button>
        </a>
    </div>
</body>
</html>

 

 

 

 

测试用例

测试用例ID

房间编号

房间类型

房间描述

预期结果

TC1

123

标准间

舒适的标准间

添加成功

TC2

12345

豪华间

豪华的房间

添加成功

TC3

123456

豪华间

豪华的房间

房间编号过长

TC4

123

标准间

舒适的标准间(超过1000字符)

房间描述过长

TC5

123

标准间

舒适的标准间

房间信息重复

TC6

123

 

舒适的标准间

房间类型缺失

TC7

 

标准间

舒适的标准间

房间编号缺失

 

 

四、实验思考

① 在实际的测试中,如何设计测试用例才能达到用最少的测试用例检测出最多的缺陷;

1. 基于风险设计测试用例

识别高风险模块:根据软件的需求规格说明书和设计文档,识别出高风险模块。例如,在一个电商系统中,支付模块通常被视为高风险模块,因为它直接关系到交易的安全性和准确性。

优先测试高风险功能:将更多的测试资源和精力投入到高风险模块的测试中,设计更多的测试用例来覆盖这些模块的各种输入和场景。

2. 使用等价类划分和边界值分析

等价类划分:将输入数据划分为有效的等价类和无效的等价类。例如,对于一个输入框要求输入年龄(1-120岁),有效的等价类是1-120之间的整数,无效的等价类包括小于1、大于120、非整数等。

边界值分析:选择等价类边界附近的值作为测试数据。例如,对于上述年龄输入框,边界值可以是0、1、120、121等。

3. 采用场景测试法

设计业务场景:从业务流程的角度出发,设计测试用例。例如,在一个在线书店系统中,可以设计以下场景:用户搜索书籍、将书籍加入购物车、用户结算、支付成功等。

覆盖关键业务流程:确保每个关键业务流程都有对应的测试用例。

4. 利用错误推测法

基于经验设计测试用例:根据以往的测试经验和常见的软件缺陷类型,设计测试用例。例如,如果之前发现系统在处理大量并发请求时容易出现性能问题,那么在测试时可以设计高并发场景下的测试用例。

 

② 在进行用例设计时,如何考虑软件测试用例的充分性和减少软件测试用例的冗余性;

1. 确保测试用例的充分性

需求覆盖:确保每个需求都有对应的测试用例。可以使用需求跟踪矩阵来跟踪每个需求对应的测试用例,确保需求的全覆盖。

功能覆盖:对软件的每个功能点都进行测试。例如,对于一个文件编辑软件,要测试打开文件、保存文件、编辑文件等所有功能。

输入覆盖:考虑各种可能的输入情况,包括正常输入、异常输入和边界值输入。例如,对于一个登录功能,要测试正确的用户名和密码、错误的用户名、错误的密码、空用户名等输入情况。

2. 减少测试用例的冗余性

去除重复的测试用例:定期对测试用例进行评审,去除重复的测试用例。例如,如果有多个测试用例都是测试同一个功能的正常输入情况,可以保留一个具有代表性的测试用例,删除其他重复的测试用例。

合并相似的测试用例:将相似的测试用例合并。例如,如果有多个测试用例都是测试不同浏览器下的页面显示问题,可以将它们合并为一个测试用例,使用多个浏览器进行测试。

使用正交数组等设计方法:正交数组是一种统计学方法,可以用于设计测试用例,以减少测试用例的数量,同时保证测试的充分性。通过正交数组,可以在较少的测试用例中覆盖尽可能多的输入组合。

posted @ 2025-05-21 10:51  痛苦代码源  阅读(18)  评论(0)    收藏  举报