A comprehensive project for learning and practicing testing fundamentals, including unit tests, integration tests, and Selenium web automation.
This project is designed to teach testing best practices through hands-on examples. It covers:
- Unit testing with Jest
- Test organization and structure
- Assertions and matchers
- Test fixtures and mocks
- Code coverage analysis
- Integration testing patterns
- Web automation with Selenium WebDriver
testing_basics/
├── src/ # Source code
│ ├── calculator.js # Example: Simple calculator
│ ├── stringUtils.js # Example: String utilities
│ └── index.js # Entry point
├── tests/ # Test files
│ ├── calculator.test.js # Unit tests for calculator
│ ├── stringUtils.test.js # Unit tests for string utilities
│ ├── selenium/ # Selenium automation tests
│ │ ├── basicTest.js # Basic Selenium example
│ │ ├── googleSearch.js # Google search automation
│ │ └── pageInteraction.js # Page interaction examples
│ └── fixtures/ # Test data and fixtures
├── .github/ # GitHub configuration
│ └── copilot-instructions.md
└── jest.config.js # Jest configuration
- Node.js (v14 or higher)
- npm
- Chrome browser (for Selenium tests)
- Navigate to the project directory:
cd testing_basics- Install dependencies:
npm installThis will install:
- Jest: JavaScript testing framework
- Selenium WebDriver: Browser automation library
- ChromeDriver: WebDriver for Chrome browser
- Run all Jest tests:
npm test- Run tests in watch mode:
npm run test:watch- Run tests with coverage report:
npm run test:coverage- Run basic Selenium example:
npm run test:selenium- Run specific Selenium test:
node tests/selenium/googleSearch.js- Writing simple test cases
- Understanding test structure (Arrange, Act, Assert)
- Using Jest matchers
- Testing pure functions
- Naming conventions
- Test organization
- Using test fixtures
- Error handling in tests
- Mocking functions and modules
- Testing async code
- Code coverage analysis
- Integration testing
- Browser automation fundamentals
- Locating elements
- Interacting with web pages
- Handling waits and timeouts
- Testing web applications
A simple calculator module with basic arithmetic operations.
Utility functions for string manipulation and validation.
Main entry point demonstrating calculator and string utilities.
Unit tests for the calculator module demonstrating:
- Testing simple functions
- Using different matchers
- Testing error cases
Unit tests for string utilities demonstrating:
- String validation
- String transformation testing
- Edge case handling
Basic Selenium WebDriver example:
- Opening a browser
- Navigating to a website
- Finding elements
- Performing simple actions
Practical example of searching on Google:
- Using multiple locator strategies
- Interacting with form elements
- Waiting for elements to load
- Capturing results
Advanced page interaction examples:
- Clicking elements
- Entering text in fields
- Handling alerts
- Managing browser windows
| Command | Description |
|---|---|
npm test |
Run all Jest tests |
npm run test:watch |
Run tests in watch mode |
npm run test:coverage |
Generate coverage report |
npm run test:selenium |
Run basic Selenium example |
npm run dev |
Run the application |
- Test Names: Clear, descriptive test names that explain what is being tested
- Arrange-Act-Assert: Proper test structure for readability
- DRY Principle: Using
beforeEachandafterEachto reduce duplication - Error Testing: Testing both success and failure cases
- Coverage: Aiming for high code coverage (70%+ threshold)
- Wait Strategies: Using explicit waits instead of hard waits
- Element Locators: Using reliable locator strategies
- Error Handling: Properly handling exceptions during test execution
- Browser Management: Opening and closing browsers cleanly
- Page Objects: Organizing tests with page object pattern (optional)
- Chrome (via ChromeDriver)
- Firefox (via GeckoDriver)
- Safari (native support)
const { Builder } = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
let driver = new Builder()
.forBrowser('chrome')
.setChromeOptions(new chrome.Options().headless())
.build();const { By } = require('selenium-webdriver');
// Find by ID
driver.findElement(By.id('elementId'));
// Find by CSS selector
driver.findElement(By.css('.classname'));
// Find by XPath
driver.findElement(By.xpath('//button[@type="submit"]'));
// Find by class name
driver.findElement(By.className('classname'));
// Find by name
driver.findElement(By.name('fieldname'));const { Key } = require('selenium-webdriver');
// Click element
element.click();
// Type text
element.sendKeys('text');
// Press keys
element.sendKeys(Key.ENTER);
// Get text
element.getText();
// Get attribute
element.getAttribute('href');
// Submit form
element.submit();const { until, WebDriverWait } = require('selenium-webdriver');
// Wait up to 10 seconds
const element = await new WebDriverWait(driver, 10000)
.until(until.elementLocated(By.id('myElement')));
// Wait for element to be visible
await new WebDriverWait(driver, 10000)
.until(until.elementIsVisible(element));When adding new features:
- Create the feature in
src/ - Write unit tests in
tests/ - Add Selenium tests in
tests/selenium/if testing web interactions - Ensure all tests pass:
npm testandnpm run test:selenium - Verify coverage:
npm run test:coverage
If you get a ChromeDriver error, reinstall dependencies:
npm installAlways call driver.quit() in your tests:
await driver.quit();Use explicit waits instead of implicit waits:
const wait = new WebDriverWait(driver, 10000);
const element = await wait.until(until.elementLocated(By.id('id')));MIT