Modern software testing requires more than just manual clicking and exploratory testing. Today’s QA engineers need powerful development environments, specialized extensions, and debugging tools to write automated tests, analyze network traffic, and investigate bugs efficiently. This comprehensive guide covers the essential IDEs, extensions, and tools that every tester should master.
Table of Contents
- VS Code for QA Engineers
- IntelliJ IDEA for Testing
- Browser DevTools Mastery
- Proxy Tools: Charles and Fiddler
- Choosing the Right Tools
VS Code for QA Engineers
Visual Studio Code has become the go-to editor for many testers due to its lightweight nature, extensive extension marketplace, and excellent support for multiple programming languages. Let’s explore how to transform VS Code into a powerful testing environment.
Essential Extensions for Testers
1. Test Runner Extensions
Jest Runner
- Direct integration with Jest testing framework
- Run individual tests or test suites with one click
- Display test results inline in the editor
- Debug tests directly from the editor
Installation:
code --install-extension Orta.vscode-jest
Configuration in .vscode/settings.json
:
{
"jest.autoRun": "off",
"jest (as discussed in [From Manual to Automation: Complete Transition Guide for QA Engineers](/blog/manual-to-automation-transition)).showCoverageOnLoad": true,
"jest.coverageFormatter": "DefaultFormatter",
"jest.debugMode": true
}
Test Explorer UI
- Unified test explorer for multiple frameworks
- Supports Jest, Mocha, Pytest, JUnit, and more
- Tree view of all tests with pass/fail indicators
- Quick navigation to test definitions
code --install-extension hbenl.vscode-test-explorer
Playwright Test for VSCode
- Run Playwright tests directly from VS Code
- Pick locators with visual selector tool
- Record tests with codegen integration
- Debug with breakpoints
code --install-extension ms-playwright.playwright
Configuration example:
{
"playwright.reuseBrowser": true,
"playwright (as discussed in [Cloud Testing Platforms: Complete Guide to BrowserStack, Sauce Labs, AWS Device Farm & More](/blog/cloud-testing-platforms)).showTrace": true,
"playwright.env": {
"HEADLESS": "false"
}
}
2. Code Quality and Linting
ESLint Essential for JavaScript/TypeScript test code quality:
code --install-extension dbaeumer.vscode-eslint
.eslintrc.js
for test files:
module.exports = {
env: {
node: true,
jest: true,
mocha: true
},
extends: [
'eslint:recommended',
'plugin:jest/recommended'
],
rules: {
'jest/no-disabled-tests': 'warn',
'jest/no-focused-tests': 'error',
'jest/valid-expect': 'error'
}
}
Prettier Consistent code formatting for test automation:
code --install-extension esbenp.prettier-vscode
Configuration:
{
"editor.formatOnSave": true,
"prettier.singleQuote": true,
"prettier.semi": false,
"prettier.tabWidth": 2
}
3. API Testing Extensions
REST Client Test API endpoints without leaving VS Code:
code --install-extension humao.rest-client
Create .http
files for API testing:
### Get User by ID
GET https://api.example.com/users/123
Authorization: Bearer {{token}}
### Create New User
POST https://api.example.com/users
Content-Type: application/json
{
"name": "John Doe",
"email": "john@example.com"
}
### Variables
@baseUrl = https://api.example.com
@token = eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
### Using Variables
GET {{baseUrl}}/profile
Authorization: Bearer {{token}}
Thunder Client Lightweight alternative to Postman:
code --install-extension rangav.vscode-thunder-client
Features:
- Collections and environments
- Graphical interface for API testing
- Generate code snippets in multiple languages
- Import/export Postman collections
4. Debugging and Inspection
JavaScript Debugger Built into VS Code, but requires configuration:
Create .vscode/launch.json
:
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Jest Current File",
"program": "${workspaceFolder}/node_modules/.bin/jest",
"args": [
"${fileBasename}",
"--runInBand",
"--no-cache"
],
"console": "integratedTerminal",
"internalConsoleOptions": "neverOpen"
},
{
"type": "node",
"request": "launch",
"name": "Debug Playwright Test",
"program": "${workspaceFolder}/node_modules/.bin/playwright",
"args": [
"test",
"${file}",
"--debug"
],
"console": "integratedTerminal"
}
]
}
CodeLLDB (for Python testing):
code --install-extension vadimcn.vscode-lldb
Python debugging configuration:
{
"type": "python",
"request": "launch",
"name": "Pytest Current File",
"module": "pytest",
"args": [
"${file}",
"-v",
"-s"
],
"console": "integratedTerminal"
}
5. Version Control and Collaboration
GitLens Enhanced Git capabilities for tracking test changes:
code --install-extension eamodio.gitlens
Key features for testers:
- Blame annotations showing who wrote each test
- File history to track test evolution
- Compare test versions across branches
- Line history for understanding test modifications
Live Share Pair testing and collaborative debugging:
code --install-extension MS-vsliveshare.vsliveshare
Use cases:
- Pair programming on test automation
- Remote debugging sessions
- Collaborative test review
- Knowledge sharing sessions
Custom Snippets for Test Automation
Create custom snippets in Code > Preferences > User Snippets
:
Jest Test Snippets (javascript.json
):
{
"Jest Describe Block": {
"prefix": "desc",
"body": [
"describe('${1:suite name}', () => {",
" ${2:// test code}",
"});"
]
},
"Jest Test Case": {
"prefix": "test",
"body": [
"test('${1:test name}', async () => {",
" ${2:// test implementation}",
"});"
]
},
"Jest Before Each": {
"prefix": "beforeach",
"body": [
"beforeEach(async () => {",
" ${1:// setup code}",
"});"
]
},
"API Test Template": {
"prefix": "apitest",
"body": [
"test('${1:endpoint} should ${2:expected behavior}', async () => {",
" const response = await request(app)",
" .${3:get}('${4:/api/endpoint}')",
" .set('Authorization', `Bearer \\${token}`);",
"",
" expect(response.status).toBe(${5:200});",
" expect(response.body).toMatchObject({",
" ${6:// expected properties}",
" });",
"});"
]
}
}
Playwright Snippets:
{
"Playwright Test": {
"prefix": "pwtest",
"body": [
"test('${1:test description}', async ({ page }) => {",
" await page.goto('${2:https://example.com}');",
" ${3:// test steps}",
"});"
]
},
"Playwright Expect": {
"prefix": "pwexpect",
"body": [
"await expect(page.locator('${1:selector}')).${2:toBeVisible}();"
]
}
}
Workspace Configuration for Test Projects
Create .vscode/settings.json
for your test project:
{
"files.exclude": {
"**/.git": true,
"**/node_modules": true,
"**/coverage": true,
"**/playwright-report": true
},
"search.exclude": {
"**/node_modules": true,
"**/coverage": true,
"**/dist": true
},
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
},
"files.associations": {
"*.spec.js": "javascript",
"*.test.js": "javascript",
"*.http": "http"
},
"jest.autoRun": {
"watch": false,
"onSave": "test-file"
},
"testing.automaticallyOpenPeekView": "failureInVisibleDocument",
"terminal.integrated.defaultProfile.osx": "zsh",
"npm.enableScriptExplorer": true
}
Tasks for Common Testing Operations
Create .vscode/tasks.json
:
{
"version": "2.0.0",
"tasks": [
{
"label": "Run All Tests",
"type": "npm",
"script": "test",
"problemMatcher": [],
"presentation": {
"reveal": "always",
"panel": "new"
}
},
{
"label": "Run Tests with Coverage",
"type": "npm",
"script": "test:coverage",
"problemMatcher": [],
"presentation": {
"reveal": "always"
}
},
{
"label": "Lint Test Files",
"type": "npm",
"script": "lint",
"problemMatcher": ["$eslint-stylish"]
},
{
"label": "Generate Playwright Report",
"type": "shell",
"command": "npx playwright show-report",
"problemMatcher": []
}
]
}
Keyboard Shortcuts for Productivity
Customize keyboard shortcuts in Keybindings
(JSON):
[
{
"key": "ctrl+shift+t",
"command": "testing.runCurrentFile"
},
{
"key": "ctrl+shift+d",
"command": "testing.debugCurrentFile"
},
{
"key": "ctrl+shift+a",
"command": "testing.runAll"
},
{
"key": "ctrl+shift+f",
"command": "testing.reRunFailTests"
}
]
Multi-Root Workspaces for Complex Projects
For projects with separate frontend and backend tests:
Create test-automation.code-workspace
:
{
"folders": [
{
"name": "API Tests",
"path": "./api-tests"
},
{
"name": "E2E Tests",
"path": "./e2e-tests"
},
{
"name": "Performance Tests",
"path": "./performance-tests"
}
],
"settings": {
"files.watcherExclude": {
"**/node_modules/**": true
}
}
}
IntelliJ IDEA for Testing
IntelliJ IDEA (and other JetBrains IDEs) provide powerful features for Java-based test automation, including excellent support for JUnit, TestNG, Selenium, and other testing frameworks.
Essential Plugins for Testing
1. Test Automation Plugins
JUnit 5 Support (Built-in)
- Run tests from editor gutter icons
- Navigate between tests and production code
- Generate test methods automatically
- Coverage analysis
Configuration in Run Configuration
:
VM options: -ea -Dfile.encoding=UTF-8
Working directory: $MODULE_WORKING_DIR$
Environment variables: ENV=test
TestNG Plugin Advanced testing framework support:
<!-- pom.xml dependency -->
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>7.8.0</version>
<scope>test</scope>
</dependency>
TestNG configuration (testng.xml
):
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="Test Suite" parallel="methods" thread-count="5">
<test name="API Tests">
<classes>
<class name="com.example.tests.UserApiTest"/>
<class name="com.example.tests.ProductApiTest"/>
</classes>
</test>
<test name="UI Tests">
<packages>
<package name="com.example.tests.ui"/>
</packages>
</test>
</suite>
Cucumber for Java BDD testing support:
Settings > Plugins > Install "Cucumber for Java"
Features:
- Gherkin syntax highlighting
- Navigation from steps to step definitions
- Generate step definitions from feature files
- Run scenarios from editor
Example feature file:
Feature: User Authentication
Background:
Given the application is running
And the database is clean
@smoke @api
Scenario: Successful login with valid credentials
Given a user with username "testuser" exists
When the user logs in with username "testuser" and password "Test123!"
Then the login should be successful
And a valid JWT token should be returned
@negative
Scenario Outline: Failed login attempts
When the user logs in with username "<username>" and password "<password>"
Then the login should fail
And the error message should be "<error>"
Examples:
| username | password | error |
| invalid | Test123! | Invalid credentials |
| testuser | wrong | Invalid credentials |
| | Test123! | Username required |
2. Code Coverage Tools
IntelliJ IDEA Code Coverage (Built-in) Run tests with coverage:
- Right-click on test class/package
- Select “Run with Coverage”
- View coverage in editor gutter and Coverage tool window
Configuration in .idea/workspace.xml
:
<component name="CoverageOptionsProvider">
<option name="myAddOrReplace" value="2" />
<option name="myGlobalRunner" value="IDEA" />
<option name="myTraceTestFramework" value="false" />
</component>
JaCoCo Plugin More advanced coverage reporting:
<!-- Maven plugin -->
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.11</version>
<executions>
<execution>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
<execution>
<id>jacoco-check</id>
<goals>
<goal>check</goal>
</goals>
<configuration>
<rules>
<rule>
<element>PACKAGE</element>
<limits>
<limit>
<counter>LINE</counter>
<value>COVEREDRATIO</value>
<minimum>0.80</minimum>
</limit>
</limits>
</rule>
</rules>
</configuration>
</execution>
</executions>
</plugin>
3. REST API Testing
HTTP Client (Built-in)
Create .http
files for API testing:
### Development environment
@host = http://localhost:8080
@token = {{auth_token}}
### Get Authentication Token
# @name auth
POST {{host}}/api/auth/login
Content-Type: application/json
{
"username": "admin",
"password": "admin123"
}
> {% client.global.set("auth_token", response.body.token); %}
### Get All Users (Authenticated)
GET {{host}}/api/users
Authorization: Bearer {{token}}
### Create New User
POST {{host}}/api/users
Content-Type: application/json
Authorization: Bearer {{token}}
{
"username": "newuser",
"email": "newuser@example.com",
"role": "USER"
}
### Update User
# @name updateUser
PUT {{host}}/api/users/{{userId}}
Content-Type: application/json
Authorization: Bearer {{token}}
{
"email": "updated@example.com"
}
### Response handler
> {%
client.test("Request executed successfully", function() {
client.assert(response.status === 200, "Response status is not 200");
});
client.test("User updated correctly", function() {
client.assert(response.body.email === "updated@example.com");
});
%}
### Delete User
DELETE {{host}}/api/users/{{userId}}
Authorization: Bearer {{token}}
4. Database Tools Integration
Database Tools and SQL (Built-in) Connect to test databases for data verification:
- Open Database tool window
- Add data source (PostgreSQL, MySQL, etc.)
- Create SQL console for test data management
Example test data setup script:
-- Setup test data
TRUNCATE TABLE users CASCADE;
TRUNCATE TABLE orders CASCADE;
INSERT INTO users (id, username, email, role, created_at)
VALUES
(1, 'testuser1', 'test1@example.com', 'USER', NOW()),
(2, 'testuser2', 'test2@example.com', 'USER', NOW()),
(3, 'admin', 'admin@example.com', 'ADMIN', NOW());
INSERT INTO orders (id, user_id, product_id, quantity, total, status)
VALUES
(1, 1, 101, 2, 199.98, 'COMPLETED'),
(2, 1, 102, 1, 49.99, 'PENDING'),
(3, 2, 101, 1, 99.99, 'COMPLETED');
-- Verify data
SELECT u.username, COUNT(o.id) as order_count, SUM(o.total) as total_spent
FROM users u
LEFT JOIN orders o ON u.id = o.user_id
GROUP BY u.id, u.username;
Live Templates for Test Code
Create custom live templates in Settings > Editor > Live Templates
:
JUnit 5 Test Method:
@Test
@DisplayName("$DESCRIPTION$")
void $METHOD_NAME$() {
// Arrange
$ARRANGE$
// Act
$ACT$
// Assert
$ASSERT$
}
REST Assured API Test:
@Test
void test$METHOD$Returns$STATUS$() {
given()
.contentType(ContentType.JSON)
.header("Authorization", "Bearer " + token)
.when()
.$HTTP_METHOD$("$ENDPOINT$")
.then()
.statusCode($STATUS_CODE$)
.body("$JSON_PATH$", equalTo($EXPECTED_VALUE$));
}
Selenium Page Object Method:
public $RETURN_TYPE$ $METHOD_NAME$($PARAMETERS$) {
wait.until(ExpectedConditions.elementToBeClickable($ELEMENT$));
$ELEMENT$.$ACTION$();
return $RETURN_VALUE$;
}
TestNG Data Provider:
@DataProvider(name = "$PROVIDER_NAME$")
public Object[][] $METHOD_NAME$() {
return new Object[][] {
$DATA$
};
}
Run Configurations for Test Execution
JUnit Run Configuration Template:
Name: All Unit Tests
Test kind: All in package
Package: com.example.tests.unit
VM options: -ea -Xmx512m
Working directory: $MODULE_DIR$
Environment variables:
ENV=test
LOG_LEVEL=DEBUG
Before launch: Build, Run Maven Goal (clean compile)
TestNG Suite Configuration:
Name: Integration Tests
Suite: src/test/resources/testng-integration.xml
VM options: -Denv=staging -Dbrowser=chrome
Listeners: com.example.listeners.TestListener
Before launch: Build, Run Maven Goal (clean test-compile)
Debugging Test Failures
Conditional Breakpoints: Right-click on breakpoint and add condition:
username.equals("problematicUser") && response.getStatus() != 200
Evaluate Expression:
During debugging, use Alt+F8
to evaluate:
// Check JSON response content
new ObjectMapper().readTree(response.getBody().asString())
// Verify element state
driver.findElement(By.id("submitBtn")).isEnabled()
// Database query verification
jdbcTemplate.queryForObject("SELECT COUNT(*) FROM users WHERE status = 'ACTIVE'", Integer.class)
Exception Breakpoints: Set breakpoints for specific exceptions:
- Go to
Run > View Breakpoints
- Add
Java Exception Breakpoints
- Enter exception class (e.g.,
AssertionError
,TimeoutException
)
Code Analysis and Inspection
Enable useful inspections for test code:
Settings > Editor > Inspections > Enable:
- JUnit > Test method naming convention
- JUnit > Test method without assertions
- TestNG > Dependent methods
- Java > Probable bugs > Constant conditions
- Java > Testing > Assertion arguments order
Custom inspection profile for tests:
<!-- .idea/inspectionProfiles/Tests.xml -->
<profile version="1.0">
<option name="myName" value="Tests" />
<inspection_tool class="JUnitTestMethodWithNoAssertions" enabled="true" level="WARNING" />
<inspection_tool class="TestMethodWithoutAssertion" enabled="true" level="WARNING" />
</profile>
Browser DevTools Mastery
Browser Developer Tools are essential for every tester, whether you’re debugging UI issues, analyzing network performance, or investigating JavaScript errors. Modern browsers (Chrome, Firefox, Safari, Edge) offer powerful built-in tools.
Chrome DevTools for Testing
1. Elements Panel
Inspecting DOM for Test Automation:
- Right-click element → Inspect
- Find unique selectors for automation
- Copy XPath: Right-click element → Copy → Copy XPath
- Copy JS Path: Right-click element → Copy → Copy JS path
Best Practices for Selector Generation:
// Instead of fragile XPath:
// /html/body/div[1]/div[2]/form/div[3]/button
// Use more stable selectors:
document.querySelector('[data-testid="submit-button"]')
document.querySelector('button[type="submit"].primary')
// Or relative XPath:
//button[contains(text(), 'Submit')]
//button[@data-testid='submit-button']
Live Edit for Testing:
- Double-click attributes to modify
- Edit as HTML for complex changes
- Test CSS changes in Styles panel
- Force element states: :hover, :active, :focus
2. Console Panel
Essential Console Commands for Testers:
// Query elements (similar to test automation)
$('button.submit') // Returns first match (like querySelector)
$$('button') // Returns all matches (like querySelectorAll)
$x('//button[@type="submit"]') // XPath query
// Inspect elements
inspect($('button.submit')) // Opens Elements panel
// Monitor events
monitorEvents($('form'), 'submit') // Log form submission
unmonitorEvents($('form')) // Stop monitoring
// Network monitoring
monitor(functionName) // Log when function is called
unmonitor(functionName)
// Performance
console.time('operationName')
// ... code execution ...
console.timeEnd('operationName') // Shows execution time
// Table display for data analysis
console.table(users) // Display array of objects as table
// Test assertions
console.assert(value > 0, 'Value must be positive')
// Get event listeners
getEventListeners($('button.submit'))
// Copy data to clipboard
copy(JSON.stringify(userData))
Snippets for Reusable Test Scripts:
Create snippet in Sources > Snippets
:
// Snippet: Check All Validation Errors
(function checkValidation() {
const errors = $$('.error-message');
console.table(errors.map(el => ({
element: el.closest('[data-testid]')?.dataset.testid || 'unknown',
message: el.textContent.trim(),
visible: window.getComputedStyle(el).display !== 'none'
})));
})();
// Snippet: Test Form Data
(function getFormData() {
const form = $('form');
const formData = new FormData(form);
const data = {};
for (let [key, value] of formData.entries()) {
data[key] = value;
}
console.log('Form Data:', data);
copy(JSON.stringify(data, null, 2));
console.log('Copied to clipboard!');
})();
// Snippet: Find Orphaned Test IDs
(function findOrphanedTestIds() {
const elements = $$('[data-testid]');
const testIds = elements.map(el => ({
id: el.dataset.testid,
tag: el.tagName,
text: el.textContent.trim().substring(0, 50)
}));
console.table(testIds);
console.log(`Total: ${testIds.length} elements with test IDs`);
})();
3. Network Panel
Analyzing API Requests for Testing:
Filtering Requests:
Filter by type: XHR, Fetch, JS, CSS, Img
Filter by domain: domain:api.example.com
Filter by status: status-code:404
Filter by method: method:POST
Combine: method:POST domain:api status-code:200
Request Analysis:
- Headers: Check authorization tokens, content types
- Payload: Verify request body format
- Preview: View response data structure
- Response: Raw response data
- Timing: Analyze request duration
Copy Request as Code: Right-click request → Copy → Copy as cURL / Copy as fetch / Copy as PowerShell
# Example cURL for test automation
curl 'https://api.example.com/users' \
-H 'Authorization: Bearer eyJhbGc...' \
-H 'Content-Type: application/json' \
--data-raw '{"username":"testuser"}' \
--compressed
HAR File Export for Bug Reports:
- Right-click in Network panel
- Save all as HAR
- Attach to bug report for complete network trace
Throttling for Performance Testing:
Network panel > Throttling dropdown:
- Fast 3G (1.6 Mbps)
- Slow 3G (400 Kbps)
- Offline
- Custom profiles
4. Sources Panel for Debugging
JavaScript Debugging for Testers:
Breakpoint Types:
- Line Breakpoints: Click line number
- Conditional Breakpoints: Right-click line → Add conditional breakpoint
userId === 123 && response.status !== 200
- DOM Breakpoints: Right-click element in Elements panel
- Break on subtree modifications
- Break on attribute modifications
- Break on node removal
- Event Listener Breakpoints: Sources > Event Listener Breakpoints
- Mouse > click
- Keyboard > keydown
- Form > submit
- XHR > XMLHttpRequest sent
- XHR/Fetch Breakpoints: Sources > XHR/fetch Breakpoints
- Add URL pattern:
api/users
- Add URL pattern:
Local Overrides for Testing:
1. Sources > Overrides > Enable Local Overrides
2. Select folder for overrides
3. Edit response in Sources panel
4. Save (Ctrl+S)
5. Reload page to test modified response
Use cases:
- Test error handling without backend changes
- Modify API responses for edge cases
- Test different data scenarios
- Simulate slow/failed responses
Blackboxing Third-Party Scripts:
Settings > Blackboxing > Add pattern
Pattern: node_modules/
Improves debugging by skipping library code.
5. Performance Panel
Recording Performance for Test Analysis:
1. Click Record
2. Perform actions
3. Stop recording
4. Analyze:
- FPS: Frames per second (smooth = 60 FPS)
- CPU: JavaScript execution time
- Network: Request waterfall
- Screenshots: Visual timeline
Key Metrics for Testers:
- FCP (First Contentful Paint): When first content appears
- LCP (Largest Contentful Paint): When main content loaded
- TTI (Time to Interactive): When page becomes interactive
- TBT (Total Blocking Time): Time main thread is blocked
- CLS (Cumulative Layout Shift): Visual stability
Performance Testing Script:
// Record performance metrics
const perfData = performance.getEntriesByType('navigation')[0];
console.table({
'DNS Lookup': perfData.domainLookupEnd - perfData.domainLookupStart,
'TCP Connection': perfData.connectEnd - perfData.connectStart,
'Request Time': perfData.responseStart - perfData.requestStart,
'Response Time': perfData.responseEnd - perfData.responseStart,
'DOM Processing': perfData.domInteractive - perfData.responseEnd,
'Total Load Time': perfData.loadEventEnd - perfData.navigationStart
});
// Get Web Vitals
const observer = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
console.log(`${entry.name}: ${entry.value}`);
}
});
observer.observe({ entryTypes: ['largest-contentful-paint', 'first-input', 'layout-shift'] });
6. Application Panel
Storage Inspection for Testing:
Local Storage / Session Storage:
// View in Console
console.table(Object.entries(localStorage))
// Test data manipulation
localStorage.setItem('authToken', 'test-token-123')
localStorage.removeItem('userId')
localStorage.clear()
// Test for automation
expect(localStorage (as discussed in [Test Management Systems: Jira vs TestRail vs Zephyr](/blog/test-management-systems-comparison)).getItem('theme')).toBe('dark')
Cookies:
- View all cookies for domain
- Edit cookie values
- Delete individual cookies
- Clear all cookies
IndexedDB:
- Inspect database structure
- View stored records
- Delete databases for clean test state
Cache Storage:
- Inspect Service Worker caches
- View cached responses
- Delete cache for testing
7. Lighthouse for Quality Testing
Run automated audits:
1. Open Lighthouse panel
2. Select categories:
- Performance
- Accessibility
- Best Practices
- SEO
- Progressive Web App
3. Choose device (Mobile/Desktop)
4. Click "Generate report"
Command Line Lighthouse:
npm install -g lighthouse
# Run audit
lighthouse https://example.com --output html --output-path ./report.html
# With custom config
lighthouse https://example.com \
--throttling.cpuSlowdownMultiplier=4 \
--only-categories=performance,accessibility \
--chrome-flags="--headless"
Firefox Developer Tools
Unique Features for Testers:
CSS Grid/Flexbox Inspector:
- Visual overlay for Grid/Flexbox layouts
- Better than Chrome for CSS debugging
Accessibility Inspector:
Tools > Browser Tools > Accessibility
- View accessibility tree
- Check ARIA attributes
- Simulate color blindness
- Check contrast ratios
Screenshot Command:
Open Developer Tools > Settings (F1) > Available Toolbox Buttons > Enable "Take a screenshot"
Or use Console:
:screenshot --fullpage
:screenshot --selector ".main-content"
Network Request Blocking:
Network panel > Right-click request > Block URL
Test error handling without backend changes.
Proxy Tools: Charles and Fiddler
Proxy tools intercept HTTP/HTTPS traffic between client and server, enabling testers to inspect, modify, and mock API responses. Essential for mobile testing, API testing, and security testing.
Charles Proxy
Charles is a cross-platform HTTP proxy / HTTP monitor / Reverse Proxy that enables developers and testers to view all HTTP/HTTPS traffic.
Installation and Setup
# macOS
brew install --cask charles
# Windows: Download from charlesproxy.com
# License: ~$50 (free trial available)
Initial Configuration:
- Proxy > Proxy Settings
- Port: 8888 (default)
- Enable transparent HTTP proxying: ✓
- Proxy > macOS Proxy (to set system proxy)
SSL Certificate Installation (for HTTPS decryption):
macOS:
1. Help > SSL Proxying > Install Charles Root Certificate
2. Open Keychain Access
3. Find "Charles Proxy" certificate
4. Double-click > Trust > Always Trust
Windows:
1. Help > SSL Proxying > Install Charles Root Certificate
2. Certificate will be added to Windows Certificate Store
Mobile Device (iOS/Android):
1. Connect device to same WiFi as computer
2. Device WiFi Settings > Configure Proxy > Manual
- Server: [Computer IP]
- Port: 8888
3. Open browser on device: chls.pro/ssl
4. Install certificate
5. iOS: Settings > General > About > Certificate Trust Settings > Enable
SSL Proxying Settings
Enable SSL proxying for specific hosts:
Proxy > SSL Proxying Settings > Add
Location:
Host: *.example.com
Port: 443
Or for all hosts:
Host: *
Port: 443
Recording and Analyzing Traffic
Structure View:
- Hierarchical view of hosts and paths
- Expand to see all requests to specific endpoint
- Right-click > Clear to remove noise
Sequence View:
- Chronological list of all requests
- Better for understanding request flow
- Shows exact timing of requests
Request/Response Inspector:
Tabs:
- Overview: Method, status, timing, size
- Headers: Request/response headers
- Text: Plain text response
- JSON: Formatted JSON with tree view
- XML: Formatted XML
- Raw: Complete raw request/response
Traffic Filtering
Focus on Specific Host:
Right-click host > Focus
Now only shows traffic for that host
Recording Settings:
Proxy > Recording Settings > Include
Add:
Protocol: HTTP+HTTPS
Host: api.example.com
Port: 443
Path: /api/*
Filter by Content Type:
View > Filter Settings
Show only:
☑ JSON
☑ XML
☐ HTML
☐ Images
☐ CSS/JavaScript
Request Manipulation
Breakpoints for Request/Response Modification:
1. Proxy > Breakpoint Settings > Enable Breakpoints
2. Add breakpoint:
- Host: api.example.com
- Path: /api/users
- Request: ✓
- Response: ✓
When request/response hits breakpoint:
- Edit JSON Request tab: Modify request body
- Edit Response tab: Modify response
- Click Execute to continue
Use Cases:
- Test error handling by changing status codes
- Modify response data for edge cases
- Change request parameters
- Test timeout scenarios (add delay)
Map Local & Map Remote
Map Local (Replace remote response with local file):
Tools > Map Local Settings > Add
Map From:
Protocol: HTTPS
Host: api.example.com
Path: /api/users
Map To:
Local Path: /Users/test/mock-responses/users.json
Mock response file (users.json
):
{
"users": [
{
"id": 1,
"name": "Test User",
"email": "test@example.com",
"role": "admin"
}
],
"total": 1
}
Map Remote (Redirect requests to different server):
Tools > Map Remote Settings > Add
Map From:
Protocol: HTTPS
Host: api-prod.example.com
Path: /api/v2/users
Map To:
Protocol: HTTPS
Host: api-staging.example.com
Path: /api/v2/users
Use cases:
- Test against staging while using production frontend
- Test new API version
- Test load balancer behavior
Rewrite Tool
Modify Requests/Responses with Rules:
Tools > Rewrite Settings > Add
Name: Add CORS Headers
Apply to: api.example.com
Add Rule:
Type: Add Header
Where: Response
Name: Access-Control-Allow-Origin
Value: *
Add Rule:
Type: Modify Status
Where: Response
Status: 200
(Change 4xx/5xx to 200 for testing)
Add Rule:
Type: Body Replacement
Where: Response
Match: "status":"active"
Replace: "status":"inactive"
Throttling (Network Conditioning)
Proxy > Throttle Settings > Enable Throttling
Preset: 3G (780 kbps down, 330 kbps up)
Or Custom:
Bandwidth: 512 kbps
Utilisation: 80%
Round-trip latency: 300ms
MTU: 1500 bytes
Apply to: Only selected hosts
Add: api.example.com
Use Cases:
- Test app behavior on slow networks
- Test timeouts
- Test loading states
- Test progressive enhancement
Repeat Requests
Repeat Testing:
Right-click request > Repeat
Right-click request > Repeat Advanced
- Count: 10
- Concurrency: 5
- Delay: 1000ms
Use for:
- Load testing (basic)
- Testing race conditions
- Testing rate limiting
- Reproducing intermittent issues
Export and Reporting
Export Session:
File > Export Session
Formats:
- Charles Session (.chls)
- HAR (HTTP Archive)
- CSV
- JSON
Generate Report:
File > Export Report
- HTML Report
- Include request/response bodies
- Include timing information
Attach to bug reports for complete context.
Fiddler Classic / Fiddler Everywhere
Fiddler is another powerful web debugging proxy, popular on Windows. Fiddler Everywhere is the cross-platform version.
Installation
# Windows (Fiddler Classic - Free)
winget install Fiddler.Fiddler
# Cross-platform (Fiddler Everywhere - Subscription)
# Download from telerik.com/fiddler
Key Features
Composers: Create custom requests:
Composer > Parsed
Request:
Method: POST
URL: https://api.example.com/users
Headers:
Content-Type: application/json
Authorization: Bearer {token}
Body:
{
"username": "testuser",
"email": "test@example.com"
}
Execute > View response
AutoResponder (Similar to Charles Map Local):
Rules > Add Rule
If request matches:
EXACT: https://api.example.com/users
Then respond with:
File: C:\mocks\users.json
Or: *404
Or: *delay:5000 (5 second delay)
Or: *bpu (break on request)
FiddlerScript (C# scripting):
// Auto-modify requests
static function OnBeforeRequest(oSession: Session) {
// Add header to all API requests
if (oSession.uriContains("/api/")) {
oSession.oRequest["X-Test-Mode"] = "true";
}
// Block analytics
if (oSession.uriContains("analytics.google.com")) {
oSession.oRequest.FailSession(404, "Blocked", "");
}
}
// Auto-modify responses
static function OnBeforeResponse(oSession: Session) {
// Force CORS
if (oSession.uriContains("/api/")) {
oSession.oResponse["Access-Control-Allow-Origin"] = "*";
}
// Log slow responses
if (oSession.Timers.ClientDoneResponse.Subtract(oSession.Timers.ClientBeginRequest).TotalMilliseconds > 2000) {
FiddlerObject.log("Slow request: " + oSession.fullUrl);
}
}
Filters:
Filters tab:
Hosts:
Show only: api.example.com
Hide: cdn.example.com
Client Process:
Show only: chrome.exe
Breakpoints:
Break request on POST
Break response on status 500
Request Builder: More advanced than Composer:
Request Builder > New Request
Templates:
- REST API GET
- REST API POST with JSON
- SOAP Request
- GraphQL Query
Save as collection for reuse
Comparing Charles vs Fiddler
Feature | Charles | Fiddler Classic | Fiddler Everywhere |
---|---|---|---|
Platform | Mac, Windows, Linux | Windows only | Mac, Windows, Linux |
Price | $50 (perpetual) | Free | $150/year subscription |
UI | Native (Java Swing) | Native (WinForms) | Electron (modern) |
Learning Curve | Medium | Medium | Easy |
Performance | Good | Excellent | Good |
Scripting | Limited | C# (powerful) | JavaScript |
SSL Setup | Easy | Easy | Easiest |
Mobile Testing | Excellent | Excellent | Excellent |
Request Mocking | Map Local/Remote | AutoResponder | Mock Server |
Network Throttling | Yes | Yes | Yes |
API Testing | Basic | Composer | Advanced (collections) |
Best For | Mac users, simplicity | Windows power users | Teams, cross-platform |
Mobile Testing Workflow
Complete mobile testing setup:
- Configure Proxy on Device:
iOS:
Settings > Wi-Fi > [Network] > Configure Proxy
Manual: [Computer IP]:8888
Android:
Settings > Wi-Fi > [Network] > Advanced
Proxy: Manual
Hostname: [Computer IP]
Port: 8888
Install SSL Certificate (see Charles setup above)
Enable SSL Proxying for app domains
Common Mobile Testing Scenarios:
Test API Error Handling:
- Use Breakpoints to change response status to 500
- Verify app shows appropriate error message
- Check if retry mechanism works
Test Offline Mode:
- Use Map Local to return cached responses
- Block specific requests
- Verify offline functionality
Test Different API Versions:
- Use Map Remote to point to different API versions
- Test backward compatibility
- Test migration scenarios
Test Slow Networks:
- Apply throttling (3G settings)
- Verify loading states
- Check timeout handling
- Test progressive image loading
Capture for Bug Reports:
- Record complete session
- Export HAR file
- Include in bug report with steps to reproduce
Choosing the Right Tools
IDE Selection Matrix
Use Case | VS Code | IntelliJ IDEA |
---|---|---|
JavaScript/TypeScript tests | ✓✓✓ Excellent | ✓✓ Good |
Java test automation | ✓ Basic | ✓✓✓ Excellent |
Python testing | ✓✓✓ Excellent (with extensions) | ✓✓ Good (PyCharm better) |
Multi-language projects | ✓✓✓ Excellent | ✓✓ Good |
Lightweight/Fast startup | ✓✓✓ Excellent | ✓ Slower |
Built-in features | ✓ Needs extensions | ✓✓✓ Excellent |
Free/Open source | ✓✓✓ Free | ✓ Community Edition |
API testing | ✓✓ Good (extensions) | ✓✓✓ Built-in |
Recommended Tool Combinations
Frontend Test Automation:
- IDE: VS Code
- Extensions: Playwright, Jest, ESLint
- Browser: Chrome DevTools
- Proxy: Charles
Backend API Testing:
- IDE: IntelliJ IDEA / VS Code
- Tools: REST Client, Postman
- Proxy: Charles / Fiddler
- Database: DBeaver / IntelliJ Database Tools
Mobile Testing:
- IDE: VS Code / Android Studio
- Proxy: Charles (best mobile support)
- Device Mirroring: scrcpy
- Performance: Chrome DevTools (remote debugging)
Full Stack Testing:
- IDE: VS Code (multi-root workspace)
- Browser: Chrome DevTools
- API: IntelliJ HTTP Client / Thunder Client
- Proxy: Charles
Learning Path
Week 1-2: IDE Basics
- Set up VS Code or IntelliJ IDEA
- Install essential extensions/plugins
- Learn keyboard shortcuts
- Configure debugging
- Create custom snippets
Week 3-4: Browser DevTools
- Master Elements and Console panels
- Learn Network analysis
- Practice JavaScript debugging
- Create reusable snippets
- Run Lighthouse audits
Week 5-6: Proxy Tools
- Install and configure Charles/Fiddler
- Set up SSL proxying
- Practice request modification
- Create mock responses with Map Local
- Test mobile apps
Week 7-8: Advanced Techniques
- Combine tools in testing workflow
- Create automated test helpers
- Build custom debugging scripts
- Document team best practices
- Train other team members
Productivity Tips
1. Keyboard Shortcuts Learn these first:
- VS Code:
Cmd/Ctrl + P
(quick open),Cmd/Ctrl + Shift + P
(command palette) - DevTools:
Cmd/Ctrl + Shift + C
(inspect element),Cmd + K
(clear console) - Charles:
Cmd/Ctrl + K
(clear session),Cmd/Ctrl + R
(start/stop recording)
2. Custom Snippets Create snippets for:
- Common test patterns
- API request templates
- Console debugging scripts
- Mock data generators
3. Workspace Organization
- Use multi-root workspaces for complex projects
- Create .vscode/tasks.json for common operations
- Save debugging configurations
- Organize proxy sessions by feature
4. Documentation Document in your team wiki:
- IDE setup instructions
- Required extensions/plugins
- Debugging configurations
- Proxy setup for projects
- Common troubleshooting steps
5. Automation Automate repetitive tasks:
- Test execution scripts
- Coverage report generation
- HAR file analysis scripts
- Network performance monitoring
Conclusion
Mastering the right tools transforms testing efficiency. VS Code and IntelliJ IDEA provide powerful environments for test development with the right extensions and configurations. Browser DevTools offer unmatched insight into application behavior. Proxy tools like Charles and Fiddler enable deep API inspection and manipulation.
The key is not to learn every feature of every tool, but to:
- Choose tools that fit your tech stack
- Master the features you use daily (80/20 rule)
- Automate repetitive tasks with snippets and scripts
- Document your setup for team consistency
- Continuously learn as tools evolve
Start with one tool from each category (IDE, DevTools, Proxy), build proficiency, then expand your toolkit. Remember: tools are force multipliers, but testing expertise is what matters most.
Next Steps:
- Set up your primary IDE with essential extensions today
- Practice browser DevTools daily during testing
- Install and configure a proxy tool this week
- Create your first custom snippet or debugging configuration
- Share your learnings with your team
Happy testing!