✅ Improve test coverage and reduce mock dependency
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 5/5
- Thời gian dự kiến
- Hơn một tuần
- Mức phù hợp với người mới
- 28/100
- Loại issue
- Tái cấu trúc
- Độ rõ ràng
- Cần làm rõ
- Mức độ hoạt động
- Đình trệ
- Công nghệ
- git, javascript
- Lĩnh vực
- testing
Hướng nghiên cứu
Bắt đầu với tests/index.test.js và mục 5 trong báo cáo phân tích chất lượng tại claudedocs/quality-analysis-report.md để hiểu các thiếu sót hiện tại về mocking và coverage. Xem xét các bài kiểm thử dịch vụ và cấu hình hiện có trước khi quyết định những bài kiểm thử lỗi, trường hợp biên và tích hợp tùy chọn nào là khả thi. Được coi là hoàn tất khi các bộ kiểm thử đã thống nhất vượt qua một cách ổn định, coverage vượt quá 80% và việc thiết lập kiểm thử tích hợp được ghi lại trong tests/README.md.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Problem
Current test suite has good coverage but relies heavily on mocks, which can hide integration issues. Several critical scenarios are untested.
Current issues:
- Heavy mocking of major functions (
getGitSummary,gptCommit) - Tests validate mock calls rather than actual behavior
- No integration tests with real OpenAI API
- Missing error scenario coverage
- No tests for edge cases
Test Coverage Gaps
1. Missing Error Scenarios
// Currently untested:
❌ OpenAI API errors (rate limits, invalid keys, timeouts)
❌ Config file corruption or invalid JSON
❌ Concurrent access to config file
❌ Network timeout scenarios
❌ Edge cases in git diff parsing (empty files, binary files, huge diffs)
❌ API response validation (malformed responses)
2. Heavy Mocking Issues
Current test pattern (tests/index.test.js):
const result = gitGptCommit.getGitSummary()
expect(result).toBeTruthy()
expect(gitGptCommit.getGitSummary).toHaveBeenCalled() // ⚠️ Only tests mock call
Problem: Tests pass even if actual implementation is broken.
3. No Integration Tests
No tests verify:
- Actual OpenAI API integration
- Real git repository operations
- End-to-end commit workflow
- Config file persistence across runs
Proposed Improvements
1. Add Error Scenario Tests
// tests/error-handling.test.js
describe('Error Handling', () => {
it('should handle OpenAI rate limit errors', async () => {
const mockError = new Error('Rate limit exceeded')
mockError.status = 429
vi.mocked(openai.chat.completions.create).mockRejectedValueOnce(mockError)
await expect(gptCommit()).rejects.toThrow('Rate limit')
})
it('should handle invalid API key errors', async () => {
const mockError = new Error('Invalid API key')
mockError.status = 401
vi.mocked(openai.chat.completions.create).mockRejectedValueOnce(mockError)
await expect(gptCommit()).rejects.toThrow('Invalid API key')
})
it('should handle network timeout errors', async () => {
const mockError = new Error('Network timeout')
mockError.code = 'ETIMEDOUT'
vi.mocked(exec).mockRejectedValueOnce(mockError)
await expect(getGitSummary()).rejects.toThrow('Network')
})
it('should handle corrupted config file', () => {
fs.writeFileSync(CONFIG_FILE, 'invalid json {{{')
expect(() => loadConfig()).not.toThrow()
expect(model).toBe('gpt-5-mini') // Should use default
})
})
2. Add Integration Tests (Optional)
// tests/integration/openai.integration.test.js
describe('OpenAI Integration', () => {
// Only runs if OPENAI_API_KEY is set
const skipIfNoApiKey = process.env.OPENAI_API_KEY ? test : test.skip
skipIfNoApiKey('should generate valid commit messages', async () => {
const testDiff = fs.readFileSync('fixtures/sample-diff.txt', 'utf8')
// Use real OpenAI API
const message = await generateCommitMessage(testDiff)
expect(message).toBeDefined()
expect(message.length).toBeGreaterThan(10)
expect(message.length).toBeLessThan(200)
}, 10000) // 10s timeout for API call
skipIfNoApiKey('should respect language setting', async () => {
const testDiff = 'diff --git a/file.js...'
const englishMessage = await generateCommitMessage(testDiff, 'English')
const japaneseMessage = await generateCommitMessage(testDiff, '日本語')
// Basic validation that language is respected
expect(japaneseMessage).toMatch(/[\u3000-\u303f\u3040-\u309f\u30a0-\u30ff]/)
}, 10000)
})
3. Add Edge Case Tests
// tests/edge-cases.test.js
describe('Edge Cases', () => {
it('should handle empty git diff', async () => {
vi.mocked(exec).mockResolvedValueOnce({ stdout: '' })
const result = await getGitSummary()
expect(result).toBeNull()
})
it('should handle huge git diff', async () => {
const hugeDiff = 'diff --git...\n'.repeat(10000) // Very large diff
vi.mocked(exec).mockResolvedValueOnce({ stdout: hugeDiff })
// Should validate size and possibly warn or truncate
await expect(getGitSummary()).rejects.toThrow('too large')
})
it('should handle binary file diffs', async () => {
const binaryDiff = 'Binary files differ\n'
vi.mocked(exec).mockResolvedValueOnce({ stdout: binaryDiff })
const result = await getGitSummary()
expect(result).toBeDefined()
})
it('should handle diff with sensitive data patterns', async () => {
const sensitiveDiff = 'diff --git\n+const API_KEY = "secret123"'
vi.mocked(exec).mockResolvedValueOnce({ stdout: sensitiveDiff })
// Should warn user about sensitive data
const consoleSpy = vi.spyOn(console, 'warn')
await getGitSummary()
expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining('sensitive'))
})
})
4. Reduce Mocking in Core Tests
// tests/sanitization.test.js - Good example (no mocks)
describe('sanitizeCommitMessage', () => {
it('should remove dangerous characters', () => {
const input = 'feat: add feature!@#$%^&*()'
const output = sanitizeCommitMessage(input)
expect(output).toBe('feat: add feature')
})
})
// tests/services/GitService.test.js - Test real logic
describe('GitService', () => {
it('should construct correct git diff command', () => {
const service = new GitService()
const command = service.buildDiffCommand()
expect(command).toContain('git diff --cached')
expect(command).toContain(':(exclude)*lock.json')
})
})
Test Organization
tests/
├─ unit/ # Pure unit tests (no mocks)
│ ├─ utils/
│ │ └─ sanitize.test.js
│ ├─ services/
│ │ ├─ OpenAIService.test.js
│ │ ├─ GitService.test.js
│ │ └─ ConfigService.test.js
│ └─ validators.test.js
├─ integration/ # Integration tests (optional)
│ ├─ openai.integration.test.js
│ └─ e2e.integration.test.js
├─ error-scenarios/ # Error handling tests
│ ├─ api-errors.test.js
│ ├─ config-errors.test.js
│ └─ network-errors.test.js
└─ edge-cases/ # Edge case tests
├─ large-diffs.test.js
├─ binary-files.test.js
└─ sensitive-data.test.js
Benefits
- ✅ Better confidence in code correctness
- ✅ Catch integration issues before production
- ✅ Validate error handling actually works
- ✅ Reduce false confidence from mocks
- ✅ Better regression prevention
Acceptance Criteria
- Add error scenario test suite (10+ tests)
- Add edge case test suite (10+ tests)
- Optional: Add integration test suite (gated by env var)
- Reduce mocking in existing tests where possible
- Achieve >80% code coverage
- All tests pass reliably
- Document how to run integration tests
Priority
Medium-High - Prevents bugs from reaching users
Related
Quality analysis report: claudedocs/quality-analysis-report.md section 5
Notes
- Integration tests should be optional (gated by
OPENAI_API_KEYenv var) - Consider using fixtures for consistent test data
- Add test timeout configurations for API calls
- Document test organization in tests/README.md
- Ngôn ngữ chính
- JavaScript
- Star
- 36
- Fork
- 3
- Chỉ số merge pull request
- Không có pull request nào được merge trong 30 ngày
Chuẩn bị môi trường
Dự án này không cung cấp dev container, Dockerfile hay hướng dẫn đóng góp, nên bạn cần tự thiết lập môi trường: hãy bắt đầu từ README và xem hướng dẫn đóng góp lần đầu của chúng tôi để biết các bước chung.
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của laststance/git-gpt-commit
-
fix error with giant diffĐang mở
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 25/100
laststance/git-gpt-commit#75 ·
-
enhancement low-priority performance
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 35/100
laststance/git-gpt-commit#72 ·
-
enhancement low-priority standards
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 25/100
laststance/git-gpt-commit#70 ·
-
documentation good first issue medium-priority
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 45/100
laststance/git-gpt-commit#69 ·
-
architecture high-priority refactoring
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 30/100
laststance/git-gpt-commit#67 ·
Tất cả issue của laststance/git-gpt-commit
Issue tương tự
-
bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
openlibhums/janeway#5604 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
[BUG] Generic OSC does not initialize OSC client on startup when "Listen for Feedback" is disabledĐang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 86/100
-
area/statement-execution TS conversion
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 76/100
scylladb/nodejs-rs-driver#584 ·
Maintainer thường phản hồi trong vòng 2 ngày
-
新讀者走讀回報,照著一篇文章實際操作Đang mởdocumentation good first issue help wanted
Độ khó 1/5 1-3 giờ Mức phù hợp với người mới 92/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 69/100
Maintainer thường phản hồi trong vòng 3 ngày