Set Up Your Testing Environment — Hands-On Software Testing, Part 1
- Shawn West
- Jul 8
- 3 min read
Updated: Aug 6
Hands-On Software Testing · Part 1
The reason people skip writing tests is rarely philosophical — it's friction. If running a test takes fifteen seconds and a context switch, you won't do it while you're in the middle of coding. This walks through setting up a testing environment where a test runs in a single keystroke, so testing becomes something you do continuously instead of something you schedule for later (and then don't).
Before writing a single test, you need a working test runner that's fast, gives clear output, and you trust. This tutorial walks through setting one up.
What You'll Build
A working test runner you can invoke with one command, that runs a placeholder test and reports clearly.
Step 1: Pick the Tool (5 min)
Common choices by language:
Python: pytest (default for most modern projects)
JavaScript/TypeScript: vitest or jest
Java: JUnit 5
C#/.NET: xUnit
Go: built-in testing package
Ruby: RSpec
Pick whatever's standard in your ecosystem. Don't overthink.
Step 2: Install (5 min)
Python:
pip install pytest
Node:
npm install --save-dev vitest
.NET:
dotnet new xunit -n YourProject.Tests
Install in a virtual env or contained context where possible.
Step 3: Configure (10 min)
pytest — pytest.ini:
[pytest]
testpaths = tests
python_files = test_*.py
python_classes = Test*
python_functions = test_*
vitest — vitest.config.ts:
import { defineConfig } from 'vitest/config';
export default defineConfig({
test: {
include: ['**/*.test.ts'],
environment: 'node',
},
});
Configuration is mostly defaults at first. Don't over-configure.
Step 4: Write a Placeholder Test (5 min)
Python — tests/test_smoke.py:
def test_smoke():
assert 1 + 1 == 2
TypeScript — src/smoke.test.ts:
import { test, expect } from 'vitest';
test('smoke test', () => {
expect(1 + 1).toBe(2);
});
You're not testing your real code yet. You're verifying the test runner runs.
Step 5: Run It (2 min)
pytest # or
npm test # or
dotnet test
Expected output: 1 test passed.
If it doesn't work, fix it now. The test runner working is the foundation for everything.
Step 6: Make It Fast to Run (5 min)
The faster the runner, the more often you'll use it. Aim for <5 seconds startup.
Skip slow plugins you don't need
Configure parallel execution if available
Use watch mode for tight loops
pytest: pytest --tb=short -q (terse output during dev)
vitest: npx vitest --reporter=basic (faster reporter)
Step 7: Wire Up Your Editor (5 min)
VS Code: install the testing extension for your runner. Run individual tests with one click.
This dramatically increases how often you'll run tests.
Step 8: Add a "Test" Script (3 min)
Make running tests trivial:
Node — in package.json:
{
"scripts": {
"test": "vitest",
"test:watch": "vitest --watch",
"test:run": "vitest run"
}
}
Python — in Makefile:
test:
pytest
test-watch:
pytest-watch
When the command is short, you run it more.
What You Just Did
You have a working test runner with a passing placeholder test. The infrastructure is now in place; the next tutorial writes a test that catches a real bug.
Time spent: 30 minutes. Worth it.
Common Failure Modes
Over-configuring at start. Adding plugins, custom reporters, etc. before you've written tests. Keep it minimal.
Slow runner. Multi-second startup. Investigate; fast feedback matters.
No watch mode. Running tests manually every change. Use watch mode during development.
Different runners in different contexts. Local uses X, CI uses Y. Same runner everywhere; CI is just non-interactive.
Continue the Hands-On Software Testing path
Part of the Hands-On Software Testing learning path.


