Is it recommended to test model validations?

Asked

Viewed 332 times

1

My experience is with Ruby on Rails, but I believe my question will be for other cases.

The ORM Activerecord (from Rails) allows validating in fields things like:

  • Presence
  • Oneness
  • Size (of a string)
  • etc.

I am in doubt if I should create tests to check if these validations are working. Sometimes I think it doesn’t make much sense, especially the presence of a field, because this I can already define via bank through a Constraint NOT NULL, therefore is redundant.

Moreover, it seems that testing model validations takes more work than testing the controllers. And when I test a controller, in a way I’m testing the model as well, because the controller manipulates the model.

It is recommended or not to create tests for model validations?

3 answers

3

Regarding the situation of creating tests for validations, my answer is No. This is because you are probably already using a framework that already has tests and ensures that these validations work.

Therefore, avoid testing what has already been tested.

As to whether or not validations need to be defined, I would say it is best to define. True, constraints can (and should) be created in the BD itself. The difference is that if you arrive at the database without a mandatory value (for example), the query will fail. As long as you have the validations in the template, you can inform the user more pleasantly.

Of course "Graceful" errors also depend on the ORM / Framework you are working with.

  • Yes, defining validations is fundamental, otherwise we would have to use try/catch to treat errors. As for testing validations, it may be more necessary if you don’t want to define contraints at the bank.

  • 1

    Validating the model also helps with performance issues, as it avoids overloading the network and database server with something that could have been checked earlier.

  • @utluiz I don’t think the performance gain would be noticeable in most cases (but this is more my kick than experience). Besides, if the system is web, the validation will be done on the server anyway. And there are important reasons to create constraints at the bank.

  • 1

    @Andrey You are considering simple cases, such as criminal records. Even so, the overhead to open connection and transfer data between the application process and the database process can be large if several consecutive operations are performed. If you are entering, for example, 72 installments in the database of a financing operation and the latter has a problem, the time will be very noticeable, since the system will have opened a transaction and inserted data in several tables, created several Locks and transfer transaction data plus 72 tranches.

  • 1

    My concern is that we are always too optimistic about "it won’t affect performance so much". I thought so too, until one day I had to turn a system used in several resales upside down because it was giving timeout. Only with some "beasts" optimizations could I reduce the time by 90%, because little by little the "not perceptible" became practically unbearable.

  • 1

    Another problem that can occur is if there is high competition, that is, many users. Leaving validation to the bank also means opening an unnecessary connection in many cases. Of course each system is different, but it is good to think twice before assuming that there will be no competition problems, especially if the system is used online. However, if it is an internal system I agree with you~e.

Show 1 more comment

3


My answer is:

Depends, if you or your team uses Houlda-matchers, as quoted in another response, test validations becomes something trivial, so test.

However, I believe that Shoulda-matchers is an unnecessary dependency and you do not need to test very simple validations (such as validates_presence_of) or associations. This type of code comes straight from Rails and the only way you could make a mistake in it would be by misspelling the field name, which I believe is something easy to observe.

But imagine a case where validation depends on a reasonably complex regular expression, for example to validate a phone number. In this case, as the code is not so trivial it would be interesting to have case tests for more common valid and invalid phones and even some exceptional cases to ensure.

This test approach also applies to scopes: if you are creating a very simple scope, with a trivial query, do not write the test. However, if the scope involves complex rules and custom SQL, then it’s worth testing.

Watch Alexandre Freire’s lecture, 'What not to test' to better understand: http://www.infoq.com/br/presentations/o-que-nao-testar

Many people will say that you should test everything and should have 100% coverage. I would say that the right thing is to test what is important for your application: its business logic and things that have not been tested by the development of the framework. That is, one should test the maximum logic that does not depend on the framework. And the assurance that the framework works should be in the high-level (integration) testing, which will not test all the code but will serve as a health test to ensure that the parts work together and that the framework plays its role.

1

Depends on how you’re developing.

If you are doing test-driven design, i.e., Red-Green-Refactor makes sense to ensure that validations exist on the model.

Using Shoulda (https://github.com/thoughtbot/shoulda), you make the tests much easier.

Ex:

describe Post do
  it { should belong_to(:user) }
  it { should validate_presence_of(:title) }
end
  • Unknown this Gem, I’ll study it later. It seems much simpler than creating the tests in hand.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.