Debug

Testing Is Documentation

tests/Debug/DebugTest.phpDebug - 图1

添加一个组件调试。

Uses

  1. <?php
  2. use Error;
  3. use Exception;
  4. use Leevel\Cache\File as CacheFile;
  5. use Leevel\Database\IDatabase;
  6. use Leevel\Debug\Debug;
  7. use Leevel\Di\Container;
  8. use Leevel\Event\Dispatch;
  9. use Leevel\Event\IDispatch;
  10. use Leevel\Http\JsonResponse;
  11. use Leevel\Http\Request;
  12. use Leevel\Http\Response;
  13. use Leevel\Kernel\App as Apps;
  14. use Leevel\Log\File as LogFile;
  15. use Leevel\Log\ILog;
  16. use Leevel\Option\IOption;
  17. use Leevel\Option\Option;
  18. use Leevel\Session\File as SessionFile;
  19. use Leevel\Session\ISession;
  20. use Tests\Database;
  21. use Tests\Database\DatabaseTestCase as TestCase;

JSON 关联数组调试

关联数组结构会在尾部追加一个选项 :trace 用于调试。

返回结构

  1. $response = ["foo" => "bar", ":trace" => []];

关联数组在尾部追加一个选项作为调试信息,这与非关联数组有所不同。

  1. public function testJson(): void
  2. {
  3. $debug = $this->createDebug();
  4. $this->assertFalse($debug->isBootstrap());
  5. $debug->bootstrap();
  6. $this->assertTrue($debug->isBootstrap());
  7. $request = new Request();
  8. $response = new JsonResponse(['foo' => 'bar']);
  9. $debug->handle($request, $response);
  10. $content = $response->getContent();
  11. $this->assertStringContainsString('{"foo":"bar",":trace":', $content);
  12. $this->assertStringContainsString('"php":{"version":', $content);
  13. $this->assertStringContainsString('Starts from this moment with QueryPHP.', $content);
  14. }

JSON 非关联数组调试

非关联数组结构会在尾部追加一个 :trace 用于调试。

返回结构

  1. $response = ["foo", "bar", [":trace" => []]];

非关联数组在尾部追加一个调试信息,将不会破坏返回接口的 JSON 结构。

  1. public function testJsonForNotAssociativeArray(): void
  2. {
  3. $debug = $this->createDebug();
  4. $this->assertFalse($debug->isBootstrap());
  5. $debug->bootstrap();
  6. $this->assertTrue($debug->isBootstrap());
  7. $request = new Request();
  8. $response = new JsonResponse(['foo', 'bar']);
  9. $debug->handle($request, $response);
  10. $content = $response->getContent();
  11. $this->assertStringContainsString('"foo","bar",{":trace":{', $content);
  12. $this->assertStringContainsString('"php":{"version":', $content);
  13. $this->assertStringContainsString('Starts from this moment with QueryPHP.', $content);
  14. }

关闭调试

  1. public function testDisable(): void
  2. {
  3. $debug = $this->createDebug();
  4. $this->assertFalse($debug->isBootstrap());
  5. $debug->bootstrap();
  6. $this->assertTrue($debug->isBootstrap());
  7. $request = new Request();
  8. $response = new JsonResponse(['foo' => 'bar']);
  9. $debug->handle($request, $response);
  10. $content = $response->getContent();
  11. $this->assertStringContainsString('{"foo":"bar",":trace":', $content);
  12. $this->assertStringContainsString('"php":{"version":', $content);
  13. $this->assertStringContainsString('Starts from this moment with QueryPHP.', $content);
  14. $debug->disable();
  15. $response2 = new JsonResponse(['foo' => 'bar']);
  16. $debug->handle($request, $response2);
  17. $content = $response2->getContent();
  18. $this->assertStringNotContainsString('{"foo":"bar",":trace":', $content);
  19. $this->assertStringNotContainsString('"php":{"version":', $content);
  20. $this->assertStringNotContainsString('Starts from this moment with QueryPHP.', $content);
  21. }

启用调试

  1. public function testEnable(): void
  2. {
  3. $debug = $this->createDebug();
  4. $this->assertFalse($debug->isBootstrap());
  5. $debug->bootstrap();
  6. $this->assertTrue($debug->isBootstrap());
  7. $request = new Request();
  8. $response = new JsonResponse(['foo' => 'bar']);
  9. $debug->disable();
  10. $debug->handle($request, $response);
  11. $content = $response->getContent();
  12. $this->assertStringNotContainsString('{"foo":"bar",":trace":', $content);
  13. $this->assertStringNotContainsString('"php":{"version":', $content);
  14. $this->assertStringNotContainsString('Starts from this moment with QueryPHP.', $content);
  15. $this->assertTrue($debug->isBootstrap());
  16. $debug->enable();
  17. $this->assertTrue($debug->isBootstrap());
  18. $response2 = new JsonResponse(['foo' => 'bar']);
  19. $debug->handle($request, $response2);
  20. $content = $response2->getContent();
  21. $this->assertStringContainsString('{"foo":"bar",":trace":', $content);
  22. $this->assertStringContainsString('"php":{"version":', $content);
  23. $this->assertStringContainsString('Starts from this moment with QueryPHP.', $content);
  24. }

启用调试但是未初始化

  1. public function testEnableWithoutBootstrap(): void
  2. {
  3. $debug = $this->createDebug();
  4. $request = new Request();
  5. $response = new JsonResponse(['foo' => 'bar']);
  6. $debug->disable();
  7. $debug->handle($request, $response);
  8. $content = $response->getContent();
  9. $this->assertStringNotContainsString('{"foo":"bar",":trace":', $content);
  10. $this->assertStringNotContainsString('"php":{"version":', $content);
  11. $this->assertStringNotContainsString('Starts from this moment with QueryPHP.', $content);
  12. $this->assertFalse($debug->isBootstrap());
  13. $debug->enable();
  14. $this->assertTrue($debug->isBootstrap());
  15. $response2 = new JsonResponse(['foo' => 'bar']);
  16. $debug->handle($request, $response2);
  17. $content = $response2->getContent();
  18. $this->assertStringContainsString('{"foo":"bar",":trace":', $content);
  19. $this->assertStringContainsString('"php":{"version":', $content);
  20. $this->assertStringContainsString('Starts from this moment with QueryPHP.', $content);
  21. }

调试消息等级

支持的消息类型

  1. # Tests\Debug\DebugTest::getMessageLevelsData
  2. public function getMessageLevelsData()
  3. {
  4. return [
  5. ['emergency'], ['alert'], ['critical'],
  6. ['error'], ['warning'], ['notice'],
  7. ['info'], ['debug'], ['log'],
  8. ];
  9. }

系统支持多种消息类型,可以参考这个进行调试。

  1. public function testMessageLevelsData(string $level): void
  2. {
  3. $debug = $this->createDebug();
  4. $this->assertFalse($debug->isBootstrap());
  5. $debug->bootstrap();
  6. $this->assertTrue($debug->isBootstrap());
  7. $request = new Request();
  8. $response = new JsonResponse(['foo' => 'bar']);
  9. foreach (['hello', 'world'] as $v) {
  10. $debug->{$level}($v);
  11. }
  12. $debug->handle($request, $response);
  13. $content = $response->getContent();
  14. $this->assertStringContainsString('{"foo":"bar",":trace":', $content);
  15. $this->assertStringContainsString('"php":{"version":', $content);
  16. $this->assertStringContainsString('Starts from this moment with QueryPHP.', $content);
  17. $this->assertStringContainsString('{"message":"hello","message_html":null,"is_string":true,"label":"'.$level.'",', $content);
  18. $this->assertStringContainsString('{"message":"world","message_html":null,"is_string":true,"label":"'.$level.'",', $content);
  19. }

调试 Session

  1. public function testWithSession(): void
  2. {
  3. $debug = $this->createDebug();
  4. $this->assertFalse($debug->isBootstrap());
  5. $debug->bootstrap();
  6. $this->assertTrue($debug->isBootstrap());
  7. $request = new Request();
  8. $response = new JsonResponse(['foo' => 'bar']);
  9. $session = $debug->getContainer()->make('session');
  10. $session->set('test_session', 'test_value');
  11. $debug->handle($request, $response);
  12. $content = $response->getContent();
  13. $this->assertStringContainsString('"session":{"test_session":"test_value"},', $content);
  14. }

调试 Log

  1. public function testWithLog(): void
  2. {
  3. $debug = $this->createDebugWithLog();
  4. $container = $debug->getContainer();
  5. $this->assertFalse($debug->isBootstrap());
  6. $debug->bootstrap();
  7. $this->assertTrue($debug->isBootstrap());
  8. $request = new Request();
  9. $response = new JsonResponse(['foo' => 'bar']);
  10. $log = $container->make('log');
  11. $log->info('test_log', ['exends' => 'bar']);
  12. $log->debug('test_log_debug');
  13. $debug->handle($request, $response);
  14. $content = $response->getContent();
  15. $this->assertStringContainsString('"logs":{"count":2,', $content);
  16. $this->assertStringContainsString('test_log info: {\"exends\":\"bar\"}', $content);
  17. $this->assertStringContainsString('test_log_debug debug: []', $content);
  18. }

调试数据库

  1. public function testWithDatabase(): void
  2. {
  3. $debug = $this->createDebugWithDatabase();
  4. $container = $debug->getContainer();
  5. $this->assertFalse($debug->isBootstrap());
  6. $debug->bootstrap();
  7. $this->assertTrue($debug->isBootstrap());
  8. $request = new Request();
  9. $response = new JsonResponse(['foo' => 'bar']);
  10. $database = $container->make('database');
  11. $database
  12. ->table('guest_book')
  13. ->findAll();
  14. $debug->handle($request, $response);
  15. $content = $response->getContent();
  16. $this->assertStringContainsString('"logs":{"count":1,', $content);
  17. $this->assertStringContainsString('SQL: [39] SELECT `guest_book`.* FROM `guest_book` | Params: 0', $content);
  18. }

调试时间

  1. public function testTime(): void
  2. {
  3. $debug = $this->createDebug();
  4. $this->assertFalse($debug->isBootstrap());
  5. $debug->bootstrap();
  6. $this->assertTrue($debug->isBootstrap());
  7. $request = new Request();
  8. $response = new JsonResponse(['foo' => 'bar']);
  9. $debug->time('time_test');
  10. $debug->end('time_test');
  11. $debug->handle($request, $response);
  12. $content = $response->getContent();
  13. $this->assertStringContainsString('"time":{"start"', $content);
  14. $this->assertStringContainsString('"measures":[{"label":"time_test","start":', $content);
  15. }

调试带有标签的时间

  1. public function testTimeWithLabel(): void
  2. {
  3. $debug = $this->createDebug();
  4. $this->assertFalse($debug->isBootstrap());
  5. $debug->bootstrap();
  6. $this->assertTrue($debug->isBootstrap());
  7. $request = new Request();
  8. $response = new JsonResponse(['foo' => 'bar']);
  9. $debug->time('time_test', 'time_label');
  10. $debug->end('time_test');
  11. $debug->handle($request, $response);
  12. $content = $response->getContent();
  13. $this->assertStringContainsString('"time":{"start"', $content);
  14. $this->assertStringContainsString('"measures":[{"label":"time_label","start":', $content);
  15. }