In my journey of learning Rails, I'm wondering if I should test model validations. If so, is this a correct way to do it?

require 'test_helper'

assert_not s.valid?, "Address was valid without any data"
assert s.errors.include? :name
assert s.errors.include? :phone
assert s.errors.include? :user
assert s.errors.include? :city

s.name = "Some"
s.phone = "8296964737"
s.user_id = 1

# Test Inclusion of city
s.city = "Santo"
assert_not s.valid?, "Address was valid with incorrect city"

s.city = "Santo Domingo"
assert s.valid?, "Address not valid with everything filled"
end

end


3.3 What to Include in Your Unit Tests

Ideally, you would like to include a test for everything which could possibly break. It's a good practice to have at least one test for each of your validations and at least one test for every method in your model.

In this case, what would be the correct way to add a test for a single validation?

## Unit tests

Unit tests should test the smallest behavior possible in each method of tests. Why ? Because when you make changes it helps determine what has break just by looking at failing tests.

3.3 What to Include in Your Unit Tests

Ideally, you would like to include a test for everything which could possibly break. It's a good practice to have at least one test for each of your validations and at least one test for every method in your model.

I added emphasis on something I find very important, you should test each validation on it's own. That way it's easier to see every rules your code have. By looking at your tests, I should easily see what your code is about and what I should expect to see.

## When you want to comment, refactor

Most of time when you add a comment it's a sign that you should refactor (this is not an absolute rule, but it's apply in a lot of case).

# Test Inclusion of city
s.city = "Santo"
assert_not s.valid?, "Address was valid with incorrect city"


Do you see what you did there ? It's a test case inside your test. If you need to reuse some constant or variable in a test, there are ways to do this without being in the same method. You can setup data in a method and call it in your test methods to keep your code clean.

You should have :

  test "shipping addresses validations" do
assert_not s.valid?, "Address was valid without any data"
assert s.errors.include? :name
assert s.errors.include? :phone
assert s.errors.include? :user
assert s.errors.include? :city
end

test "inclusion of city" do