PromucFlow_constructor/.cursor/docs/references/testing-reference.md
vivek-appsmith d176e40726
refactor: restructure .cursor directory for improved organization and clarity (#40196)
# refactor: restructure .cursor directory for improved organization and
clarity

## Description

This PR refactors the `.cursor` directory to enhance organization,
clarity, and maintainability.

### Problem

The existing `.cursor` directory lacked clear organization, making it
difficult to find specific files, understand their purpose, and add new
components consistently.

### Solution

A comprehensive restructuring:

#### New Directory Structure

```
.cursor/
├── settings.json                  # Main configuration file
├── docs/                          # Documentation
│   ├── guides/                    # In-depth guides
│   ├── references/                # Quick references
│   └── practices/                 # Best practices
├── rules/                         # Rule definitions
│   ├── commit/                    # Commit-related rules
│   ├── quality/                   # Code quality rules
│   ├── testing/                   # Testing rules
│   └── verification/              # Verification rules
└── hooks/                         # Git hooks and scripts
```

#### Key Changes

1. **Logical Categorization**: Organized files into clear categories
based on purpose
2. **Improved Documentation**: Added comprehensive README files for each
directory
3. **Standardized Naming**: Implemented consistent kebab-case naming
convention
4. **Reference Updates**: Updated all internal references to point to
new file locations

### Benefits

- **Easier Navigation**: Clear categorization makes finding files
intuitive
- **Improved Understanding**: Comprehensive documentation explains
purpose and usage
- **Simplified Maintenance**: Logical structure makes updates and
additions easier
- **Better Onboarding**: New team members can quickly understand the
system

This refactoring sets a solid foundation for all Cursor AI-related
configurations and rules, making it easier for the team to leverage
Cursor's capabilities.
2025-04-11 12:04:33 +05:30

219 lines
6.1 KiB
Markdown

# Appsmith Testing Quick Reference
## Testing Requirements
### For Bug Fixes
1. **Unit Tests (Required)**
- Reproduce the bug scenario
- Verify the fix works correctly
- Test edge cases and potential regressions
- Place in the same directory as the fixed code with `.test.ts` extension
2. **End-to-End Tests (Required for user-facing changes)**
- Create a Cypress test that simulates the user action that would trigger the bug
- Verify the fix works correctly in the application context
- Place in `app/client/cypress/e2e/Regression/`
3. **Redux/React Safety Tests (For Redux/React code)**
- Test with both valid and null/undefined state structures
- Verify that property access is handled safely
- Test edge cases where nested properties might not exist
### For Feature Development
1. **Unit Tests (Required)**
- Test each component or function individually
- Cover the main functionality, edge cases, and error conditions
- Place alongside the implemented code
2. **Integration Tests (For complex features)**
- Test interactions between components
- Verify that data flows correctly between components
3. **End-to-End Tests (For user-facing features)**
- Simulate user interactions with the feature
- Verify that the feature works correctly in the application context
## Test File Locations
- **Unit Tests:** Same directory as the code being tested (e.g., `Component.test.tsx`)
- **Cypress E2E Tests:** `app/client/cypress/e2e/Regression/[Category]/[Feature]_spec.js`
- **Backend Tests:** `app/server/src/test/java/com/appsmith/server/...`
## Templates
### Unit Test for Bug Fix (React Component)
```typescript
import React from "react";
import { render, screen, fireEvent } from "@testing-library/react";
import MyComponent from "./MyComponent";
describe("MyComponent bug fix", () => {
it("should reproduce the bug scenario", () => {
// Arrange: Setup the conditions that trigger the bug
render(<MyComponent prop="value" />);
// Act: Perform the action that triggers the bug
fireEvent.click(screen.getByText("Button"));
// Assert: Verify the bug is fixed
expect(screen.getByText("Expected Result")).toBeInTheDocument();
});
it("should maintain existing functionality", () => {
// Test that related functionality still works
render(<MyComponent prop="otherValue" />);
expect(screen.getByText("Other Result")).toBeInTheDocument();
});
});
```
### E2E Test for Bug Fix
```javascript
describe("Feature Bug Fix", { tags: ["@tag.Bugfix", "@tag.Regression"] }, function() {
before(() => {
cy.login();
cy.createTestWorkspace();
});
it("should no longer exhibit the bug", () => {
// Steps to reproduce the bug
cy.get("[data-cy=element]").click();
cy.get("[data-cy=other-element]").type("value");
// Verify the bug is fixed
cy.get("[data-cy=result]").should("have.text", "Expected Result");
});
});
```
### Redux Safety Test
```typescript
import { configureStore } from '@reduxjs/toolkit';
import reducer, { selectUserData } from './userSlice';
import { renderHook } from '@testing-library/react-hooks';
import { Provider } from 'react-redux';
import React from 'react';
import { useSelector } from 'react-redux';
describe("Redux safety tests", () => {
// Test with missing nested properties
it("should handle missing nested properties safely", () => {
// Create store with incomplete state
const store = configureStore({
reducer: {
user: reducer
},
preloadedState: {
user: {
// Missing nested user data structure
}
}
});
// Test selector with missing data
const wrapper = ({ children }) => (
<Provider store={store}>{children}</Provider>
);
const { result } = renderHook(() => useSelector(selectUserData), { wrapper });
// Should not throw an error and return default/fallback value
expect(result.current).toEqual(/* expected default value */);
});
it("should handle deep property access safely", () => {
// Similar setup but with different state permutations
// Test various incomplete state structures
});
});
```
### Unit Test for Redux Sagas
```typescript
import { runSaga } from 'redux-saga';
import { mySaga } from './mySaga';
describe("mySaga", () => {
it("should dispatch expected actions", async () => {
// Mock dependencies
const dispatched = [];
const mockStore = {
dispatch: (action) => dispatched.push(action),
getState: () => ({ data: 'mock data' }),
};
// Run the saga
await runSaga(mockStore, mySaga, { payload: { id: '123' } }).toPromise();
// Assert expected actions were dispatched
expect(dispatched).toEqual([
{ type: 'SOME_ACTION', payload: 'mock data' },
]);
});
});
```
## Best Practices
1. **Test the User Experience**
- Focus on testing what the user sees and experiences
- Don't test implementation details unless necessary
2. **Use Descriptive Test Names**
- Tests should clearly describe what they're testing
- Use format: `should [expected behavior] when [condition]`
3. **Isolate Tests**
- Each test should be independent
- Don't rely on state from other tests
4. **Test Edge Cases**
- Empty input, invalid input, boundary conditions
- Error states and recovery
- Null/undefined in Redux state trees
- Missing nested properties
5. **Keep Tests Fast**
- Tests should run quickly to encourage frequent testing
- Use mocks for slow dependencies
6. **Test Coverage Guidelines**
- 80%+ coverage for critical paths
- Focus on business logic rather than UI details
7. **Redux/React Safety Testing**
- Test selectors with incomplete state structures
- Verify error boundaries catch property access errors
- Test with various state permutations to ensure robustness
## Running Tests
### Frontend Unit Tests
```bash
cd app/client
yarn test # Run all tests
yarn test:watch # Run in watch mode
yarn test:coverage # Generate coverage report
```
### Cypress E2E Tests
```bash
cd app/client
yarn cypress:open # Open Cypress UI
yarn cypress:run # Run headless
```
### Backend Tests
```bash
cd app/server
./mvnw test
```