This comprehensive guide covers everything you need to know about software testing, from fundamental concepts to advanced practices and tools.
Tests individual components or functions in isolation, ensuring each unit of code performs its intended function correctly and independently. Here’s an example:
// Function to test
function calculateTax(income: number, taxRate: number): number {
if (income < 0 || taxRate < 0 || taxRate > 100) {
throw new Error('Invalid input parameters');
}
return (income * taxRate) / 100;
}
// Unit test
describe('calculateTax function', () => {
it('should correctly calculate tax for valid inputs', () => {
// Arrange
const income = 50000;
const taxRate = 20;
// Act
const result = calculateTax(income, taxRate);
// Assert
expect(result).toBe(10000);
});
it('should throw error for negative income', () => {
// Arrange
const income = -1000;
const taxRate = 20;
// Act & Assert
expect(() => calculateTax(income, taxRate))
.toThrow('Invalid input parameters');
});
it('should throw error for invalid tax rate', () => {
// Arrange
const income = 50000;
const taxRate = 101;
// Act & Assert
expect(() => calculateTax(income, taxRate))
.toThrow('Invalid input parameters');
});
});
Verifies that different components or services of an application work together correctly when integrated. This includes testing API interactions, database operations, and service communication. Here’s an example:
describe('User Registration Flow', () => {
it('should create user and send welcome email', async () => {
// Setup test database and email service
const db = new TestDatabase();
const emailService = new MockEmailService();
// Create user through API
const response = await request(app)
.post('/api/users')
.send({
email: '[email protected]',
password: 'password123'
});
// Verify user was created in database
const user = await db.users.findOne({
email: '[email protected]'
});
expect(user).toBeDefined();
expect(user.email).toBe('[email protected]');
// Verify welcome email was sent
expect(emailService.sentEmails).toContainEqual({
to: '[email protected]',
subject: 'Welcome to our platform!'
});
});
});
Tests the complete application flow from start to finish, simulating real user interactions across multiple components and services. This includes testing user journeys like registration, login, and core business operations. Here’s an example:
describe('E-commerce Purchase Flow', () => {
it('should complete full purchase journey', async () => {
// Login
await page.goto('/login');
await page.fill('#email', '[email protected]');
await page.fill('#password', 'password123');
await page.click('#login-button');
// Browse and add product to cart
await page.goto('/products');
await page.click('[data-testid="product-1"]');
await page.click('#add-to-cart');
// Checkout process
await page.goto('/cart');
await page.click('#checkout-button');
// Fill shipping details
await page.fill('#address', '123 Test St');
await page.fill('#city', 'Test City');
await page.fill('#zip', '12345');
// Payment
await page.fill('#card-number', '4242424242424242');
await page.fill('#expiry', '12/25');
await page.fill('#cvv', '123');
// Complete order
await page.click('#place-order');
// Verify success
const orderConfirmation = await page.textContent('#order-confirmation');
expect(orderConfirmation).toContain('Order placed successfully');
});
});