ai-chore(config): 调整流程配置及改进测试代码
- 将 FLOW_USE_CUSTOM_PROCESS 从 true 改为 false,禁用自定义流程 - 在 BlockTest 测试用例中改用 setBlockMode 方法设置阻断模式 - 设置统一的错误处理,将错误转为异常抛出 - 重命名 BlockTest 测试文件路径,优化测试组织结构 - 更新 IDE php include paths,调整依赖包引用顺序 - 删除无用的 tests/flow/Test.php 测试文件 - 微调 start.php、webman、windows.php 配置或代码模块
This commit is contained in:
@@ -0,0 +1,174 @@
|
||||
<?php
|
||||
|
||||
namespace tests\flow\cases;
|
||||
|
||||
use app\config\Config;
|
||||
use app\flow\config\ProcessConfig;
|
||||
use app\flow\ProcessEngine;
|
||||
use app\utils\Logger;
|
||||
use tests\flow\TestCase;
|
||||
use tests\flow\VirtualityFlowProcessor;
|
||||
|
||||
/**
|
||||
* 流程阻断逻辑测试
|
||||
*
|
||||
* 覆盖场景:
|
||||
* 7. 流程阻断逻辑正确性
|
||||
*/
|
||||
class BlockTest extends TestCase
|
||||
{
|
||||
private VirtualityFlowProcessor $processor;
|
||||
private bool $originalBlockMode;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
$this->processor = VirtualityFlowProcessor::createStandard();
|
||||
|
||||
// 保存原始 blockMode 值
|
||||
$this->originalBlockMode = Config::getInstance()->blockMode;
|
||||
}
|
||||
|
||||
protected function tearDown(): void
|
||||
{
|
||||
parent::tearDown();
|
||||
$this->processor->reset();
|
||||
|
||||
// 恢复原始 blockMode 值
|
||||
Config::getInstance()->setBlockMode($this->originalBlockMode);
|
||||
}
|
||||
|
||||
// ==================== 7. 流程阻断逻辑正确性 ====================
|
||||
|
||||
/**
|
||||
* 测试流程链正确执行
|
||||
*/
|
||||
public function testProcessChainExecution(): void
|
||||
{
|
||||
$engine = ProcessEngine::createStandard();
|
||||
|
||||
// 验证流程链已构建
|
||||
$nodes = $engine->getNodes();
|
||||
$this->assertNotEmpty($nodes, '流程链应包含节点');
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试禁用节点后的流程
|
||||
*/
|
||||
public function testDisabledNodeSkipped(): void
|
||||
{
|
||||
$config = ProcessConfig::createStandard();
|
||||
$config->skipStep('晨洗');
|
||||
|
||||
$processor = VirtualityFlowProcessor::create($config);
|
||||
|
||||
$result = $processor->swipe('操作员1', '胃镜1', '清洗');
|
||||
|
||||
// 晨洗被跳过,应该直接进入清洗
|
||||
$this->assertSuccess($result);
|
||||
$this->assertStep($result, '清洗');
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试时间验证策略阻断 - 阻断模式开启
|
||||
*
|
||||
* 当 blockMode=true 时,清洗时长不达标应该返回错误
|
||||
*/
|
||||
public function testTimeValidationBlockWithBlockModeOn(): void
|
||||
{
|
||||
// 开启阻断模式
|
||||
Config::getInstance()->setBlockMode(true);
|
||||
|
||||
// 创建一个时间不足的场景(只有5秒)
|
||||
$context = $this->processor->createContextBuilder()
|
||||
->endoscope('胃镜1')
|
||||
->reader('漂洗')
|
||||
->operator('操作员1')
|
||||
->currentStep('清洗')
|
||||
->duration(5) // 只有5秒,时间不足
|
||||
->batchNo(date('Ymd') . '010001')
|
||||
->build();
|
||||
|
||||
$engine = ProcessEngine::createStandard();
|
||||
$result = $engine->execute($context);
|
||||
|
||||
// 阻断模式下,时间不足应该导致流程失败
|
||||
$this->assertFalse($result->isSuccess(), '阻断模式下,时长不足应失败');
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试时间验证策略 - 阻断模式关闭
|
||||
*
|
||||
* 当 blockMode=false 时,清洗时长不达标仍可继续,但应有提醒
|
||||
*/
|
||||
public function testTimeValidationWithBlockModeOff(): void
|
||||
{
|
||||
// 关闭阻断模式
|
||||
Config::getInstance()->setBlockMode(false);
|
||||
|
||||
// 创建一个时间不足的场景
|
||||
$context = $this->processor->createContextBuilder()
|
||||
->endoscope('胃镜1')
|
||||
->reader('漂洗')
|
||||
->operator('操作员1')
|
||||
->currentStep('清洗')
|
||||
->duration(5) // 只有5秒,时间不足
|
||||
->batchNo(date('Ymd') . '010001')
|
||||
->build();
|
||||
|
||||
$engine = ProcessEngine::createStandard();
|
||||
$result = $engine->execute($context);
|
||||
|
||||
// 非阻断模式下,时间不足应该可以继续流程
|
||||
$this->assertTrue($result->isSuccess(), '非阻断模式下,时长不足应可继续');
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试重复刷卡阻断
|
||||
*/
|
||||
public function testDuplicateSwipeBlock(): void
|
||||
{
|
||||
$operator = '操作员1';
|
||||
$endoscope = '胃镜1';
|
||||
|
||||
// 完成清洗
|
||||
$result1 = $this->processor->swipe($operator, $endoscope, '清洗');
|
||||
$this->assertSuccess($result1);
|
||||
|
||||
// 继续漂洗
|
||||
$result2 = $this->processor->swipe($operator, $endoscope, '漂洗');
|
||||
|
||||
// 重复刷漂洗卡
|
||||
$result3 = $this->processor->swipe($operator, $endoscope, '漂洗');
|
||||
|
||||
// 获取语音,验证重复刷卡提示
|
||||
$voice3 = $result3->getFullVoice();
|
||||
$this->assertNotEmpty($voice3, '应有语音输出');
|
||||
$this->assertStringContainsString('重复刷卡', $voice3, '语音应包含重复刷卡提示');
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试时长达标时的正常流程
|
||||
*/
|
||||
public function testTimeValidationPass(): void
|
||||
{
|
||||
// 开启阻断模式
|
||||
Config::getInstance()->setBlockMode(true);
|
||||
|
||||
// 创建时长达标的场景(120秒,超过最低要求)
|
||||
$context = $this->processor->createContextBuilder()
|
||||
->endoscope('胃镜1')
|
||||
->reader('漂洗')
|
||||
->operator('操作员1')
|
||||
->currentStep('清洗')
|
||||
->duration(120) // 120秒,时间充足
|
||||
->batchNo(date('Ymd') . '010001')
|
||||
->build();
|
||||
|
||||
$engine = ProcessEngine::createStandard();
|
||||
$result = $engine->execute($context);
|
||||
|
||||
// 时长达标应该成功
|
||||
$this->assertTrue($result->isSuccess(), '时长达标应成功');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
<?php
|
||||
|
||||
namespace tests\flow\cases;
|
||||
|
||||
use app\flow\ProcessEngine;
|
||||
use tests\flow\TestCase;
|
||||
use tests\flow\VirtualityFlowProcessor;
|
||||
|
||||
/**
|
||||
* 错误刷卡流程测试
|
||||
*
|
||||
* 覆盖场景:
|
||||
* 5. 错误刷卡流程
|
||||
*/
|
||||
class ErrorFlowTest extends TestCase
|
||||
{
|
||||
private VirtualityFlowProcessor $processor;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
$this->processor = VirtualityFlowProcessor::createStandard();
|
||||
}
|
||||
|
||||
protected function tearDown(): void
|
||||
{
|
||||
parent::tearDown();
|
||||
$this->processor->reset();
|
||||
}
|
||||
|
||||
// ==================== 5. 错误刷卡流程 ====================
|
||||
|
||||
/**
|
||||
* 测试未刷人员卡直接刷内镜卡
|
||||
*/
|
||||
public function testSwipeEndoscopeWithoutOperator(): void
|
||||
{
|
||||
// 不刷人员卡,直接刷内镜卡
|
||||
$result = $this->processor->swipeEndoscopeCard('胃镜1', '清洗');
|
||||
|
||||
$this->assertFailure($result, '未刷人员卡应失败');
|
||||
$this->assertVoiceContains($result, '请刷人员卡');
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试刷卡顺序错误 - 跳过清洗直接漂洗
|
||||
*/
|
||||
public function testWrongStepOrder(): void
|
||||
{
|
||||
$operator = '操作员1';
|
||||
$endoscope = '胃镜1';
|
||||
|
||||
// 新流程,直接刷漂洗
|
||||
$result = $this->processor->swipe($operator, $endoscope, '漂洗');
|
||||
|
||||
// 应该提示步骤顺序错误
|
||||
// 注意:具体行为取决于流程引擎的实现
|
||||
$this->assertNotNull($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试重复刷同一步骤的卡
|
||||
*/
|
||||
public function testDuplicateSwipe(): void
|
||||
{
|
||||
$operator = '操作员1';
|
||||
$endoscope = '胃镜1';
|
||||
|
||||
// 第一次刷清洗
|
||||
$result1 = $this->processor->swipe($operator, $endoscope, '清洗');
|
||||
$this->assertSuccess($result1);
|
||||
|
||||
// 第二次刷清洗(重复刷卡)
|
||||
$result2 = $this->processor->swipe($operator, $endoscope, '清洗');
|
||||
|
||||
// 应该被重复刷卡节点拦截
|
||||
$this->assertNotNull($result2);
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试读卡器未绑定
|
||||
*/
|
||||
public function testUnboundReader(): void
|
||||
{
|
||||
$context = $this->processor->createContextBuilder()
|
||||
->endoscope('胃镜1')
|
||||
->customReader('R999', '', '') // 未绑定的读卡器
|
||||
->operator('操作员1')
|
||||
->newProcess()
|
||||
->build();
|
||||
|
||||
$engine = ProcessEngine::createStandard();
|
||||
$result = $engine->execute($context);
|
||||
|
||||
// 读卡器未绑定应该在 FlowProcessor 层处理
|
||||
// 这里主要测试 ProcessEngine 的行为
|
||||
$this->assertNotNull($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试内镜卡未绑定
|
||||
*/
|
||||
public function testUnboundEndoscope(): void
|
||||
{
|
||||
$context = $this->processor->createContextBuilder()
|
||||
->endoscope('未绑定卡')
|
||||
->reader('清洗')
|
||||
->operator('操作员1')
|
||||
->newProcess()
|
||||
->build();
|
||||
|
||||
$engine = ProcessEngine::createStandard();
|
||||
$result = $engine->execute($context);
|
||||
|
||||
// 内镜未绑定应该触发错误
|
||||
$this->assertNotNull($result);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
namespace tests\flow\cases;
|
||||
|
||||
use tests\flow\TestCase;
|
||||
use tests\flow\VirtualContextBuilder;
|
||||
use tests\flow\VirtualityFlowProcessor;
|
||||
|
||||
/**
|
||||
* 辅助工具测试
|
||||
*
|
||||
* 测试 VirtualityFlowProcessor 和 VirtualContextBuilder 等测试工具
|
||||
*/
|
||||
class HelperTest extends TestCase
|
||||
{
|
||||
private VirtualityFlowProcessor $processor;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
$this->processor = VirtualityFlowProcessor::createStandard();
|
||||
}
|
||||
|
||||
protected function tearDown(): void
|
||||
{
|
||||
parent::tearDown();
|
||||
$this->processor->reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试 VirtualityFlowProcessor 状态重置
|
||||
*/
|
||||
public function testProcessorReset(): void
|
||||
{
|
||||
// 执行一些操作
|
||||
$this->processor->swipe('操作员1', '胃镜1', '清洗');
|
||||
|
||||
// 重置
|
||||
$this->processor->reset();
|
||||
|
||||
// 重置后应该是新流程
|
||||
$history = $this->processor->getHistory();
|
||||
$this->assertEmpty($history, '重置后历史应为空');
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试 VirtualContextBuilder 功能
|
||||
*/
|
||||
public function testVirtualContextBuilder(): void
|
||||
{
|
||||
$builder = VirtualContextBuilder::create();
|
||||
|
||||
$context = $builder
|
||||
->endoscope('胃镜1')
|
||||
->reader('清洗')
|
||||
->operator('操作员1')
|
||||
->currentStep('清洗')
|
||||
->batchNo('20260310010001')
|
||||
->build();
|
||||
|
||||
$this->assertEquals('清洗', $context->getCurrentStep());
|
||||
$this->assertEquals('20260310010001', $context->getBatchNo());
|
||||
$this->assertEquals('张三', $context->getOperator()->name);
|
||||
$this->assertEquals('胃镜1号', $context->getEndoscope()->name);
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试环境配置加载
|
||||
*/
|
||||
public function testEnvironmentConfig(): void
|
||||
{
|
||||
$env = $this->processor->getEnvironment();
|
||||
|
||||
$this->assertArrayHasKey('readers', $env);
|
||||
$this->assertArrayHasKey('endoscopes', $env);
|
||||
$this->assertArrayHasKey('operators', $env);
|
||||
$this->assertArrayHasKey('config', $env);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
|
||||
namespace tests\flow\cases;
|
||||
|
||||
use tests\flow\TestCase;
|
||||
use tests\flow\VirtualityFlowProcessor;
|
||||
|
||||
/**
|
||||
* 机洗流程测试
|
||||
*
|
||||
* 覆盖场景:
|
||||
* 3. 机洗流程
|
||||
* 4. 晨洗 + 机洗流程
|
||||
*/
|
||||
class MachineWashTest extends TestCase
|
||||
{
|
||||
private VirtualityFlowProcessor $processor;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
$this->processor = VirtualityFlowProcessor::createMachineWash();
|
||||
}
|
||||
|
||||
protected function tearDown(): void
|
||||
{
|
||||
parent::tearDown();
|
||||
$this->processor->reset();
|
||||
}
|
||||
|
||||
// ==================== 3. 机洗流程 ====================
|
||||
|
||||
/**
|
||||
* 测试机洗流程
|
||||
*/
|
||||
public function testMachineWashProcess(): void
|
||||
{
|
||||
$result = $this->processor->swipe('操作员1', '胃镜1', '机洗');
|
||||
|
||||
$this->assertSuccess($result, '机洗应成功');
|
||||
$this->assertStep($result, '机洗');
|
||||
$this->assertHasBatchNo($result);
|
||||
$this->assertTrue($result->isSuccess(), 'isSuccess() 应为 true');
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试机洗流程使用便捷方法
|
||||
*/
|
||||
public function testMachineWashProcessUsingHelper(): void
|
||||
{
|
||||
$result = $this->processor->executeMachineWash('操作员1', '肠镜1');
|
||||
|
||||
$this->assertSuccess($result, '机洗应成功');
|
||||
$this->assertStep($result, '机洗');
|
||||
$this->assertTrue($result->isSuccess(), 'isSuccess() 应为 true');
|
||||
}
|
||||
|
||||
// ==================== 4. 晨洗 + 机洗流程 ====================
|
||||
|
||||
/**
|
||||
* 测试晨洗后接机洗流程
|
||||
*/
|
||||
public function testMorningWashThenMachineWash(): void
|
||||
{
|
||||
$operator = '操作员1';
|
||||
$endoscope = '胃镜1';
|
||||
|
||||
// 直接执行机洗(假设晨洗已完成)
|
||||
$result = $this->processor->swipe($operator, $endoscope, '机洗');
|
||||
|
||||
$this->assertSuccess($result, '晨洗后机洗应成功');
|
||||
$this->assertStep($result, '机洗');
|
||||
$this->assertTrue($result->isSuccess(), 'isSuccess() 应为 true');
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试多个内镜同时机洗
|
||||
*/
|
||||
public function testMultipleEndoscopeMachineWash(): void
|
||||
{
|
||||
$operator = '操作员1';
|
||||
|
||||
// 胃镜1机洗
|
||||
$result1 = $this->processor->swipe($operator, '胃镜1', '机洗');
|
||||
$this->assertSuccess($result1);
|
||||
$batchNo1 = $result1->getBatchNo();
|
||||
|
||||
// 肠镜1机洗
|
||||
$result2 = $this->processor->swipe($operator, '肠镜1', '机洗');
|
||||
$this->assertSuccess($result2);
|
||||
$batchNo2 = $result2->getBatchNo();
|
||||
|
||||
// 批次号应不同
|
||||
$this->assertNotEquals($batchNo1, $batchNo2, '不同内镜机洗应有不同批次号');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,215 @@
|
||||
<?php
|
||||
|
||||
namespace tests\flow\cases;
|
||||
|
||||
use app\flow\config\ProcessConfig;
|
||||
use app\flow\ProcessEngine;
|
||||
use tests\flow\TestCase;
|
||||
use tests\flow\VirtualContextBuilder;
|
||||
use tests\flow\VirtualityFlowProcessor;
|
||||
|
||||
/**
|
||||
* 手工洗流程测试
|
||||
*
|
||||
* 覆盖场景:
|
||||
* 1. 正常完整手工洗流程
|
||||
* 2. 正常完整手工晨洗流程
|
||||
*/
|
||||
class ManualWashTest extends TestCase
|
||||
{
|
||||
private VirtualityFlowProcessor $processor;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
$this->processor = VirtualityFlowProcessor::createStandard();
|
||||
}
|
||||
|
||||
protected function tearDown(): void
|
||||
{
|
||||
parent::tearDown();
|
||||
$this->processor->reset();
|
||||
}
|
||||
|
||||
// ==================== 1. 正常完整手工洗流程 ====================
|
||||
|
||||
/**
|
||||
* 测试完整手工洗流程:清洗 -> 漂洗 -> 消毒 -> 终末漂洗 -> 干燥
|
||||
*/
|
||||
public function testCompleteManualWashProcess(): void
|
||||
{
|
||||
$operator = '操作员1';
|
||||
$endoscope = '胃镜1';
|
||||
|
||||
// 步骤1:清洗
|
||||
$result1 = $this->processor->swipe($operator, $endoscope, '清洗');
|
||||
$this->assertSuccess($result1, '清洗步骤应成功');
|
||||
$this->assertStep($result1, '清洗');
|
||||
$this->assertNeedDatabaseOperation($result1);
|
||||
$batchNo = $result1->getBatchNo();
|
||||
$this->assertNotEmpty($batchNo, '应生成批次号');
|
||||
|
||||
// 步骤2:漂洗
|
||||
$result2 = $this->processor->swipe($operator, $endoscope, '漂洗');
|
||||
$this->assertSuccess($result2, '漂洗步骤应成功');
|
||||
$this->assertStep($result2, '漂洗');
|
||||
$this->assertBatchNoEquals($result2, $batchNo, '批次号应保持一致');
|
||||
|
||||
// 步骤3:消毒
|
||||
$result3 = $this->processor->swipe($operator, $endoscope, '消毒');
|
||||
$this->assertSuccess($result3, '消毒步骤应成功');
|
||||
$this->assertStep($result3, '消毒');
|
||||
$this->assertBatchNoEquals($result3, $batchNo, '批次号应保持一致');
|
||||
|
||||
// 步骤4:终末漂洗
|
||||
$result4 = $this->processor->swipe($operator, $endoscope, '终末漂洗');
|
||||
$this->assertSuccess($result4, '终末漂洗步骤应成功');
|
||||
$this->assertStep($result4, '终末漂洗');
|
||||
$this->assertBatchNoEquals($result4, $batchNo, '批次号应保持一致');
|
||||
|
||||
// 步骤5:干燥
|
||||
$result5 = $this->processor->swipe($operator, $endoscope, '干燥');
|
||||
$this->assertSuccess($result5, '干燥步骤应成功');
|
||||
$this->assertStep($result5, '干燥');
|
||||
$this->assertBatchNoEquals($result5, $batchNo, '批次号应保持一致');
|
||||
|
||||
// 验证最终步骤成功
|
||||
$this->assertTrue($result5->isSuccess(), '干燥步骤 isSuccess() 应为 true');
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试使用便捷方法执行完整手工洗流程
|
||||
*/
|
||||
public function testCompleteManualWashProcessUsingHelper(): void
|
||||
{
|
||||
$results = $this->processor->executeFullManualWash('操作员1', '胃镜1');
|
||||
|
||||
$this->assertCount(5, $results, '应有5个步骤结果');
|
||||
|
||||
foreach ($results as $step => $result) {
|
||||
$this->assertSuccess($result, "{$step} 步骤应成功");
|
||||
$this->assertStep($result, $step);
|
||||
$this->assertTrue($result->isSuccess(), "{$step} isSuccess() 应为 true");
|
||||
}
|
||||
|
||||
// 验证批次号一致性
|
||||
$batchNo = $results['清洗']->getBatchNo();
|
||||
foreach ($results as $step => $result) {
|
||||
$this->assertBatchNoEquals($result, $batchNo, "{$step} 批次号应一致");
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== 2. 正常完整手工晨洗流程 ====================
|
||||
|
||||
/**
|
||||
* 测试晨洗判断 - 当天首次使用需要晨洗
|
||||
*/
|
||||
public function testMorningWashRequired(): void
|
||||
{
|
||||
// 创建需要晨洗的上下文
|
||||
$context = $this->processor->createContextBuilder()
|
||||
->endoscope('胃镜1')
|
||||
->reader('清洗')
|
||||
->operator('操作员1')
|
||||
->needMorningWash(0) // 今天没有洗消记录
|
||||
->newProcess()
|
||||
->build();
|
||||
|
||||
// 执行流程
|
||||
$engine = ProcessEngine::createStandard();
|
||||
$result = $engine->execute($context);
|
||||
|
||||
// 晨洗策略应该生效
|
||||
$this->assertNotNull($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试晨洗完成后的正常流程
|
||||
*/
|
||||
public function testManualWashAfterMorningWash(): void
|
||||
{
|
||||
$operator = '操作员1';
|
||||
$endoscope = '胃镜1';
|
||||
|
||||
// 模拟晨洗已完成状态,执行正常流程
|
||||
$this->processor->clearEndoscopeState($endoscope);
|
||||
|
||||
// 执行完整手工洗流程
|
||||
$results = $this->processor->executeFullManualWash($operator, $endoscope);
|
||||
|
||||
// 验证所有步骤成功
|
||||
foreach ($results as $step => $result) {
|
||||
$this->assertSuccess($result, "{$step} 应成功");
|
||||
$this->assertTrue($result->isSuccess(), "{$step} isSuccess() 应为 true");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试不同操作员接手流程
|
||||
*/
|
||||
public function testDifferentOperatorContinueProcess(): void
|
||||
{
|
||||
$endoscope = '胃镜1';
|
||||
|
||||
// 操作员1开始清洗
|
||||
$result1 = $this->processor->swipe('操作员1', $endoscope, '清洗');
|
||||
$this->assertSuccess($result1);
|
||||
$batchNo = $result1->getBatchNo();
|
||||
|
||||
// 操作员2继续漂洗
|
||||
$result2 = $this->processor->swipe('操作员2', $endoscope, '漂洗');
|
||||
|
||||
// 不同操作员应该可以继续流程
|
||||
$this->assertSuccess($result2);
|
||||
$this->assertBatchNoEquals($result2, $batchNo, '批次号应保持一致');
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试流程完成后开始新流程
|
||||
*/
|
||||
public function testNewProcessAfterComplete(): void
|
||||
{
|
||||
$operator = '操作员1';
|
||||
$endoscope = '胃镜1';
|
||||
|
||||
// 完成一个完整流程
|
||||
$results = $this->processor->executeFullManualWash($operator, $endoscope);
|
||||
$firstBatchNo = $results['清洗']->getBatchNo();
|
||||
|
||||
// 清除状态,开始新流程
|
||||
$this->processor->clearEndoscopeState($endoscope);
|
||||
|
||||
// 开始新流程
|
||||
$newResult = $this->processor->swipe($operator, $endoscope, '清洗');
|
||||
|
||||
// 应该成功,且批次号不同
|
||||
$this->assertSuccess($newResult);
|
||||
$this->assertNotEquals($firstBatchNo, $newResult->getBatchNo(), '新流程应有新批次号');
|
||||
}
|
||||
|
||||
/**
|
||||
* 不同内镜同时进行
|
||||
*/
|
||||
public function testConcurrentProcessIsolation(): void
|
||||
{
|
||||
$operator = '操作员1';
|
||||
|
||||
// 胃镜1开始清洗
|
||||
$result1 = $this->processor->swipe($operator, '胃镜1', '清洗');
|
||||
$this->assertSuccess($result1);
|
||||
$batchNo1 = $result1->getBatchNo();
|
||||
|
||||
// 肠镜1也开始清洗
|
||||
$result2 = $this->processor->swipe($operator, '肠镜1', '清洗');
|
||||
$this->assertSuccess($result2);
|
||||
$batchNo2 = $result2->getBatchNo();
|
||||
|
||||
// 两个内镜的批次号应该不同
|
||||
$this->assertNotEquals($batchNo1, $batchNo2, '不同内镜应有不同批次号');
|
||||
|
||||
// 继续胃镜1的流程
|
||||
$result3 = $this->processor->swipe($operator, '胃镜1', '漂洗');
|
||||
$this->assertSuccess($result3);
|
||||
$this->assertBatchNoEquals($result3, $batchNo1, '胃镜1批次号应保持不变');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
<?php
|
||||
|
||||
namespace tests\flow\cases;
|
||||
|
||||
use app\flow\ProcessEngine;
|
||||
use tests\flow\TestCase;
|
||||
use tests\flow\VirtualityFlowProcessor;
|
||||
|
||||
/**
|
||||
* 语音输出测试
|
||||
*
|
||||
* 覆盖场景:
|
||||
* 6. 语音输出正确性验证
|
||||
*/
|
||||
class VoiceTest extends TestCase
|
||||
{
|
||||
private VirtualityFlowProcessor $processor;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
$this->processor = VirtualityFlowProcessor::createStandard();
|
||||
}
|
||||
|
||||
protected function tearDown(): void
|
||||
{
|
||||
parent::tearDown();
|
||||
$this->processor->reset();
|
||||
}
|
||||
|
||||
// ==================== 6. 语音输出正确性验证 ====================
|
||||
|
||||
/**
|
||||
* 测试清洗步骤语音输出
|
||||
*/
|
||||
public function testWashStepVoice(): void
|
||||
{
|
||||
$result = $this->processor->swipe('操作员1', '胃镜1', '清洗');
|
||||
|
||||
$this->assertSuccess($result);
|
||||
// 语音应该包含步骤相关信息
|
||||
$voice = $result->getFullVoice();
|
||||
$this->assertNotEmpty($voice, '应有语音输出');
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试消毒步骤语音输出
|
||||
*/
|
||||
public function testDisinfectStepVoice(): void
|
||||
{
|
||||
// 先完成前置步骤
|
||||
$this->processor->swipe('操作员1', '胃镜1', '清洗');
|
||||
$this->processor->swipe('操作员1', '胃镜1', '漂洗');
|
||||
|
||||
// 消毒步骤
|
||||
$result = $this->processor->swipe('操作员1', '胃镜1', '消毒');
|
||||
|
||||
$this->assertSuccess($result);
|
||||
$voice = $result->getFullVoice();
|
||||
$this->assertNotEmpty($voice, '应有语音输出');
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试人员卡刷卡语音
|
||||
*/
|
||||
public function testOperatorCardVoice(): void
|
||||
{
|
||||
$result = $this->processor->swipeOperatorCard('操作员1', '清洗');
|
||||
|
||||
// 人员卡应提示"请刷内镜卡"
|
||||
$this->assertVoiceContains($result, '请刷内镜卡');
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试错误情况语音
|
||||
*/
|
||||
public function testErrorVoice(): void
|
||||
{
|
||||
// 未刷人员卡
|
||||
$result = $this->processor->swipeEndoscopeCard('胃镜1', '清洗');
|
||||
|
||||
$voice = $result->getFullVoice();
|
||||
$this->assertNotEmpty($voice, '错误情况应有语音提示');
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试清洗时长不足时的语音模板参数替换
|
||||
*
|
||||
* 语音应包含具体的时长不足提示
|
||||
*/
|
||||
public function testWashDurationInsufficientVoice(): void
|
||||
{
|
||||
// 创建清洗时长不足的场景(只有5秒)
|
||||
$context = $this->processor->createContextBuilder()
|
||||
->endoscope('胃镜1')
|
||||
->reader('漂洗')
|
||||
->operator('操作员1')
|
||||
->currentStep('清洗')
|
||||
->duration(5) // 只有5秒,时间不足
|
||||
->batchNo(date('Ymd') . '010001')
|
||||
->build();
|
||||
|
||||
$engine = ProcessEngine::createStandard();
|
||||
$result = $engine->execute($context);
|
||||
|
||||
// 语音应该包含时长不足相关提示
|
||||
$voice = $result->getFullVoice();
|
||||
$this->assertNotEmpty($voice, '时长不足应有语音提示');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user