Testing Stack
Gumroad uses a comprehensive testing stack for quality assurance:- RSpec 3.12 - Test framework
- Capybara 3.38 - Integration testing
- Selenium WebDriver - Browser automation
- Factory Bot - Test data generation
- Faker - Realistic fake data
- VCR - HTTP interaction recording
- WebMock - HTTP request stubbing
Running Tests
Setup Test Environment
Before running tests, ensure the test database is set up:1
Start Docker services
2
Setup test database
3
Export JavaScript constants
The
js:export command generates JavaScript constants for the test environment. Without this, tests may try to navigate to the development domain and encounter 502 errors.Running Test Suite
macOS Fork Error
If you encounter fork-related errors on macOS:Test Organization
Tests are organized by type:Writing Tests
Test Naming Conventions
Using Factories
Factory Bot provides test data generation:Integration Testing with Capybara
Capybara enables end-to-end testing through browser automation.Writing Capybara Tests
Element Selection Best Practices
Prefer semantic selectors over class names:1
Text content (preferred)
2
Input labels
3
Input placeholders
4
ARIA attributes
5
Class names (last resort)
Interaction Methods
Preventing Flaky Specs
Use have_selector for waiting
Use have_selector for waiting
Never use sleep
Never use sleep
Test multiple times locally
Test multiple times locally
Capybara’s
have_selector is smart and handles waiting automatically. Always prefer it over find when checking for element presence.Browser Setup
Chrome and ChromeDriver
Integration specs use Google Chrome:HTTP Mocking
VCR for Recording HTTP Interactions
VCR records HTTP requests and replays them in tests:WebMock for Stubbing
WebMock allows stubbing HTTP requests without recording:Testing Background Jobs
Sidekiq Test Helpers
Testing Guidelines
General Principles
Descriptive Names
Write test names that explain the behavior being tested, not implementation details.
Group Related Tests
Use
describe and context blocks to organize related test cases.Keep Tests Independent
Each test should be able to run in isolation without depending on other tests.
Test the Fix
Tests must fail when the fix is reverted. If a test passes without the application code change, it’s invalid.
API Endpoint Testing
For API endpoints, test:- Response status codes
- Response format (JSON structure)
- Response content accuracy
- Error cases and edge cases
Continuous Integration
Buildkite
Tests run automatically on Buildkite for every commit.Reproducing CI Failures
To reproduce Buildkite test failures locally, ensure:- Same Ruby and Node versions
- Fresh database setup
- Elasticsearch reindexed
- JavaScript exports updated
Troubleshooting
Chromedriver connection timeout
Chromedriver connection timeout
Problem: Integration spec times out with:Solution: Ensure Chrome and ChromeDriver are properly installed and versions match.
Rack timeout
Rack timeout
Problem: Integration spec times out:Solution: Create Then restart Spring:
.env.test.local with:Visual Testing
Gumroad uses QA Wolf for visual regression testing.- Enabled by default on
mainbranch - Not enabled by default on feature branches
- Catches visual regressions before production
Test Data Best Practices
1
Use factories over fixtures
Factory Bot provides more flexibility than fixtures and makes tests clearer.
2
Use realistic data
Faker generates realistic test data that catches edge cases fixtures might miss.
3
Clean data between tests
RSpec’s
database_cleaner ensures tests don’t interfere with each other.4
Use let and let! strategically
let is lazy-loaded, let! is eager. Choose based on when data is needed.Next Steps
Contributing
Learn testing requirements for pull requests
Architecture
Understand the system architecture
Authentication
Test authentication flows
Deployment
Deploy after tests pass