Setup and context
Writing test code is one of the most time-consuming aspects of software development. Creating unit tests, integration tests, and end-to-end tests requires deep understanding of business logic and extensive preparation. With Antigravity AI, you can dramatically accelerate the test creation process while improving code coverage across all testing levels.
Unit Test Generation Strategy
Unit tests verify the individual behavior of functions and class methods. When using Antigravity AI for test generation, the key is to accurately parse the source code structure and comprehensively cover edge cases.
Antigravity AI Prompt Strategy
You are an expert Jest test engineer. Analyze the following TypeScript function and generate comprehensive unit tests.
Function signature:
export function calculateShippingCost(weight: number, distance: number, isExpress: boolean): number
Requirements:
1. Generate 8-10 test cases covering normal, boundary, and edge cases
2. Include parametrized tests for different weight/distance combinations
3. Test error conditions (negative values, null inputs)
4. Use Jest matchers for clear assertions
5. Follow AAA pattern (Arrange, Act, Assert)
Output only valid Jest test code with describe/it blocks.When you submit this prompt to Antigravity's agent, it generates high-quality test code like this:
// Example unit tests following Jest conventions
describe('calculateShippingCost', () => {
describe('normal cases', () => {
it('should calculate standard shipping cost for domestic orders', () => {
// Arrange
const weight = 5;
const distance = 100;
const isExpress = false;
// Act
const result = calculateShippingCost(weight, distance, isExpress);
// Assert
expect(result).toBeGreaterThan(0);
expect(result).toBeLessThan(1000);
});
it('should apply express surcharge when isExpress is true', () => {
const standardCost = calculateShippingCost(5, 100, false);
const expressCost = calculateShippingCost(5, 100, true);
expect(expressCost).toBeGreaterThan(standardCost);
});
});
describe('boundary conditions', () => {
it('should handle zero weight correctly', () => {
expect(() => calculateShippingCost(0, 100, false)).not.toThrow();
});
it('should reject negative weight', () => {
expect(() => calculateShippingCost(-5, 100, false)).toThrow();
});
it('should handle maximum distance value', () => {
expect(calculateShippingCost(10, 5000, false)).toBeGreaterThan(0);
});
});
describe('edge cases', () => {
const testCases = [
{ weight: 0.1, distance: 1, isExpress: false },
{ weight: 1000, distance: 5000, isExpress: true },
{ weight: 50, distance: 0, isExpress: false }
];
test.each(testCases)(
'should handle edge case: weight=$weight, distance=$distance, isExpress=$isExpress',
({ weight, distance, isExpress }) => {
expect(() => calculateShippingCost(weight, distance, isExpress)).not.toThrow();
}
);
});
});Setting Coverage Targets
For unit tests, establish coverage goals in progressive stages:
- Statement Coverage: 80%+ — Every line of code is executed
- Branch Coverage: 75%+ — Both branches of if/else statements are tested
- Function Coverage: 90%+ — All functions are invoked
Antigravity AI automatically identifies coverage gaps and proposes additional test cases to bridge them.
Integration Testing Patterns
Integration tests verify interactions between multiple modules and services. When testing API endpoints, database connections, and external service integrations, mocking strategy becomes critical.
API Integration Tests with supertest
// Example API integration tests
const request = require('supertest');
const app = require('../src/app');
describe('POST /api/orders', () => {
it('should create a new order with valid payload', async () => {
const payload = {
customerId: 'cust-123',
items: [
{ productId: 'prod-001', quantity: 2 },
{ productId: 'prod-002', quantity: 1 }
],
shippingAddress: '123 Main St'
};
const response = await request(app)
.post('/api/orders')
.send(payload)
.expect(201);
expect(response.body).toHaveProperty('orderId');
expect(response.body.status).toBe('pending');
expect(response.body.total).toBeGreaterThan(0);
});
it('should validate required fields', async () => {
const invalidPayload = {
items: [] // Missing customerId and shippingAddress
};
await request(app)
.post('/api/orders')
.send(invalidPayload)
.expect(400);
});
it('should handle database errors gracefully', async () => {
// Set database mock to error state
jest.spyOn(global, 'db').mockRejectedValueOnce(new Error('DB unavailable'));
const payload = {
customerId: 'cust-123',
items: [{ productId: 'prod-001', quantity: 1 }],
shippingAddress: '123 Main St'
};
const response = await request(app)
.post('/api/orders')
.send(payload)
.expect(500);
expect(response.body.error).toBeDefined();
});
});Antigravity Agent Workflow
For integration test generation, we recommend this agent workflow:
- Dependency Mapping — Automatically extract dependencies between services
- Mock Strategy Decision — Determine which services should be mocked
- Test Scenario Generation — Auto-generate happy path, error, and edge case scenarios
- Assertion Design — Verify expected outputs and side effects
E2E Testing Strategy with Playwright
E2E tests validate actual user workflows at the browser level. Playwright enables cross-platform testing across multiple browsers with minimal overhead.
Automatic Playwright Test Generation
// Example Playwright E2E tests
import { test, expect } from '@playwright/test';
test.describe('E-commerce Checkout Flow', () => {
test.beforeEach(async ({ page }) => {
await page.goto('https://example.com/products');
});
test('should complete purchase from product search to order confirmation', async ({ page }) => {
// Search for product
await page.fill('input[placeholder="Search products"]', 'laptop');
await page.click('button:has-text("Search")');
await page.waitForSelector('[data-testid="product-card"]');
// Click first product
await page.click('[data-testid="product-card"]:first-child');
await expect(page).toHaveURL(/\/product\/\d+$/);
// Verify product details
const price = await page.textContent('[data-testid="price"]');
expect(price).toMatch(/\$\d+\.\d{2}/);
// Add to cart
await page.click('button:has-text("Add to Cart")');
const cartBadge = await page.textContent('[data-testid="cart-count"]');
expect(cartBadge).toBe('1');
// Navigate to checkout
await page.click('[data-testid="cart-icon"]');
await page.click('button:has-text("Proceed to Checkout")');
// Fill shipping information
await page.fill('input[name="address"]', '123 Main Street');
await page.fill('input[name="city"]', 'Springfield');
await page.selectOption('select[name="country"]', 'US');
// Fill payment information
const frameHandle = await page.$('iframe[title="Payment form"]');
const paymentFrame = await frameHandle.contentFrame();
await paymentFrame.fill('input[name="cardnumber"]', '4111111111111111');
// Place order
await page.click('button:has-text("Place Order")');
// Verify confirmation page
await expect(page).toHaveURL(/\/order-confirmation/);
const orderNumber = await page.textContent('[data-testid="order-number"]');
expect(orderNumber).toMatch(/ORD-\d+/);
});
test('should show error when payment fails', async ({ page }) => {
await page.goto('https://example.com/checkout');
await page.fill('input[name="address"]', '123 Main Street');
// Enter invalid card number
const frameHandle = await page.$('iframe[title="Payment form"]');
const paymentFrame = await frameHandle.contentFrame();
await paymentFrame.fill('input[name="cardnumber"]', '0000000000000000');
await page.click('button:has-text("Place Order")');
// Verify error message
const error = await page.textContent('[data-testid="payment-error"]');
expect(error).toContain('Payment failed');
});
test('should handle network timeouts gracefully', async ({ page }) => {
await page.route('**/api/checkout', route => route.abort('timedout'));
await page.goto('https://example.com/checkout');
await page.click('button:has-text("Place Order")');
// Expect timeout error
const errorMessage = await page.waitForSelector('[data-testid="error-message"]');
expect(errorMessage).toBeTruthy();
});
});Mutation Testing Concepts
Mutation testing is an advanced technique for evaluating test quality. It introduces intentional changes (mutations) to source code and verifies whether your tests detect them.
Antigravity AI integrates with mutation testing tools like Stryker to achieve:
- Test Effectiveness Score — How many mutations your tests catch
- Coverage Gap Identification — Code paths that aren't adequately tested
- Test Improvement Suggestions — New test cases for undetected mutations
// Mutation detection example
// Original code
function isEligibleForDiscount(age: number, purchaseAmount: number): boolean {
return age >= 65 && purchaseAmount > 100;
}
// Mutation 1: Change >= to >
// Test should detect: expect(isEligibleForDiscount(65, 150)).toBe(true)
// Mutation 2: Change && to ||
// Test should detect: expect(isEligibleForDiscount(65, 50)).toBe(false)Best Practices for Antigravity Agent Usage
- Progressive Test Design — Follow the sequence: unit tests → integration tests → E2E tests
- Explicit Prompts — Specify test target, coverage goals, and frameworks clearly
- Continuous Validation — Run and validate generated tests, establishing a feedback loop
- Coverage Monitoring — Integrate coverage measurement into your CI/CD pipeline
Conclusion
Antigravity AI dramatically shortens the test-driven development (TDD) cycle. Whether generating unit tests rapidly, automating integration test mocking strategies, or designing detailed E2E scenarios, AI assistance improves efficiency across all testing levels.
By achieving both high test quality and comprehensive coverage, you build more reliable software. Experience how Antigravity AI transforms your testing workflow today.