.github/skills/test-writing/SKILL.md
This skill focuses on writing/designing effective and comprehensive tests for code. It emphasizes the importance of covering various scenarios, including happy cases, error cases, edge cases, and input validation. The skill also highlights the need to write tests based on expected correct behavior rather than current implementation, and to maintain a high level of coverage (at least 80%).
npx skillsauth add sonht1109/vscode-copilot-kit test-writingInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Correctness: Test on function behavior, not implementation. If the function is wrong, create tests based on the expected behavior, not the actual implementation and report the issue to the user.
Execution: Always run the test file after creating or editing it to ensure it works as intended.
IMPORTANT: Should always group similar cases if possible into a single test using loops or parameterized tests to avoid redundancy and improve maintainability. Eg:
// GOOD
describe('should throw error if input is invalid', () => {
it.each([
{ input: null, description: 'null' },
{ input: undefined, description: 'undefined' },
{ input: '', description: 'empty string' },
{ input: 123, description: 'number' },
{ input: {}, description: 'object' },
])('throws error for $description input', ({ input }) => {
expect(() => {
myFunction(input);
}).toThrow('Invalid input');
});
});
// BAD
describe('should throw error if input is invalid', () => {
it('throws error for null input', () => {
expect(() => {
myFunction(null);
}).toThrow('Invalid input');
});
it('throws error for undefined input', () => {
expect(() => {
myFunction(undefined);
}).toThrow('Invalid input');
});
it('throws error for empty string input', () => {
expect(() => {
myFunction('');
}).toThrow('Invalid input');
});
// ...
});
Coverage: Make sure coverage is at least 80%.
Meaningful Test Names: Use descriptive names for test cases that clearly indicate what is being tested and the expected outcome. Description and expectation must match.
// GOOD
it('should propagate error from database', async () => {
const mockError = new Error('Database error');
database.query.mockRejectedValue(mockError);
await expect(myFunction()).rejects.toThrow('Database error');
expect(database.query).toHaveBeenCalledWith(expectedQuery);
});
// BAD: those errors are mocked errors, we should not validate the result of the mocked function.
// Just merge those into one genric test case for error handling, no need to validate the specific error message, just validate the call to the mocked function.
it('should throw if query is timeout', async () => {
const mockError = new Error('query timeout');
database.query.mockRejectedValue(mockError);
await expect(myFunction()).rejects.toThrow('query timeout');
expect(database.query).toHaveBeenCalledWith(expectedQuery);
});
it('should throw if database is down', async () => {
const mockError = new Error('database is down');
database.query.mockRejectedValue(mockError);
await expect(myFunction()).rejects.toThrow('database is down');
expect(database.query).toHaveBeenCalledWith(expectedQuery);
});
// GOOD
it('should return correct result', async () => {
const mockResult = { id: 1, name: 'Test' };
database.query.mockResolvedValue(mockResult);
const result = await myFunction();
expect(result).toEqual(mockResult);
expect(database.query).toHaveBeenCalledWith(expectedQuery);
});
// BAD: those results are mocked results, we should not validate the result of the mocked function
// Just merge those into one genric test case for correct result, no need to validate the specific result, just validate the call to the mocked function.
it('should return correct result', async () => {
const mockResult = { id: 1, name: 'Test' };
database.query.mockResolvedValue(mockResult);
const result = await myFunction();
expect(result).toEqual(mockResult);
expect(database.query).toHaveBeenCalledWith(expectedQuery);
});
it('result should have correct name', async () => {
const mockResult = { id: 1, name: 'Test' };
database.query.mockResolvedValue(mockResult);
const result = await myFunction();
expect(result.name).toBe('Test');
expect(database.query).toHaveBeenCalledWith(expectedQuery);
});
If its unitest, focus on creating unit tests that isolate individual functions or components to verify their behavior in isolation. Do mock on other dependencies if necessary.
If its integration test or API test:
development
This skill focuses on writing/designing effective and comprehensive tests for code. It emphasizes the importance of covering various scenarios, including happy cases, error cases, edge cases, and input validation. The skill also highlights the need to write tests based on expected correct behavior rather than current implementation, and to maintain a high level of coverage (at least 80%).
content-media
Use when complex problems require systematic step-by-step reasoning with ability to revise thoughts, branch into alternative approaches, or dynamically adjust scope. Ideal for multi-stage analysis, design planning, problem decomposition, or tasks with initially unclear scope. DO NOT use when single-step answers suffice.
tools
--- name: sentry description: Guide for using the Sentry CLI to interact with Sentry from the command line. Use when the user asks about viewing issues, events, projects, organizations, making API calls, or authenticating with Sentry via CLI. Primary workflow: given a short issue ID (e.g. PROJECT-123), fetch full bug report with description and stack trace. --- # Sentry CLI Skill This skill handles Sentry CLI operations: authentication, issue lookup by short ID, event details, and bug report g
documentation
Use when doing tasks related to markdown files, such as editing README.md or other documentation files.