RSpec Testing

by Convext

Public

RSpec testing patterns for Ruby

Rules (38)

Config

high Use environment variables for configuration

Config in env vars, not code. Never commit .env. Commit .env.example. Never hardcode secrets.

Csharp

high Use xUnit or NUnit for testing

xUnit preferred (modern, parallel). NUnit also good. Use `[Fact]`/`[Theory]` or `[Test]`/`[TestCase]`.

Database

critical Never store sensitive data in plain text

Passwords: bcrypt. API keys: encrypt. PII: field-level encryption. Never log sensitive data.

Dependencies

critical Always use latest dependency versions

Use latest stable versions. Fix breaking changes—don't avoid upgrades. Check official registries.

Git

medium Atomic commits with Conventional Commits

Small, focused commits. Use: feat/fix/refactor/test/docs/chore. Each commit independently deployable.

Go

high Use Go testing package

Built-in testing package. Table-driven tests. `go test -v ./...`. Use testify for assertions if needed.

Java

high Use JUnit 5 for testing

JUnit 5 (Jupiter) for all tests. Use `@Test`, `@BeforeEach`, `@ParameterizedTest`. Mockito for mocking.

Laravel

high Use Pest for Laravel testing

Pest is Laravel's default testing framework. Expressive syntax. Use arch tests for architecture rules. describe/it blocks.

Llm Behavior

critical No rationalizations

No excuses: 'pre-existing', 'unrelated', 'tedious', 'for now'. Recognize and continue working.

critical User defines success

User and tests define done. Don't redefine scope or declare partial progress as complete.

critical Own all code in the repository

You wrote every line. No 'pre-existing issues'—only issues you haven't fixed yet.

Php

high Use PHPUnit for testing

PHPUnit for all tests. Use data providers for parameterized tests. Pest for simpler syntax if preferred.

Python

medium Use unittest for Python basics

unittest for simple cases or legacy code. TestCase classes. setUp/tearDown. Prefer pytest for new projects.

medium Use pytest for testing

pytest with fixtures and parametrize. Simple asserts, rich plugin ecosystem.

Rails

critical Use Rails credentials for secrets

Rails.application.credentials for secrets. `rails credentials:edit`. Environment-specific credentials. Never commit master.key.

high Use Minitest for Rails testing

Minitest only—no RSpec. Rails default, fast, simple, fixtures-integrated.

Rust

high Use cargo test for Rust

`cargo test` for all tests. Doc tests in comments. Integration tests in tests/. `#[cfg(test)]` modules.

Security

critical Implement proper authentication and authorization

Auth: bcrypt/argon2 for passwords, rate limiting, secure sessions/tokens. Authz: check permissions on every request, use policy objects or middleware.

critical Use HTTPS everywhere

Force SSL, redirect HTTP→HTTPS, secure cookies (Secure/HttpOnly/SameSite), HSTS headers.

critical Validate and sanitize all user input

Allowlists, not denylists. Validate type/length/format. Sanitize HTML. Parameterized queries only.

Swift

high Use Swift Testing for new tests

Swift Testing (@Test, #expect) for new code. Cleaner syntax than XCTest. Parameterized tests with @Test(arguments:). Parallel by default.

Testing

critical No mocking the class under test

Test real instances. Mocking the class under test hides bugs.

critical Never ignore failing tests

Fix failures immediately. No skipping, no "pre-existing issues." Own the codebase state—a test suite with ignored tests can't be trusted.

high Test behavior, not implementation

Test public interfaces, inputs/outputs. Tests must survive refactoring. Don't test private methods.

high TDD: Red -> Green -> Refactor

1) Write failing test 2) Minimum code to pass 3) Refactor. Every line has a reason.

high Use Jest for JavaScript testing

Jest for unit/integration tests. `describe`/`it` blocks. Mock with jest.mock(). Snapshot testing sparingly.

high Use Vitest for Vite projects

Vitest for Vite-based projects. Jest-compatible API. Native ESM. Use @testing-library for components.

high Use Cypress for E2E testing

Cypress for E2E tests. Commands for reusable actions. cy.intercept() for network. Avoid flaky selectors.

high Use Playwright for cross-browser E2E

Playwright for multi-browser E2E. Auto-wait for elements. Trace viewer for debugging. Parallel execution.

high Mock only at external boundaries

Mock only: external HTTP APIs, time, filesystem side effects, third-party services. Use real implementations for internal services, database, and business logic.

medium Use Mocha for Node.js testing

Mocha with Chai assertions. describe/it blocks. Sinon for mocking. async/await in tests.

medium Integration tests over unit tests for web apps

Integration tests for full request/response cycle. Unit tests for complex logic, edge cases, performance.

medium Use fixtures or factories for test data

Use consistent test data setup: fixtures for stable reference data, factories for dynamic scenarios. Avoid inline object creation scattered throughout tests.

medium Use Capybara for Rails integration

Capybara for system tests. Use semantic selectors. Wait for async. Headless Chrome in CI.

medium Use RSpec for Ruby BDD

RSpec describe/context/it. let/let! for setup. FactoryBot for data. Avoid excessive mocking.

medium One assertion per test (conceptually)

One logical concept per test. Multiple asserts OK if same concept. Clear test names describing behavior.

Workflow

critical Code must work locally before pushing

Verify changes locally: run app, run tests, check for errors. CI catches environment issues, not basic bugs.

high Run formatter, linter, and tests before commit

Format → Lint → Test before every commit. Never rely on CI for basic checks.

Use this Ruleset

Sign in to adopt or fork this ruleset

Sign in with GitHub

Statistics

Rules
38
Standards
0
Projects using
0
Created
Jan 15, 2026