Kiểm thử phần mềm

Kiểm thử biến hình cho bộ kiểm chứng thời khóa biểu

Suy luận về phép hoán vị, đổi mã và nới ràng buộc. Tạo ca neo và phản ví dụ để phát hiện lỗi phụ thuộc dữ liệu.

Vấn đề nghiên cứuNâng cao18 phút đọcPython

Thích và đánh giá Bình luận và hỏi đáp
Lịch gốc và lịch đã hoán vị cần cho cùng số lỗi và điểm, miễn mọi dữ liệu nghiệp vụ giữ nguyên.
Lịch gốc và lịch đã hoán vị cần cho cùng số lỗi và điểm, miễn mọi dữ liệu nghiệp vụ giữ nguyên. Mở hình lớn ↗

1. Khi biết quy luật nhưng khó tính kết quả đầy đủ

Với một thời khóa biểu lớn, ta có thể biết lịch cần tránh trùng phòng và trùng giảng viên, nhưng khó liệt kê thủ công số lỗi và từng khoản phạt. Trong kiểm thử, đây là một dạng khó khăn về oracle, tức nguồn xác định kết quả mong đợi. Kiểm thử biến hình khai thác các quan hệ giữa nhiều lần chạy. Ta biến đổi dữ liệu theo một quy tắc và kiểm tra xem kết quả mới có quan hệ đúng với kết quả cũ hay không.

Ví dụ, đổi thứ tự các bản ghi trong tệp lịch không làm thay đổi việc hai buổi có trùng ca hay trùng phòng. Ta chưa cần biết trước lịch lớn có bao nhiêu lỗi, nhưng có thể kiểm tra rằng các số đếm không đổi sau khi hoán vị. Nếu bộ kiểm chứng dựa nhầm vào vị trí các dòng thay vì khóa nghiệp vụ, phép thử này có thể làm lộ lỗi.

2. Đặt tiền điều kiện cho mỗi quan hệ biến hình

Phép biến đổiTiền điều kiệnKỳ vọng
Hoán vị bản ghiGiữ nguyên tập buổi và mọi trường.Số lỗi và điểm giữ nguyên.
Đổi mã bằng song ánhĐổi nhất quán trong lịch, ràng buộc và bảng ưu tiên.Số lỗi và điểm giữ nguyên.
Nới một ràng buộc cứngGiữ các ràng buộc còn lại và hàm mục tiêu.Mọi lịch từng hợp lệ vẫn hợp lệ.

Điều kiện đổi mã nhất quán rất quan trọng. Nếu đổi mã GV A thành x_A trong lịch mà bảng ưu tiên vẫn dùng A, điểm mềm có thể thay đổi. Đây là phản ví dụ cho một quan hệ viết thiếu tiền điều kiện. Tương tự, khi nới ràng buộc cứng, điểm tối ưu chỉ được bảo đảm không tăng nếu đang tối thiểu hóa cùng một hàm mục tiêu và cả hai giá trị là tối ưu thật sự. Kết quả tốt nhất tìm thấy trong một thời hạn cố định có thể không tuân theo thứ tự đó.

3. Kết hợp ca neo với các phép biến đổi

Môi trường thực hành. Python 3.10 trở lên. Ví dụ dùng thư viện chuẩn Python.

Python · kiem_thu_bien_hinh.pyTải mã nguồn
"""Kiểm thử biến hình cho bộ kiểm chứng lịch đồ chơi."""
from dataclasses import dataclass, replace
from itertools import combinations, permutations


@dataclass(frozen=True)
class Buoi:
    ma: str
    phong: str
    gv: str
    ca: int
    thu: int


def danh_gia(lich, gv_uu_tien):
    trung_phong = sum(a.ca == b.ca and a.thu == b.thu and a.phong == b.phong
                     for a, b in combinations(lich, 2))
    trung_gv = sum(a.ca == b.ca and a.thu == b.thu and a.gv == b.gv
                  for a, b in combinations(lich, 2))
    if trung_phong or trung_gv:
        return (trung_phong, trung_gv, None)
    ngay = {b.thu for b in lich if b.gv == gv_uu_tien}
    return (0, 0, 5 * {2, 6}.issubset(ngay))


if __name__ == "__main__":
    sample = [
        Buoi("L1", "P101", "A", 1, 2),
        Buoi("L2", "P102", "B", 1, 2),
        Buoi("L3", "P101", "A", 1, 6),
    ]
    conflict = [sample[0], replace(sample[1], phong="P101", gv="A"), sample[2]]

    # Neo kỳ vọng để tránh một validator luôn trả cùng một kết quả.
    assert danh_gia(sample, "A") == (0, 0, 5)
    assert danh_gia(conflict, "A") == (1, 1, None)

    for lich in (sample, conflict):
        expected = danh_gia(lich, "A")
        for permutation in permutations(lich):
            assert danh_gia(permutation, "A") == expected
        renamed = [replace(b, ma="x_" + b.ma, phong="x_" + b.phong, gv="x_" + b.gv)
                   for b in lich]
        assert danh_gia(renamed, "x_A") == expected

    # Minh họa lỗi thiết kế test: đổi ID giảng viên mà quên đổi ưu tiên.
    renamed = [replace(b, gv="x_" + b.gv) for b in sample]
    assert danh_gia(renamed, "A") == (0, 0, 0)
    print("Đạt kiểm thử hoán vị và đổi mã đồng bộ trên hai lịch.")

Chạy python kiem_thu_bien_hinh.py. Ví dụ có một lịch khả thi nhận 5 điểm và một lịch gây đúng một lỗi phòng, một lỗi giảng viên. Hai kỳ vọng cụ thể đóng vai trò ca neo. Sau đó, chương trình thử các hoán vị và đổi mã đồng bộ. Bộ kiểm chứng luôn trả một số cố định có thể vượt qua phép thử bất biến, nhưng sẽ thất bại trên một trong hai ca neo.

Chương trình so sánh số lỗi và điểm, vì đó là hợp đồng của hàm. Nếu hệ thống thực trả danh sách vi phạm, cần quyết định thứ tự có phải là một phần của hợp đồng hay không. Nếu thứ tự không quan trọng, so sánh các bản ghi lỗi đã chuẩn hóa theo cặp lớp và mã ràng buộc. Khi đổi mã, áp dụng phép ánh xạ ngược trước khi so thông báo gốc.

4. Dùng phản ví dụ để cải thiện bộ kiểm thử

Thử sửa vòng kiểm tra để chỉ so hai buổi đứng kề trong danh sách. Tạo lịch với hai buổi trùng bị ngăn cách bởi một buổi khác, rồi hoán vị để đưa chúng sát nhau. Hai kết quả khác nhau cho thấy cách kiểm tra phụ thuộc thứ tự. Tiếp theo, thử bổ sung trường cơ sở hoặc nhóm sinh viên. Viết rõ phép đổi mã nào hợp lệ trước khi sinh thêm ca tự động.

Khi báo cáo, hãy ghi số quan hệ đã dùng, các miền dữ liệu, số lỗi chủ động đưa vào mà bộ thử phát hiện, và phản ví dụ nhỏ nhất tìm được. Phương pháp này bổ sung cho đối chiếu bằng lịch nhỏ, kiểm tra biên và so sánh với bộ kiểm chứng độc lập. Đọc thêm tại Chen và cộng sự · Tổng quan kiểm thử biến hình.