@@ -155,6 +155,104 @@ connection_timeout = 30
155155- Frontend: Tests in ` __tests__/ ` or ` .test.tsx ` files
156156- Smoke tests go in the ` smoke-test/ ` directory
157157
158+ #### Testing Principles: Focus on Value Over Coverage
159+
160+ ** IMPORTANT** : Quality over quantity. Avoid AI-generated test anti-patterns that create maintenance burden without providing real value.
161+
162+ ** Focus on behavior, not implementation** :
163+
164+ - ✅ Test what the code does (business logic, edge cases that occur in production)
165+ - ❌ Don't test how it does it (implementation details, private fields via reflection)
166+ - ❌ Don't test third-party libraries work correctly (Spring, Micrometer, Kafka clients, etc.)
167+ - ❌ Don't test Java/Python language features (` synchronized ` methods are thread-safe, ` @Nonnull ` parameters reject nulls)
168+
169+ ** Avoid these specific anti-patterns** :
170+
171+ - ❌ Testing null inputs on ` @Nonnull ` /` @NonNull ` annotated parameters
172+ - ❌ Verifying exact error message wording (creates brittleness during refactoring)
173+ - ❌ Testing every possible input variation (case sensitivity × whitespace × special chars = maintenance nightmare)
174+ - ❌ Using reflection to verify private implementation details
175+ - ❌ Redundant concurrency testing on ` synchronized ` methods
176+ - ❌ Testing obvious getter/setter behavior without business logic
177+ - ❌ Testing Lombok-generated code (` @Data ` , ` @Builder ` , ` @Value ` classes) - you're testing Lombok's code generator, not your logic
178+ - ❌ Testing that annotations exist on classes - if required annotations are missing, the framework/compiler will fail at startup, not in your tests
179+
180+ ** Appropriate test scope** :
181+
182+ - ** Simple utilities** (enums, string parsing, formatters): ~ 50-100 lines of focused tests
183+ - Happy path for each method
184+ - One example of invalid input per method
185+ - Edge cases likely to occur in production
186+ - ** Complex business logic** : Test proportional to risk and complexity
187+ - Integration points and system boundaries
188+ - Security-critical operations
189+ - Error handling for realistic failure scenarios
190+ - ** Warning sign** : If tests are 5x+ the size of implementation, reconsider scope
191+
192+ ** Examples of low-value tests to avoid** :
193+
194+ ``` java
195+ // ❌ BAD: Testing @Nonnull contract (framework's job)
196+ @Test
197+ public void testNullParameterThrowsException() {
198+ assertThrows(NullPointerException . class,
199+ () - > service. process(null )); // parameter is @Nonnull
200+ }
201+
202+ // ❌ BAD: Testing Lombok-generated code
203+ @Test
204+ public void testBuilderSetsAllFields() {
205+ MyConfig config = MyConfig . builder()
206+ .field1(" value1" )
207+ .field2(" value2" )
208+ .build();
209+ assertEquals(config. getField1(), " value1" );
210+ assertEquals(config. getField2(), " value2" );
211+ }
212+
213+ // ❌ BAD: Testing that annotations exist
214+ @Test
215+ public void testConfigurationAnnotations() {
216+ assertNotNull(MyConfig . class. getAnnotation(Configuration . class));
217+ assertNotNull(MyConfig . class. getAnnotation(ComponentScan . class));
218+ }
219+ // If @Configuration is missing, Spring won't load the context - you don't need a test for this
220+
221+ // ❌ BAD: Exact error message (brittle)
222+ assertEquals(exception. getMessage(),
223+ " Unsupported database type 'oracle'. Only PostgreSQL and MySQL variants are supported." );
224+
225+ // ❌ BAD: Redundant variations
226+ assertEquals(DatabaseType . fromString(" postgresql" ), DatabaseType . POSTGRES );
227+ assertEquals(DatabaseType . fromString(" PostgreSQL" ), DatabaseType . POSTGRES );
228+ assertEquals(DatabaseType . fromString(" POSTGRESQL" ), DatabaseType . POSTGRES );
229+ assertEquals(DatabaseType . fromString(" postgresql " ), DatabaseType . POSTGRES );
230+ // ... 10 more case/whitespace variations
231+
232+ // ✅ GOOD: Focused behavioral test
233+ @Test
234+ public void testFromString_ValidInputsCaseInsensitive() {
235+ assertEquals(DatabaseType . fromString(" postgresql" ), DatabaseType . POSTGRES );
236+ assertEquals(DatabaseType . fromString(" POSTGRESQL" ), DatabaseType . POSTGRES );
237+ assertEquals(DatabaseType . fromString(" postgresql " ), DatabaseType . POSTGRES );
238+ }
239+
240+ @Test
241+ public void testFromString_InvalidInputThrows() {
242+ assertThrows(IllegalArgumentException . class,
243+ () - > DatabaseType . fromString(" oracle" ));
244+ }
245+
246+ // ✅ GOOD: Testing YOUR custom validation logic on a Lombok class
247+ @Test
248+ public void testCustomValidation() {
249+ assertThrows(IllegalArgumentException . class,
250+ () - > MyConfig . builder(). field1(" invalid" ). build(). validate());
251+ }
252+ ```
253+
254+ ** When in doubt** : Ask "Does this test protect against a realistic regression?" If not, skip it.
255+
158256#### Security Testing: Configuration Property Classification
159257
160258** Critical test** : ` metadata-io/src/test/java/com/linkedin/metadata/system_info/collectors/PropertiesCollectorConfigurationTest.java `
0 commit comments