001/tests/basic_test.cpp

215 lines
8.0 KiB
C++
Raw Permalink Normal View History

2026-04-15 08:34:21 +00:00
#include "../include/employee.hpp"
#include "../include/schedule.hpp"
#include "../include/checkin.hpp"
#include "../include/attendance.hpp"
#include "../include/alert.hpp"
#include <cassert>
#include <iostream>
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;
}
}