cqt-agent
Version:
604 lines (494 loc) • 21.4 kB
Markdown
**THIS IS AN EXECUTABLE WORKFLOW - NOT REFERENCE MATERIAL**
When this task is invoked:
1. **CODE ANALYSIS** - Analyze source code structure, dependencies, and logic flows
2. **TEST CASE GENERATION** - Create comprehensive test cases covering all scenarios
3. **FRAMEWORK-SPECIFIC IMPLEMENTATION** - Generate tests using appropriate testing frameworks
4. **QUALITY VALIDATION** - Ensure tests follow best practices and achieve high coverage
This workflow analyzes source code and generates high-quality unit tests using the appropriate testing framework for the technology stack. It creates comprehensive test suites covering normal cases, edge cases, and error scenarios.
- **file_path**: Absolute path to the source file to test
- **test_framework**: "vitest" | "jest" | "nunit" | "auto-detect"
- **coverage_target**: number (default: 90)
- **include_edge_cases**: boolean (default: true)
- **mock_dependencies**: boolean (default: true)
- **generate_integration_helpers**: boolean (default: true)
- **accessibility_tests**: boolean (default: true for components)
```yaml
step: analyze_source_code
description: Comprehensive analysis of source code to understand structure and behavior
code_analysis:
- structure_analysis:
- function_identification: Extract all functions, methods, and exports
- dependency_mapping: Map imports, external dependencies, and internal modules
- type_analysis: Analyze TypeScript types, interfaces, and props
- complexity_assessment: Evaluate cyclomatic complexity and edge cases
- behavior_analysis:
- input_output_mapping: Identify function inputs and expected outputs
- side_effect_detection: Find state mutations, API calls, DOM manipulation
- error_conditions: Identify potential error scenarios and exceptions
- async_patterns: Detect promises, async/await, callbacks
- framework_detection:
- component_analysis: React/Vue component props, state, lifecycle
- service_analysis: Business logic, data processing, API services
- utility_analysis: Pure functions, helpers, transformations
- hook_analysis: Custom hooks, state management patterns
```
```yaml
step: design_test_cases
description: Create comprehensive test scenarios covering all code paths
test_case_design:
- happy_path_scenarios:
- normal_inputs: Standard use cases with expected inputs
- typical_workflows: Common user interactions and data flows
- success_conditions: Verify correct behavior under normal conditions
- expected_outputs: Validate return values and side effects
- edge_case_scenarios:
- boundary_conditions: Min/max values, empty/null inputs
- unusual_inputs: Special characters, extreme values, type mismatches
- state_transitions: Component lifecycle, state changes
- timing_conditions: Race conditions, delayed responses
- error_scenarios:
- invalid_inputs: Malformed data, wrong types, missing parameters
- network_failures: API errors, timeout conditions
- permission_errors: Authentication, authorization failures
- system_errors: Out of memory, file system issues
- integration_scenarios:
- dependency_interactions: How component interacts with dependencies
- event_handling: User events, system events, custom events
- data_flow_testing: Props down, events up patterns
- context_usage: React Context, global state interactions
```
```yaml
step: develop_mocking_strategy
description: Create comprehensive mocking strategy for dependencies and external services
mocking_strategy:
- dependency_mocking:
- external_apis: HTTP clients, REST services, GraphQL
- database_access: ORMs, query builders, direct DB connections
- file_system: File operations, configuration loading
- third_party_libraries: Payment gateways, analytics, notifications
- component_mocking:
- child_components: Mock complex child components
- custom_hooks: Mock custom hook implementations
- context_providers: Mock React Context providers
- higher_order_components: Mock HOC wrapping
- service_mocking:
- business_services: Core business logic services
- utility_services: Logging, caching, validation
- infrastructure_services: Message queues, event buses
- configuration_services: Environment, feature flags
```
```yaml
step: generate_test_implementation
description: Generate framework-specific test implementations with best practices
implementation_generation:
- test_structure:
- describe_blocks: Logical grouping of related tests
- test_organization: Clear naming and categorization
- setup_teardown: Proper before/after hooks
- test_isolation: Independent test execution
- assertion_patterns:
- behavior_assertions: Verify actual behavior vs expected
- state_assertions: Check component/service state changes
- interaction_assertions: Verify function calls and parameters
- output_assertions: Validate return values and side effects
- framework_specific:
- vitest_patterns: Vitest-specific utilities and matchers
- testing_library: Component testing with user events
- nunit_patterns: .NET testing patterns and attributes
- async_testing: Promise/async handling patterns
```
```typescript
// Generated test for React component
import { render, screen, fireEvent, waitFor } from '@testing-library/react'
import { vi, describe, it, expect, beforeEach } from 'vitest'
import { UserDashboard } from '../UserDashboard'
import { useAuth } from '../hooks/useAuth'
import { fetchUserData } from '../services/userService'
// Mock dependencies
vi.mock('../hooks/useAuth')
vi.mock('../services/userService')
const mockUseAuth = vi.mocked(useAuth)
const mockFetchUserData = vi.mocked(fetchUserData)
describe('UserDashboard', () => {
const defaultProps = {
userId: 'user123',
onUserUpdate: vi.fn(),
theme: 'light'
}
beforeEach(() => {
vi.clearAllMocks()
mockUseAuth.mockReturnValue({
user: { id: 'user123', name: 'John Doe', role: 'user' },
isAuthenticated: true,
loading: false
})
})
describe('Rendering', () => {
it('should render user dashboard with user information', () => {
render(<UserDashboard {...defaultProps} />)
expect(screen.getByText('Welcome, John Doe')).toBeInTheDocument()
expect(screen.getByRole('main')).toHaveAttribute('aria-label', 'User Dashboard')
})
it('should show loading state when user data is loading', () => {
mockUseAuth.mockReturnValue({
user: null,
isAuthenticated: true,
loading: true
})
render(<UserDashboard {...defaultProps} />)
expect(screen.getByRole('progressbar')).toBeInTheDocument()
expect(screen.getByText('Loading dashboard...')).toBeInTheDocument()
})
it('should handle unauthenticated state', () => {
mockUseAuth.mockReturnValue({
user: null,
isAuthenticated: false,
loading: false
})
render(<UserDashboard {...defaultProps} />)
expect(screen.getByText('Please log in to access your dashboard')).toBeInTheDocument()
})
})
describe('User Interactions', () => {
it('should call onUserUpdate when profile is edited', async () => {
render(<UserDashboard {...defaultProps} />)
const editButton = screen.getByRole('button', { name: /edit profile/i })
fireEvent.click(editButton)
const nameInput = screen.getByLabelText(/name/i)
fireEvent.change(nameInput, { target: { value: 'Jane Doe' } })
const saveButton = screen.getByRole('button', { name: /save/i })
fireEvent.click(saveButton)
await waitFor(() => {
expect(defaultProps.onUserUpdate).toHaveBeenCalledWith({
id: 'user123',
name: 'Jane Doe',
role: 'user'
})
})
})
it('should handle keyboard navigation', () => {
render(<UserDashboard {...defaultProps} />)
const dashboard = screen.getByRole('main')
fireEvent.keyDown(dashboard, { key: 'Tab' })
expect(screen.getByRole('button', { name: /edit profile/i })).toHaveFocus()
})
})
describe('Data Fetching', () => {
it('should fetch user data on mount', async () => {
mockFetchUserData.mockResolvedValue({
profile: { avatar: 'avatar.jpg', preferences: {} },
stats: { loginCount: 42 }
})
render(<UserDashboard {...defaultProps} />)
expect(mockFetchUserData).toHaveBeenCalledWith('user123')
await waitFor(() => {
expect(screen.getByText('Login Count: 42')).toBeInTheDocument()
})
})
it('should handle fetch errors gracefully', async () => {
mockFetchUserData.mockRejectedValue(new Error('Network error'))
render(<UserDashboard {...defaultProps} />)
await waitFor(() => {
expect(screen.getByText('Unable to load dashboard data')).toBeInTheDocument()
})
})
})
describe('Accessibility', () => {
it('should have proper ARIA labels and roles', () => {
render(<UserDashboard {...defaultProps} />)
expect(screen.getByRole('main')).toHaveAttribute('aria-label', 'User Dashboard')
expect(screen.getByRole('button', { name: /edit profile/i })).toBeInTheDocument()
expect(screen.getByLabelText(/user statistics/i)).toBeInTheDocument()
})
it('should announce loading state to screen readers', () => {
mockUseAuth.mockReturnValue({
user: null,
isAuthenticated: true,
loading: true
})
render(<UserDashboard {...defaultProps} />)
expect(screen.getByRole('progressbar')).toHaveAttribute('aria-label', 'Loading dashboard')
})
})
describe('Error Boundaries', () => {
it('should handle component errors gracefully', () => {
const ThrowingComponent = () => {
throw new Error('Test error')
}
const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {})
expect(() => {
render(
<UserDashboard {...defaultProps}>
<ThrowingComponent />
</UserDashboard>
)
}).not.toThrow()
consoleSpy.mockRestore()
})
})
})
```
```csharp
// Generated test for .NET service
using NUnit.Framework;
using Moq;
using FluentAssertions;
using Microsoft.Extensions.Logging;
using Hubtel.Services;
using Hubtel.Models;
using Hubtel.Exceptions;
namespace Hubtel.Tests.Services
{
[]
public class PaymentServiceTests
{
private Mock<IPaymentGateway> _mockPaymentGateway;
private Mock<IUserRepository> _mockUserRepository;
private Mock<ILogger<PaymentService>> _mockLogger;
private PaymentService _paymentService;
[]
public void Setup()
{
_mockPaymentGateway = new Mock<IPaymentGateway>();
_mockUserRepository = new Mock<IUserRepository>();
_mockLogger = new Mock<ILogger<PaymentService>>();
_paymentService = new PaymentService(
_mockPaymentGateway.Object,
_mockUserRepository.Object,
_mockLogger.Object
);
}
[]
public void TearDown()
{
_paymentService?.Dispose();
}
[]
public class ProcessPaymentMethod : PaymentServiceTests
{
private PaymentRequest _validPaymentRequest;
private User _validUser;
[]
public void ProcessPaymentSetup()
{
_validPaymentRequest = new PaymentRequest
{
UserId = "user123",
Amount = 100.00m,
Currency = "USD",
PaymentMethod = "credit_card",
Description = "Test payment"
};
_validUser = new User
{
Id = "user123",
Email = "test@example.com",
IsActive = true,
PaymentMethodsEnabled = true
};
}
[]
public async Task ProcessPayment_WithValidRequest_ShouldReturnSuccessResult()
{
// Arrange
_mockUserRepository
.Setup(x => x.GetByIdAsync("user123"))
.ReturnsAsync(_validUser);
_mockPaymentGateway
.Setup(x => x.ProcessPaymentAsync(It.IsAny<PaymentRequest>()))
.ReturnsAsync(new PaymentResult
{
Success = true,
TransactionId = "txn123",
Status = PaymentStatus.Completed
});
// Act
var result = await _paymentService.ProcessPaymentAsync(_validPaymentRequest);
// Assert
result.Should().NotBeNull();
result.Success.Should().BeTrue();
result.TransactionId.Should().NotBeNullOrEmpty();
result.Status.Should().Be(PaymentStatus.Completed);
}
[]
public async Task ProcessPayment_WithInvalidUser_ShouldThrowUserNotFoundException()
{
// Arrange
_mockUserRepository
.Setup(x => x.GetByIdAsync("invalid_user"))
.ReturnsAsync((User)null);
var invalidRequest = _validPaymentRequest with { UserId = "invalid_user" };
// Act & Assert
var exception = await Assert.ThrowsAsync<UserNotFoundException>(
() => _paymentService.ProcessPaymentAsync(invalidRequest)
);
exception.UserId.Should().Be("invalid_user");
exception.Message.Should().Contain("User not found");
}
[]
[]
[]
public async Task ProcessPayment_WithInvalidAmount_ShouldThrowInvalidPaymentException(decimal invalidAmount)
{
// Arrange
var invalidRequest = _validPaymentRequest with { Amount = invalidAmount };
_mockUserRepository
.Setup(x => x.GetByIdAsync("user123"))
.ReturnsAsync(_validUser);
// Act & Assert
var exception = await Assert.ThrowsAsync<InvalidPaymentException>(
() => _paymentService.ProcessPaymentAsync(invalidRequest)
);
exception.Message.Should().Contain("Amount must be greater than zero");
}
[]
public async Task ProcessPayment_WithInactiveUser_ShouldThrowUserNotActiveException()
{
// Arrange
var inactiveUser = _validUser with { IsActive = false };
_mockUserRepository
.Setup(x => x.GetByIdAsync("user123"))
.ReturnsAsync(inactiveUser);
// Act & Assert
var exception = await Assert.ThrowsAsync<UserNotActiveException>(
() => _paymentService.ProcessPaymentAsync(_validPaymentRequest)
);
exception.UserId.Should().Be("user123");
}
[]
public async Task ProcessPayment_WhenGatewayFails_ShouldReturnFailureResult()
{
// Arrange
_mockUserRepository
.Setup(x => x.GetByIdAsync("user123"))
.ReturnsAsync(_validUser);
_mockPaymentGateway
.Setup(x => x.ProcessPaymentAsync(It.IsAny<PaymentRequest>()))
.ReturnsAsync(new PaymentResult
{
Success = false,
ErrorCode = "GATEWAY_ERROR",
ErrorMessage = "Payment gateway unavailable"
});
// Act
var result = await _paymentService.ProcessPaymentAsync(_validPaymentRequest);
// Assert
result.Should().NotBeNull();
result.Success.Should().BeFalse();
result.ErrorCode.Should().Be("GATEWAY_ERROR");
result.ErrorMessage.Should().Contain("gateway unavailable");
}
[]
public async Task ProcessPayment_ShouldLogPaymentAttempt()
{
// Arrange
_mockUserRepository
.Setup(x => x.GetByIdAsync("user123"))
.ReturnsAsync(_validUser);
_mockPaymentGateway
.Setup(x => x.ProcessPaymentAsync(It.IsAny<PaymentRequest>()))
.ReturnsAsync(new PaymentResult { Success = true, TransactionId = "txn123" });
// Act
await _paymentService.ProcessPaymentAsync(_validPaymentRequest);
// Assert
_mockLogger.Verify(
x => x.Log(
LogLevel.Information,
It.IsAny<EventId>(),
It.Is<It.IsAnyType>((v, t) => v.ToString().Contains("Processing payment for user")),
It.IsAny<Exception>(),
It.IsAny<Func<It.IsAnyType, Exception, string>>()
),
Times.Once
);
}
}
[]
public class ValidatePaymentRequestMethod : PaymentServiceTests
{
[]
public void ValidatePaymentRequest_WithValidRequest_ShouldNotThrow()
{
// Arrange
var validRequest = new PaymentRequest
{
UserId = "user123",
Amount = 50.00m,
Currency = "USD",
PaymentMethod = "credit_card"
};
// Act & Assert
Assert.DoesNotThrow(() => _paymentService.ValidatePaymentRequest(validRequest));
}
[]
[]
[]
public void ValidatePaymentRequest_WithInvalidUserId_ShouldThrowArgumentException(string invalidUserId)
{
// Arrange
var invalidRequest = new PaymentRequest
{
UserId = invalidUserId,
Amount = 50.00m,
Currency = "USD",
PaymentMethod = "credit_card"
};
// Act & Assert
var exception = Assert.Throws<ArgumentException>(
() => _paymentService.ValidatePaymentRequest(invalidRequest)
);
exception.Message.Should().Contain("UserId cannot be null or empty");
}
[]
[]
[]
public void ValidatePaymentRequest_WithInvalidCurrency_ShouldThrowArgumentException(string invalidCurrency)
{
// Arrange
var invalidRequest = new PaymentRequest
{
UserId = "user123",
Amount = 50.00m,
Currency = invalidCurrency,
PaymentMethod = "credit_card"
};
// Act & Assert
var exception = Assert.Throws<ArgumentException>(
() => _paymentService.ValidatePaymentRequest(invalidRequest)
);
exception.Message.Should().Contain("Invalid currency code");
}
}
}
}
```
- ✅ **AAA Pattern**: Arrange, Act, Assert structure
- ✅ **Descriptive Names**: Clear test method and describe block names
- ✅ **Single Responsibility**: Each test validates one specific behavior
- ✅ **Test Isolation**: Tests can run independently in any order
- ✅ **Proper Mocking**: Dependencies are properly mocked and verified
- ✅ **Edge Cases**: Boundary conditions and error scenarios covered
- ✅ **Accessibility**: Components tested for a11y compliance
- ✅ **Async Handling**: Promises and async operations properly tested
- **Line Coverage**: Target 90%+ for generated tests
- **Branch Coverage**: All conditional paths tested
- **Function Coverage**: All exported functions tested
- **Statement Coverage**: All executable statements covered
This comprehensive unit test generator creates high-quality, maintainable tests that follow best practices and achieve excellent coverage across different testing frameworks.