#include "../include/employee.hpp" #include "../include/schedule.hpp" #include "../include/checkin.hpp" #include "../include/attendance.hpp" #include "../include/alert.hpp" #include #include using namespace AttendanceSystem; void test_employee() { std::cout << "测试 Employee 类..." << std::endl; // 测试默认构造函数 Employee emp1; assert(!emp1.isValid()); // 默认构造的对象应该无效 // 测试带参构造函数 Employee emp2("EMP001", "张三", "DEPT001", "软件工程师", "13800138001", "zhangsan@example.com"); assert(emp2.isValid()); assert(emp2.getId() == "EMP001"); assert(emp2.getName() == "张三"); assert(emp2.getDepartmentId() == "DEPT001"); assert(emp2.getPosition() == "软件工程师"); assert(emp2.getMobile() == "13800138001"); assert(emp2.getEmail() == "zhangsan@example.com"); // 测试无效数据 Employee emp3("", "李四", "DEPT001", "", "", ""); assert(!emp3.isValid()); std::cout << "Employee 测试通过!" << std::endl; } void test_schedule_rule() { std::cout << "测试 ScheduleRule 类..." << std::endl; // 测试白班规则 ScheduleRule rule1("RULE001", "白班", 9, 0, 18, 0, 60, 30); assert(rule1.isValid()); assert(rule1.getRuleId() == "RULE001"); assert(rule1.getShiftName() == "白班"); assert(rule1.getStartHour() == 9); assert(rule1.getStartMinute() == 0); assert(rule1.getEndHour() == 18); assert(rule1.getEndMinute() == 0); assert(rule1.getBreakDuration() == 60); assert(rule1.getOvertimeThreshold() == 30); // 测试工作时间计算 int workDuration = rule1.calculateWorkDuration(); assert(workDuration == 8 * 60); // 9:00-18:00,减去60分钟休息,应该是8小时 // 测试加班判断 assert(!rule1.isOvertime(17, 30)); // 17:30下班,不算加班 assert(rule1.isOvertime(18, 45)); // 18:45下班,超过阈值30分钟,算加班 // 测试版本控制 ScheduleRule rule2 = rule1.createNewVersion(); assert(rule2.getVersion() == 2); // 新版本号应该是2 // 测试无效规则 ScheduleRule rule3("", "", 25, 70, -1, 70, -10, -20); // 无效时间 assert(!rule3.isValid()); std::cout << "ScheduleRule 测试通过!" << std::endl; } void test_checkin_record() { std::cout << "测试 CheckInRecord 类..." << std::endl; // 创建时间戳 std::time_t now = std::time(nullptr); std::tm* tm_now = std::localtime(&now); tm_now->tm_hour = 9; tm_now->tm_min = 15; tm_now->tm_sec = 0; std::time_t checkInTime = std::mktime(tm_now); // 测试GPS打卡 Location location(39.9042, 116.4074); CheckInRecord record1("REC001", "EMP001", CheckInMethod::GPS_LOCATION, checkInTime, location); assert(record1.isValid()); assert(record1.getRecordId() == "REC001"); assert(record1.getEmployeeId() == "EMP001"); assert(record1.getMethod() == CheckInMethod::GPS_LOCATION); assert(record1.getTimestamp() == checkInTime); assert(record1.getLocation().latitude == 39.9042); assert(record1.getLocation().longitude == 116.4074); // 测试人脸识别打卡 CheckInRecord record2("REC002", "EMP002", CheckInMethod::FACE_RECOGNITION, checkInTime, Location()); assert(record2.isValid()); assert(record2.getMethodString() == "人脸识别"); // 测试是否迟到/早退 assert(!record1.isLate(9, 0)); // 9:15打卡,期望9:00,不算迟到 assert(!record1.isLate(8, 30)); // 9:15打卡,期望8:30,不算迟到 // 创建一个早一点的打卡记录 tm_now->tm_hour = 8; tm_now->tm_min = 30; std::time_t earlyTime = std::mktime(tm_now); CheckInRecord record3("REC003", "EMP003", CheckInMethod::CARD_SWIPE, earlyTime, Location()); assert(!record3.isEarlyLeave(17, 30)); // 8:30打卡,期望17:30下班,不算早退 std::cout << "CheckInRecord 测试通过!" << std::endl; } void test_attendance_result() { std::cout << "测试 AttendanceResult 类..." << std::endl; // 创建时间戳 std::time_t now = std::time(nullptr); // 测试正常考勤 AttendanceResult result1("RES001", "EMP001", now, AttendanceStatus::NORMAL, 480, "正常上班"); assert(result1.isValid()); assert(result1.getResultId() == "RES001"); assert(result1.getEmployeeId() == "EMP001"); assert(result1.getStatus() == AttendanceStatus::NORMAL); assert(result1.getDuration() == 480); // 8小时 assert(result1.getRemarks() == "正常上班"); assert(!result1.shouldDeductSalary()); // 正常不应该扣款 assert(!result1.shouldPayOvertime()); // 正常不是加班 // 测试迟到考勤 AttendanceResult result2("RES002", "EMP002", now, AttendanceStatus::LATE, 15, "迟到15分钟"); assert(result2.getStatusString() == "迟到"); assert(result2.shouldDeductSalary()); // 迟到应该扣款 // 测试加班考勤 AttendanceResult result3("RES003", "EMP003", now, AttendanceStatus::OVERTIME, 60, "加班1小时"); assert(result3.shouldPayOvertime()); // 加班应该支付加班费 // 测试无效数据 AttendanceResult result4("", "", 0, AttendanceStatus::NORMAL, -10, ""); assert(!result4.isValid()); std::cout << "AttendanceResult 测试通过!" << std::endl; } void test_alert_event() { std::cout << "测试 AlertEvent 类..." << std::endl; std::time_t now = std::time(nullptr); // 测试未打卡异常 AlertEvent alert1("ALERT001", "EMP001", AlertType::NO_CHECK_IN, now, "员工今日未打卡"); assert(alert1.isValid()); assert(alert1.getEventId() == "ALERT001"); assert(alert1.getEmployeeId() == "EMP001"); assert(alert1.getAlertType() == AlertType::NO_CHECK_IN); assert(alert1.getReason() == "员工今日未打卡"); assert(!alert1.isHandled()); // 测试通知渠道 alert1.addNotificationChannel(NotificationChannel::IN_APP_MESSAGE); alert1.addNotificationChannel(NotificationChannel::SMS); assert(alert1.isNotifiedByChannel(NotificationChannel::IN_APP_MESSAGE)); assert(alert1.isNotifiedByChannel(NotificationChannel::SMS)); assert(!alert1.isNotifiedByChannel(NotificationChannel::EMAIL)); // 测试移除通知渠道 alert1.removeNotificationChannel(NotificationChannel::SMS); assert(!alert1.isNotifiedByChannel(NotificationChannel::SMS)); // 测试异常处理 alert1.handle("ADMIN001", "已电话联系确认"); assert(alert1.isHandled()); assert(alert1.getHandlerId() == "ADMIN001"); assert(alert1.getHandleRemarks() == "已电话联系确认"); // 测试严重性判断 AlertEvent alert2("ALERT002", "EMP002", AlertType::CONTINUOUS_ABSENCE, now, "连续缺勤3天"); assert(alert2.isCritical()); // 连续缺勤是严重异常 AlertEvent alert3("ALERT003", "EMP003", AlertType::CHECK_IN_TIME_DEVIATION, now, "打卡时间偏离"); assert(alert3.needsImmediateAttention()); // 需要立即处理 std::cout << "AlertEvent 测试通过!" << std::endl; } int main() { std::cout << "开始运行智能考勤管理系统测试..." << std::endl; std::cout << "========================================\n" << std::endl; try { test_employee(); std::cout << std::endl; test_schedule_rule(); std::cout << std::endl; test_checkin_record(); std::cout << std::endl; test_attendance_result(); std::cout << std::endl; test_alert_event(); std::cout << std::endl; std::cout << "========================================\n" << std::endl; std::cout << "所有测试通过!" << std::endl; return 0; } catch (const std::exception& e) { std::cerr << "测试异常:" << e.what() << std::endl; return 1; } catch (...) { std::cerr << "未知测试异常!" << std::endl; return 1; } }