DisasterRemovalBaseTest.php 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. <?php
  2. namespace App\Module\AppGame\Tests\Land;
  3. use App\Module\AppGame\Tests\TestConfig;
  4. use App\Module\AppGame\Tests\TestEnvironment;
  5. use Google\Protobuf\Internal\Message;
  6. use Tests\Unit\ProtoRequestTest;
  7. use Uraus\Kku\Request;
  8. use Uraus\Kku\Response;
  9. use Uraus\Kku\Common\RESPONSE_CODE;
  10. /**
  11. * 灾害去除测试基类
  12. *
  13. * 提供灾害去除相关测试的通用方法和断言
  14. */
  15. abstract class DisasterRemovalBaseTest extends ProtoRequestTest
  16. {
  17. /**
  18. * 测试用户ID
  19. */
  20. protected int $testUserId;
  21. /**
  22. * 设置测试环境
  23. */
  24. public function setUp(): void
  25. {
  26. parent::setUp();
  27. $this->testUserId = TestConfig::getTestUserId();
  28. }
  29. /**
  30. * 验证成功响应
  31. */
  32. protected function assertSuccessResponse(Response $response, ?string $expectedMessage = null): void
  33. {
  34. $this->assertInstanceOf(Response::class, $response);
  35. // 检查响应码 - OK = 1 表示成功
  36. $this->assertEquals(RESPONSE_CODE::OK, $response->getCode(), '响应码应该为OK(1)表示成功');
  37. // 检查消息
  38. if ($expectedMessage) {
  39. $this->assertStringContainsString($expectedMessage, $response->getMsg());
  40. }
  41. // 输出响应内容用于调试
  42. if (TestEnvironment::isDebugMode()) {
  43. dump('成功响应: ' . $response->serializeToJsonString());
  44. }
  45. // 总是输出响应详情用于调试
  46. dump('响应详情:', [
  47. 'code' => $response->getCode(),
  48. 'code_name' => RESPONSE_CODE::name($response->getCode()),
  49. 'msg' => $response->getMsg(),
  50. 'callpath' => $response->getCallpath(),
  51. 'run_ms' => $response->getRunMs(),
  52. 'full_response' => $response->serializeToJsonString()
  53. ]);
  54. }
  55. /**
  56. * 验证失败响应
  57. */
  58. protected function assertFailureResponse(Response $response, ?string $expectedError = null): void
  59. {
  60. $this->assertInstanceOf(Response::class, $response);
  61. // 检查响应码(非OK表示失败)
  62. $this->assertNotEquals(RESPONSE_CODE::OK, $response->getCode(), '响应码应该非OK表示失败');
  63. // 检查错误消息
  64. if ($expectedError) {
  65. $this->assertStringContainsString($expectedError, $response->getMsg());
  66. }
  67. // 输出响应内容用于调试
  68. if (TestEnvironment::isDebugMode()) {
  69. dump('失败响应: ' . $response->serializeToJsonString());
  70. }
  71. }
  72. /**
  73. * 验证验证失败响应
  74. */
  75. protected function assertValidationFailureResponse(Response $response, ?string $expectedError = null): void
  76. {
  77. $this->assertInstanceOf(Response::class, $response);
  78. // 检查响应码(VALIDATE_ERROR = 2 表示验证失败)
  79. $this->assertEquals(RESPONSE_CODE::VALIDATE_ERROR, $response->getCode(), '响应码应该为VALIDATE_ERROR(2)表示验证失败');
  80. // 检查错误消息
  81. if ($expectedError) {
  82. $this->assertStringContainsString($expectedError, $response->getMsg());
  83. }
  84. // 输出响应内容用于调试
  85. if (TestEnvironment::isDebugMode()) {
  86. dump('验证失败响应: ' . $response->serializeToJsonString());
  87. }
  88. }
  89. /**
  90. * 用户登录token缓存
  91. */
  92. private static ?string $userToken = null;
  93. /**
  94. * 获取用户登录token
  95. */
  96. protected function getUserToken(): string
  97. {
  98. if (self::$userToken === null) {
  99. self::$userToken = $this->performLogin();
  100. }
  101. return self::$userToken;
  102. }
  103. /**
  104. * 执行用户登录,获取token
  105. */
  106. private function performLogin(): string
  107. {
  108. // 暂时返回一个模拟的token,实际应用中需要真正的登录流程
  109. $testUser = TestEnvironment::getTestUser();
  110. $token = 'test_token_' . $testUser['user_id'] . '_' . time();
  111. if (TestEnvironment::isDebugMode()) {
  112. dump('模拟用户登录,token: ' . $token);
  113. }
  114. return $token;
  115. }
  116. /**
  117. * 创建基础请求对象,包含认证信息
  118. */
  119. protected function createBaseRequest(?Request $request = null): Request
  120. {
  121. if ($request === null) {
  122. $request = new Request();
  123. }
  124. // 获取用户token
  125. $token = $this->getUserToken();
  126. // 设置token到请求中
  127. $tokenRequest = new \Uraus\Kku\Request\RequestPublicToken();
  128. $tokenRequest->setTimes(time());
  129. $request->setPublicToken($tokenRequest);
  130. // 这里需要设置session或其他认证方式
  131. // 由于protobuf的限制,我们可能需要通过其他方式传递token
  132. if (TestEnvironment::isDebugMode()) {
  133. dump('创建基础请求,token: ' . $token);
  134. }
  135. return $request;
  136. }
  137. /**
  138. * 执行测试请求
  139. */
  140. protected function executeTestRequest(): Response
  141. {
  142. $response = $this->protobufRequest();
  143. // 确保返回的是Response类型
  144. if (!$response instanceof Response) {
  145. throw new \RuntimeException('protobufRequest应该返回Response对象');
  146. }
  147. return $response;
  148. }
  149. /**
  150. * 测试成功场景的通用方法
  151. */
  152. protected function runSuccessScenario(string $scenarioName, ?string $expectedMessage = null): void
  153. {
  154. if (TestEnvironment::isDebugMode()) {
  155. dump("开始测试成功场景: {$scenarioName}");
  156. }
  157. // 发送请求并验证响应
  158. $response = $this->executeTestRequest();
  159. $this->assertSuccessResponse($response, $expectedMessage);
  160. if (TestEnvironment::isDebugMode()) {
  161. dump("成功场景测试完成: {$scenarioName}");
  162. }
  163. }
  164. /**
  165. * 测试失败场景的通用方法
  166. */
  167. protected function runFailureScenario(string $scenarioName, ?string $expectedError = null): void
  168. {
  169. if (TestEnvironment::isDebugMode()) {
  170. dump("开始测试失败场景: {$scenarioName}");
  171. }
  172. // 发送请求并验证响应
  173. $response = $this->executeTestRequest();
  174. $this->assertFailureResponse($response, $expectedError);
  175. if (TestEnvironment::isDebugMode()) {
  176. dump("失败场景测试完成: {$scenarioName}");
  177. }
  178. }
  179. /**
  180. * 测试验证失败场景的通用方法
  181. */
  182. protected function runValidationFailureScenario(string $scenarioName, ?string $expectedError = null): void
  183. {
  184. if (TestEnvironment::isDebugMode()) {
  185. dump("开始测试验证失败场景: {$scenarioName}");
  186. }
  187. // 发送请求并验证响应
  188. $response = $this->executeTestRequest();
  189. $this->assertValidationFailureResponse($response, $expectedError);
  190. if (TestEnvironment::isDebugMode()) {
  191. dump("验证失败场景测试完成: {$scenarioName}");
  192. }
  193. }
  194. /**
  195. * 输出测试配置信息
  196. */
  197. protected function dumpTestConfig(array $config): void
  198. {
  199. if (TestEnvironment::isDebugMode()) {
  200. dump('测试配置:', $config);
  201. }
  202. }
  203. /**
  204. * 输出测试开始信息
  205. */
  206. protected function dumpTestStart(string $testName): void
  207. {
  208. if (TestEnvironment::isDebugMode()) {
  209. dump("=== 开始测试: {$testName} ===");
  210. }
  211. }
  212. /**
  213. * 输出测试结束信息
  214. */
  215. protected function dumpTestEnd(string $testName): void
  216. {
  217. if (TestEnvironment::isDebugMode()) {
  218. dump("=== 测试完成: {$testName} ===");
  219. }
  220. }
  221. /**
  222. * 输出响应详情
  223. */
  224. protected function dumpResponse(Response $response, string $label = '响应'): void
  225. {
  226. if (TestEnvironment::isDebugMode()) {
  227. dump("{$label}详情:", [
  228. 'code' => $response->getCode(),
  229. 'msg' => $response->getMsg(),
  230. 'callpath' => $response->getCallpath(),
  231. 'run_ms' => $response->getRunMs(),
  232. 'json' => $response->serializeToJsonString()
  233. ]);
  234. }
  235. }
  236. /**
  237. * 验证概率测试结果
  238. */
  239. protected function assertProbabilityResult(int $successCount, int $totalAttempts, int $expectedRate, int $errorMargin = 30): void
  240. {
  241. $actualRate = ($successCount / $totalAttempts) * 100;
  242. $minRate = $expectedRate - $errorMargin;
  243. $maxRate = $expectedRate + $errorMargin;
  244. $this->assertGreaterThanOrEqual($minRate, $actualRate,
  245. "成功率 {$actualRate}% 低于预期范围 {$minRate}%-{$maxRate}%");
  246. $this->assertLessThanOrEqual($maxRate, $actualRate,
  247. "成功率 {$actualRate}% 高于预期范围 {$minRate}%-{$maxRate}%");
  248. if (TestEnvironment::isDebugMode()) {
  249. dump("概率测试结果:", [
  250. 'success_count' => $successCount,
  251. 'total_attempts' => $totalAttempts,
  252. 'actual_rate' => $actualRate,
  253. 'expected_rate' => $expectedRate,
  254. 'error_margin' => $errorMargin,
  255. 'result' => '通过'
  256. ]);
  257. }
  258. }
  259. /**
  260. * 创建protobuf请求的抽象方法
  261. * 子类必须实现此方法
  262. */
  263. abstract public function create_request_protobuf(): Message;
  264. }