You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Added testing guidelines section to the CONTRIBUTING.md (#61)
## Summary
<!-- Provide a brief description of the story behind this PR, as if
explaining
to a non-technical person. Or to an LLM so it can learn from it for
future (autonomous) code improvements. Feel free to point to a deeper
design doc, if applicable.
-->
Added instructions for what tests should look like and how they should
be implemented. This should help all developers working on this project
to use consistent testing schema.
## Connected Issues
<!-- Have you cared to connect this PR to a work item in DevRev, so that
we
can understand future routing and attribution?
-->
- [#ISS-202840](https://app.devrev.ai/devrev/works/ISS-202840)
- Place test files in the same directory as the source files
22
+
23
+
### Test Organization
24
+
25
+
Tests should be organized using `describe` and `it` blocks:
26
+
27
+
```typescript
28
+
describe(MyClass.name, () => {
29
+
it('should perform expected behavior when given valid input', () => {
30
+
// Test implementation
31
+
});
32
+
33
+
it('should handle specific scenario correctly', () => {
34
+
// Test implementation
35
+
});
36
+
37
+
it('[edge] should handle null input appropriately', () => {
38
+
// Edge case test
39
+
});
40
+
41
+
it('[edge] should handle undefined input appropriately', () => {
42
+
// Edge case test
43
+
});
44
+
});
45
+
```
46
+
47
+
### Test Naming Conventions
48
+
49
+
-**Describe blocks**: Name after the symbol being tested (class, function, etc.). Use the symbol's `.name` property when available instead of hardcoding the name (e.g., `MyClass.name` instead of `'MyClass'`)
50
+
-**It blocks**: Write descriptive test names that start with "should" and describe the expected behavior
51
+
-**Edge cases**: Prefix edge case tests with `[edge]` tag (e.g., `it('[edge] should handle null input...')`)
52
+
53
+
### Test Guidelines
54
+
55
+
1.**Single Responsibility**: Each test should verify only one specific behavior or outcome
56
+
2.**Descriptive Names**: Test names should clearly describe what functionality is being tested
57
+
3.**Behavior Testing**: Tests should verify behavior, not implementation details
58
+
4.**Edge Cases**: Handle `null`, `undefined`, and other edge cases using the `[edge]` tag prefix
59
+
5.**Simplicity**: Keep tests simple and easy to understand
60
+
6.**Clarity over Brevity**: Prioritize easily understandable tests over small tests. Tests typically represent 60-70% of a software project's source code, so clarity is essential
61
+
7.**Avoid Unnecessary Abstractions**: Minimize abstractions in tests unless absolutely necessary, as they add complexity and make it harder to understand the test steps
62
+
8.**AAA Pattern**: Follow the Arrange, Act, Assert pattern for test structure:
63
+
-**Arrange**: Set up test data, dependencies, and initial state
64
+
-**Act**: Execute the function or method being tested
65
+
-**Assert**: Verify the expected outcome or behavior
66
+
67
+
### Testing Scope and Focus
68
+
69
+
**Primary Focus: Public Interfaces**
70
+
- Tests should primarily focus on testing public-facing (exported) interfaces and APIs
71
+
- Test the behavior that external consumers of your code will experience
72
+
- This ensures that breaking changes to public contracts are caught by tests
73
+
74
+
**Internal Logic Testing**
75
+
- Be pragmatic about testing internal logic when it provides significant value
76
+
- Internal APIs used globally across the application may warrant dedicated test files
77
+
- Example: `metrics.spec.ts` tests the public endpoint controller, while `metrics.interceptor.spec.ts` tests internal API used globally
78
+
- You can rename or move test files later if they organically outgrow their original scope or no longer fit together
79
+
80
+
### Example
81
+
82
+
```typescript
83
+
describe(Calculator.name, () => {
84
+
it('should add two positive numbers correctly', () => {
85
+
// Arrange
86
+
const calculator =newCalculator();
87
+
const firstNumber =2;
88
+
const secondNumber =3;
89
+
const expectedResult =5;
90
+
91
+
// Act
92
+
const result =calculator.add(firstNumber, secondNumber);
0 commit comments