Redmine for Test Management: A Complete QA Guide
Redmine is a project management tool that teams have been stretching into test management for nearly 20 years. It wasn't designed as a dedicated test management system — it was designed as a flexible, open-source project tracker. But its extensibility means QA teams can configure it to handle bug tracking, test case management, and test execution tracking with the right setup.
This guide covers how to configure Redmine specifically for QA workflows, including the plugins that make test management genuinely usable.
Redmine vs. Dedicated Test Management Tools
Before diving in: Redmine is not TestRail. It doesn't have native test plans, test runs, or pass/fail tracking out of the box. What it has is:
- Flexible custom trackers (you can create a "Test Case" tracker)
- Custom fields on any issue type
- Parent/child relationships between issues
- A reasonable workflow engine
- Solid plugin ecosystem
- REST API
If your team already runs Redmine for development and you want QA in the same system, it works well. If you're starting fresh and need dedicated test management, consider whether the Redmine approach is worth the configuration overhead.
Setting Up Redmine
Docker Installation
docker-compose.yml:
version: '3'
services:
redmine:
image: redmine:latest
ports:
- "3000:3000"
environment:
REDMINE_DB_MYSQL: db
REDMINE_DB_PASSWORD: password
REDMINE_SECRET_KEY_BASE: supersecretkey
depends_on:
- db
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: rootpassword
MYSQL_DATABASE: redmine
MYSQL_USER: redmine
MYSQL_PASSWORD: password
volumes:
- db-data:/var/lib/mysql
volumes:
db-data:docker-compose up -d
# Access at http://localhost:3000
# Default: admin / admin (change immediately)Core QA Setup
Custom Trackers
Redmine's "trackers" are issue types. Go to Administration → Trackers and create:
- Bug — defects found during testing (likely already exists)
- Test Case — individual test scenarios
- Test Execution — records of test runs
- Test Plan — grouping tests for a release
Each tracker can have its own workflow, custom fields, and status list.
Custom Statuses
Go to Administration → Issue Statuses. Create statuses appropriate for QA:
For bugs:
- New, Confirmed, In Progress, In Review, Fixed, Verified, Closed, Reopened, Won't Fix
For test cases:
- Draft, Ready, Needs Update, Deprecated
For test executions:
- Pending, Pass, Fail, Blocked, Skipped
Custom Fields
Go to Administration → Custom Fields → Issues. Add:
For Bugs:
Severity(list): Blocker, Critical, Major, Minor, CosmeticFound In Version(text): where this bug appearedTest Environment(text): browser, OS, deviceSteps to Reproduce(long text): if you want structured formatRegression Risk(list): High, Medium, Low
For Test Cases:
Preconditions(long text)Test Steps(long text)Expected Result(long text)Automation Status(list): Manual, Automated, In ProgressTest Type(list): Smoke, Regression, Exploratory, Performance
For Test Executions:
Actual Result(long text)Tester(user)Execution Date(date)Build Version(text)Pass/Fail(list): Pass, Fail, Blocked, N/A
Workflow Configuration
Go to Administration → Workflow. Set transitions for each tracker/role:
For Bugs (Developer role):
- Can move: In Progress → Fixed
- Can move: New → Won't Fix
For Bugs (QA role):
- Can move: Fixed → Verified
- Can move: Fixed → Reopened
This ensures only QA can mark bugs verified, and only developers can mark them fixed.
Test Case Management Pattern
Without a plugin, you can manage test cases as Redmine issues:
Test Case structure:
Title: [TC-001] Verify successful login with valid credentials
Tracker: Test Case
Status: Ready
Category: Authentication
Custom fields:
- Preconditions: User exists in system, not logged in
- Test Steps: 1. Navigate to login page\n2. Enter valid email\n3. Enter valid password\n4. Click "Sign In"
- Expected Result: User is redirected to dashboard, name shown in header
- Automation Status: Automated
- Test Type: RegressionTest Execution (child issue of the test case):
Title: [TE-001] Execute TC-001 for v2.4 release
Tracker: Test Execution
Parent: TC-001
Status: Pass
Custom fields:
- Actual Result: Redirected to dashboard correctly
- Build Version: 2.4.0-rc1
- Execution Date: 2026-06-05
- Tester: Jane SmithLink test executions to bugs when tests fail.
Essential Plugins
Plugins change what's possible with Redmine for QA.
Redmine TestKit (or Redmine Testlio)
Several community plugins add native test management:
redmine_testkit — adds proper test case management with:
- Test suites
- Test plans and test runs
- Pass/fail execution tracking
- Test coverage reports
Install:
cd /path/to/redmine
git clone https://github.com/pluginname/redmine_testkit.git plugins/redmine_testkit
bundle install
bundle exec rake redmine:plugins:migrate RAILS_ENV=productionRedmine Checklists
For simpler test step tracking within issues:
cd /path/to/redmine
git clone https://github.com/jbbarth/redmine_checklists.git plugins/redmine_checklists
bundle install
bundle exec rake redmine:plugins:migrate RAILS_ENV=productionAfter installation, issues can have checkboxes within their description — useful for step-by-step test cases.
Redmine Agile
If your QA team works in sprints:
- Adds Kanban boards per project
- Drag-and-drop status updates
- Sprint tracking
Version-Based Testing
Redmine's Versions feature (under each project's settings) is ideal for test planning:
- Create a version for each release:
v2.4.0,v2.5.0 - Assign test cases and bugs to their target version
- Use the Roadmap view to see progress per release
Before a release: all bugs assigned to that version should be Verified or Won't Fix. Track this in the roadmap.
Redmine REST API
Redmine has a stable REST API. Enable it at Administration → Settings → API.
Create a Bug
curl -X POST "https://redmine.example.com/issues.json" \
-H "X-Redmine-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"issue": {
"project_id": 1,
"tracker_id": 1,
"subject": "Payment fails with Amex cards",
"description": "Steps: 1. Add item to cart\n2. Checkout with Amex\n3. See error",
"priority_id": 3,
"custom_fields": [
{"id": 1, "value": "Critical"},
{"id": 2, "value": "production"}
]
}
}'Query Issues
# Get all open bugs for a project
curl "https://redmine.example.com/issues.json?project_id=myproject&tracker_id=1&status_id=open" \
-H "X-Redmine-API-Key: YOUR_API_KEY"
# Get bugs by version
curl "https://redmine.example.com/issues.json?project_id=myproject&fixed_version_id=5&status_id=*" \
-H "X-Redmine-API-Key: YOUR_API_KEY"CI Integration
import requests
REDMINE_URL = "https://redmine.yourcompany.com"
API_KEY = "your-api-key"
PROJECT_ID = "backend-api"
def create_bug_from_test_failure(test_name, error, build):
response = requests.post(
f"{REDMINE_URL}/issues.json",
headers={
"X-Redmine-API-Key": API_KEY,
"Content-Type": "application/json"
},
json={
"issue": {
"project_id": PROJECT_ID,
"tracker_id": 1, # Bug tracker ID
"subject": f"[CI] {test_name} failed in build {build}",
"description": f"**Error:**\n```\n{error}\n```\n\n*Filed automatically by CI.*",
"priority_id": 3, # High
"custom_fields": [
{"id": 1, "value": "CI Failure"} # Severity field
]
}
}
)
issue = response.json()["issue"]
return issue["id"]Reporting in Redmine
Redmine's built-in reports are basic. The most useful:
Issues report (per project):
- Filter by tracker, status, assignee, version
- Export to CSV for further analysis
Time entries — if your QA team tracks time, this builds a picture of testing effort per release.
Activity feed — recent changes across all issues. Useful for daily standups.
For serious reporting, many teams export to Google Sheets via the API and build dashboards there.
Access Control and Projects
For multi-team setups, Redmine's role/permission system gives you fine control:
- Developers see their project only
- QA team sees all projects
- Managers have reporting access
Set this under Administration → Roles and Permissions, then configure per-project under [Project] → Settings → Members.
Common QA Workflows in Redmine
Pre-release regression checklist
- Create a Test Plan issue for the release
- Add child Test Execution issues for each test case
- As testing proceeds, update execution status
- Block the release until all high-priority test executions are Pass
Bug triage process
- New bugs land in
Newstatus - QA lead triages daily: confirms severity, assigns to developer
- Developer moves to
Fixedwhen resolved - QA moves to
Verifiedafter confirming fix - Automated tests (via HelpMeTest) can also verify fixes
Regression test suite
- Tag regression tests with
regressionkeyword - Before each release: filter issues with
tracker=Test Case, keyword=regression, status=Ready - Execute the list, track results as child Test Execution issues
Redmine vs. Dedicated Tools
| Capability | Redmine | TestRail | Zephyr |
|---|---|---|---|
| Native test runs | Plugin required | Yes | Yes |
| Bug tracking | Excellent | Basic | Jira only |
| Cost | Free | Paid | Paid |
| Self-hosted | Yes | No | No |
| Customization | High | Medium | Medium |
| Setup effort | High | Low | Medium |
Redmine wins on cost and customization. It loses on out-of-the-box test management convenience.
Integrating with HelpMeTest
HelpMeTest automated tests complement Redmine's manual test tracking:
- HelpMeTest handles continuous regression testing (24/7 automated runs)
- Redmine tracks manual test cases, exploratory testing, and bug lifecycle
- Failures in HelpMeTest auto-create bugs in Redmine via the REST API
- Redmine bug resolution triggers a HelpMeTest re-run to confirm the fix
Together, they cover both the automated and manual sides of QA without forcing everything into one tool.
Conclusion
Redmine for test management isn't the path of least resistance — it requires configuration work upfront. But for teams already using Redmine for development, adding QA workflows in the same system is often the right call. Less tool switching, unified project history, shared access control.
Start with the custom trackers and fields, establish your workflow, and layer in plugins only when the native setup hits its limits. The teams that struggle with Redmine are those who try to replicate TestRail's UI exactly. The teams that succeed use Redmine's strengths — flexibility, parent/child relationships, strong API — and work with them rather than against them.