feat: add dynamic per-call SSH connections and secret redaction
- execute-command/upload/download accept host/port/username/password inline to open an ephemeral connection for a single call - add redactSecret/redactSecrets to mask credentials in logs and errors - logger log()/handleError() accept optional secrets[] for redaction - add SSH_CONFIG_MISSING error code and --password-from-env CLI flag - dynamic-mode startup: server runs with no static config
This commit is contained in:
+191
@@ -0,0 +1,191 @@
|
||||
# 测试文档
|
||||
|
||||
本项目使用 Node.js 内置的测试框架进行单元测试和集成测试。
|
||||
|
||||
## 测试结构
|
||||
|
||||
```
|
||||
test/
|
||||
├── ssh-config-parser.test.js # SSH 配置解析器测试
|
||||
├── command-line-parser.test.js # 命令行参数解析器测试
|
||||
├── ssh-connection-manager.test.js # SSH 连接管理器测试
|
||||
├── integration.test.js # 集成测试
|
||||
└── fixtures/ # 测试数据(自动生成)
|
||||
```
|
||||
|
||||
## 运行测试
|
||||
|
||||
### 运行所有测试
|
||||
|
||||
```bash
|
||||
npm test
|
||||
```
|
||||
|
||||
### 监听模式(开发时使用)
|
||||
|
||||
```bash
|
||||
npm run test:watch
|
||||
```
|
||||
|
||||
监听模式会在文件变化时自动重新运行测试。
|
||||
|
||||
### 运行单个测试文件
|
||||
|
||||
```bash
|
||||
node --test test/ssh-config-parser.test.js
|
||||
```
|
||||
|
||||
## 测试覆盖范围
|
||||
|
||||
### 1. SSH Config Parser 测试
|
||||
|
||||
测试 `src/utils/ssh-config-parser.ts` 的功能:
|
||||
|
||||
- ✅ 基本 Host 别名解析
|
||||
- ✅ 多别名 Host 行(`Host a b c`)
|
||||
- ✅ 通配符匹配(`Host *.example.com`)
|
||||
- ✅ `Host *` 默认值 fallback
|
||||
- ✅ `Include` 指令支持
|
||||
- ✅ 路径展开(`~` 和相对路径)
|
||||
- ✅ First-match-wins 语义
|
||||
- ✅ 错误处理(文件不存在等)
|
||||
|
||||
### 2. Command Line Parser 测试
|
||||
|
||||
测试 `src/cli/command-line-parser.ts` 的功能:
|
||||
|
||||
- ✅ JSON 配置文件解析(对象和数组格式)
|
||||
- ✅ `--ssh` 参数解析(JSON 和旧格式)
|
||||
- ✅ 单连接模式(命令行参数和位置参数)
|
||||
- ✅ SSH config 集成
|
||||
- ✅ 参数优先级(命令行 > SSH config)
|
||||
- ✅ 命令白名单和黑名单
|
||||
- ✅ 其他选项(`--pty`, `--pre-connect`, `--proxy`, `--socksProxy`)
|
||||
- ✅ 错误处理
|
||||
|
||||
### 3. SSH Connection Manager 测试
|
||||
|
||||
测试 `src/services/ssh-connection-manager.ts` 的功能:
|
||||
|
||||
- ✅ 配置管理(初始化、获取配置)
|
||||
- ✅ 命令验证(白名单、黑名单、正则表达式)
|
||||
- ✅ 连接状态管理
|
||||
- ✅ 多服务器支持
|
||||
|
||||
### 4. 集成测试
|
||||
|
||||
端到端测试完整流程:
|
||||
|
||||
- ✅ 从命令行参数到连接管理器的完整流程
|
||||
- ✅ 从 SSH config 到连接管理器的完整流程
|
||||
- ✅ 多服务器配置场景
|
||||
- ✅ 错误处理(无效配置、缺少字段等)
|
||||
|
||||
## 编写新测试
|
||||
|
||||
### 测试文件命名
|
||||
|
||||
测试文件应该以 `.test.js` 结尾,并放在 `test/` 目录下。
|
||||
|
||||
### 测试示例
|
||||
|
||||
```javascript
|
||||
import { describe, it, before, after } from 'node:test';
|
||||
import assert from 'node:assert';
|
||||
|
||||
describe('功能模块名称', () => {
|
||||
before(() => {
|
||||
// 测试前的准备工作
|
||||
});
|
||||
|
||||
after(() => {
|
||||
// 测试后的清理工作
|
||||
});
|
||||
|
||||
describe('子功能', () => {
|
||||
it('应该做某事', () => {
|
||||
// 测试代码
|
||||
assert.strictEqual(1 + 1, 2);
|
||||
});
|
||||
|
||||
it('应该处理错误情况', () => {
|
||||
assert.throws(() => {
|
||||
throw new Error('测试错误');
|
||||
}, /测试错误/);
|
||||
});
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
## 测试最佳实践
|
||||
|
||||
1. **独立性**:每个测试应该独立运行,不依赖其他测试的状态
|
||||
2. **清理**:使用 `after` 钩子清理测试创建的临时文件和资源
|
||||
3. **描述性**:测试名称应该清楚地描述测试的内容
|
||||
4. **覆盖边界情况**:测试正常情况、边界情况和错误情况
|
||||
5. **使用 fixtures**:将测试数据放在 `test/fixtures/` 目录下
|
||||
|
||||
## CI/CD 集成
|
||||
|
||||
测试可以轻松集成到 CI/CD 流程中:
|
||||
|
||||
```yaml
|
||||
# GitHub Actions 示例
|
||||
- name: Run tests
|
||||
run: npm test
|
||||
```
|
||||
|
||||
## 调试测试
|
||||
|
||||
### 使用 Node.js 调试器
|
||||
|
||||
```bash
|
||||
node --inspect-brk --test test/ssh-config-parser.test.js
|
||||
```
|
||||
|
||||
然后在 Chrome 中打开 `chrome://inspect` 进行调试。
|
||||
|
||||
### 查看详细输出
|
||||
|
||||
```bash
|
||||
node --test --test-reporter=tap test/**/*.test.js
|
||||
```
|
||||
|
||||
## 常见问题
|
||||
|
||||
### Q: 测试失败但没有详细错误信息?
|
||||
|
||||
A: 使用 `--test-reporter=spec` 查看详细输出:
|
||||
|
||||
```bash
|
||||
node --test --test-reporter=spec test/**/*.test.js
|
||||
```
|
||||
|
||||
### Q: 如何跳过某个测试?
|
||||
|
||||
A: 使用 `it.skip()`:
|
||||
|
||||
```javascript
|
||||
it.skip('暂时跳过的测试', () => {
|
||||
// 测试代码
|
||||
});
|
||||
```
|
||||
|
||||
### Q: 如何只运行某个测试?
|
||||
|
||||
A: 使用 `it.only()`:
|
||||
|
||||
```javascript
|
||||
it.only('只运行这个测试', () => {
|
||||
// 测试代码
|
||||
});
|
||||
```
|
||||
|
||||
## 贡献指南
|
||||
|
||||
提交 PR 时,请确保:
|
||||
|
||||
1. 所有测试通过:`npm test`
|
||||
2. 新功能有对应的测试
|
||||
3. 测试覆盖了正常情况和边界情况
|
||||
4. 代码编译通过:`npm run build`
|
||||
Reference in New Issue
Block a user