# Install pytestpipinstallpytestpytest-cov
# Run all testspytest
# Run tests in a specific filepytesttests/test_calculator.py
# Run a specific testpytesttests/test_calculator.py::test_add_positive_numbers
# Run tests matching a keywordpytest-k"add"# Run with verbose outputpytest-v
# Run with coverage reportpytest--cov=src--cov-report=term-missing
# Run with coverage HTML reportpytest--cov=src--cov-report=html
# Stop after first failurepytest-x
# Show print output (don't capture stdout)pytest-s
importpytest@pytest.fixturedefdb_connection():"""Set up a test database connection."""conn=create_test_db()yieldconn# test runs hereconn.close()# teardown after test@pytest.fixture(scope="module")defexpensive_resource():"""Created once per module, shared across all tests in the module."""returnload_large_dataset()deftest_query(db_connection):result=db_connection.execute("SELECT 1")assertresult==1
# tests/conftest.py — fixtures available to all tests in the directoryimportpytestfrommyappimportcreate_app,db@pytest.fixture(scope="session")defapp():app=create_app(testing=True)yieldapp@pytest.fixturedefclient(app):returnapp.test_client()@pytest.fixture(autouse=True)defreset_db(app):"""Automatically reset database before each test."""withapp.app_context():db.create_all()yielddb.drop_all()
# Install Jestnpminstall--save-devjest
# For TypeScriptnpminstall--save-devts-jest@types/jest
# Run all testsnpxjest
# Run in watch modenpxjest--watch
# Run with coveragenpxjest--coverage
# Run a specific filenpxjestcalculator.test.js
# Run tests matching a patternnpxjest--testNamePattern="add"
// calculator.test.jsdescribe('Calculator',()=>{test('adds two numbers',()=>{// Arrangeconsta=2,b=3;// Actconstresult=add(a,b);// Assertexpect(result).toBe(5);});test('throws on division by zero',()=>{expect(()=>divide(10,0)).toThrow('Division by zero');});});
expect(value).toBe(5);// strict equality (===)expect(value).toEqual({a:1});// deep equalityexpect(value).toBeTruthy();// truthy valueexpect(value).toBeFalsy();// falsy valueexpect(array).toContain('item');// array contains itemexpect(string).toMatch(/pattern/);// regex matchexpect(fn).toThrow();// function throwsexpect(fn).toThrow('message');// throws with messageexpect(mockFn).toHaveBeenCalled();// mock was calledexpect(mockFn).toHaveBeenCalledWith(42);// mock called with argsexpect(mockFn).toHaveBeenCalledTimes(3);// called N times
beforeAll(()=>{/* runs once before all tests in the describe block */});afterAll(()=>{/* runs once after all tests */});beforeEach(()=>{/* runs before each test */});afterEach(()=>{/* runs after each test */});
fromunittest.mockimportMagicMock,patch,call# 1. Create a mock objectmock_service=MagicMock()mock_service.get_user.return_value={"id":1,"name":"Alice"}result=process_user(1,service=mock_service)# Verify callsmock_service.get_user.assert_called_once_with(1)mock_service.get_user.assert_called_with(1)# most recent callmock_service.get_user.assert_any_call(1)# any call with these args# 2. Patch a module-level namewithpatch('mymodule.send_email')asmock_email:register_user("alice@example.com")mock_email.assert_called_once()# 3. Patch as a decorator@patch('mymodule.requests.get')deftest_fetch_user(mock_get):mock_get.return_value.json.return_value={"id":1}result=fetch_user(1)assertresult["id"]==1# 4. Mock raising an exceptionmock_db=MagicMock()mock_db.query.side_effect=ConnectionError("DB down")# 5. Spy on a real object (wrap it)fromunittest.mockimportwrapsreal_calculator=Calculator()spy=MagicMock(wraps=real_calculator)spy.add(2,3)# calls the real methodspy.add.assert_called_once_with(2,3)
// 1. Mock a functionconstmockFn=jest.fn();mockFn.mockReturnValue(42);mockFn.mockReturnValueOnce(99);// returns 99 the first time, then 42// 2. Mock a modulejest.mock('./emailService',()=>({sendEmail:jest.fn().mockResolvedValue({success:true}),}));// 3. Spy on an existing methodconstspy=jest.spyOn(console,'log').mockImplementation(()=>{});doSomeThing();expect(spy).toHaveBeenCalledWith('expected message');spy.mockRestore();// restore original// 4. Mock an async functionconstmockFetch=jest.fn().mockResolvedValue({data:[1,2,3]});// 5. Clear mocks between testsbeforeEach(()=>{jest.clearAllMocks();// clears call counts and return values});
// 1. By role — most accessible, mirrors what users seepage.getByRole('button',{name:'Submit'})page.getByRole('textbox',{name:'Email'})page.getByRole('heading',{name:'Welcome'})page.getByRole('link',{name:'Sign in'})// 2. By label — for form inputspage.getByLabel('Email address')page.getByLabel('Password')// 3. By placeholderpage.getByPlaceholder('Enter your email')// 4. By text contentpage.getByText('Welcome back')page.getByText('Submit',{exact:true})// 5. By test ID — when other selectors aren't suitable// (requires data-testid="submit-button" in HTML)page.getByTestId('submit-button')// 6. By CSS or XPath — LAST RESORT (fragile)page.locator('.submit-btn')// CSSpage.locator('//button[@type="submit"]')// XPath — avoid when possible
// Navigationawaitpage.goto('https://example.com');awaitpage.goBack();awaitpage.reload();// Interactionsawaitpage.getByLabel('Email').fill('user@example.com');awaitpage.getByRole('button',{name:'Submit'}).click();awaitpage.getByRole('checkbox').check();awaitpage.getByRole('select').selectOption('value');awaitpage.keyboard.press('Enter');// Assertionsawaitexpect(page.getByRole('heading')).toHaveText('Welcome');awaitexpect(page.getByRole('button')).toBeVisible();awaitexpect(page.getByRole('button')).toBeEnabled();awaitexpect(page).toHaveURL(/dashboard/);awaitexpect(page).toHaveTitle('Dashboard');// Waiting (Playwright auto-waits, but explicit waits are sometimes needed)awaitpage.waitForURL('**/dashboard');awaitpage.waitForSelector('[data-loaded="true"]');awaitexpect(page.locator('.spinner')).not.toBeVisible();