require 'test_helper'
class UserTest < ActiveSupport::TestCase
test "should not save user without email" do
user = User.new
assert_not user.save, "Saved user without email"
end
test "email should be unique" do
existing_user = users(:one)
new_user = User.new(email: existing_user.email)
assert_not new_user.valid?
end
end
assert
/ assert_not
- базовые проверкиassert_equal
- проверка равенстваassert_difference
- проверка изменения значенияassert_raises
- проверка исключенийrequire 'application_system_test_case'
class UsersTest < ApplicationSystemTest
test "visiting the index" do
visit users_url
assert_selector "h1", text: "Users"
end
end
gem 'rspec-rails'
rails generate rspec:install
describe User do
let(:user) { build(:user) }
it "is valid with valid attributes" do
expect(user).to be_valid
end
context "without email" do
before { user.email = nil }
it { should_not be_valid }
end
end
describe UsersController do
describe "GET #index" do
it "returns http success" do
get :index
expect(response).to have_http_status(:success)
end
it "assigns @users" do
user = create(:user)
get :index
expect(assigns(:users)).to eq([user])
end
end
end
require 'rails_helper'
RSpec.feature "Users", type: :system do
scenario "User creates new account" do
visit new_user_path
fill_in "Email", with: "test@example.com"
click_button "Create"
expect(page).to have_text("Account created")
end
end
Именование тестов:
test "description" do
it "does something" do
Фабрики вместо фикстур:
# Используйте FactoryBot
let(:user) { create(:user, email: "test@example.com") }
Принцип 3A:
Тестируйте поведение, а не реализацию
Добавляйте контексты для разных случаев:
context "when user is admin" do
before { user.update(admin: true) }
it { should be_able_to :manage, :all }
end
it "sends welcome email" do
allow(UserMailer).to receive(:welcome).and_return(double(deliver_now: true))
user = create(:user)
expect(UserMailer).to have_received(:welcome).with(user)
end
it "enqueues job" do
expect {
User.create(email: "test@example.com")
}.to have_enqueued_job(SendWelcomeEmailJob)
end
it "returns JSON" do
get "/api/users", as: :json
expect(response).to have_http_status(:ok)
expect(JSON.parse(response.body)).to include("users")
end
Резюмируем: и Minitest, и RSpec позволяют эффективно тестировать Rails-приложения. Minitest проще и быстрее, RSpec предлагает более выразительный синтаксис для сложных сценариев. Выбор зависит от предпочтений команды и сложности проекта. Главное — писать чистые, изолированные тесты, которые действительно проверяют функциональность приложения.