Optimize unit tests in Rails

Tram Ho

Unit testing is an integral part of every application. A system with unit tests that runs quickly and efficiently will save a lot of time deploying for the team during development. Here I suggest some ways to be able to optimize unit tests in rails:

Use: create,: build and: build_stubbed logically

create:

In this case a comment object will be created. It and all associations will be saved in Database.

build:

In this case, the comment object will not be saved to the Database but its associations do.

build_stubbed:

: build_stubbed will not call the Database. It will create and assign properties to an object to make the object behave the same as the object created by : create . Its associations will also be created with : build_stubbed so there is absolutely no impact on the database.

When to use: build_stubbed?

We have the model:

Factory:

Use rspec to test for the full_comment method:

In most cases it is not necessary to save the object to the Database. So when writing tests we should restrict the use of : create but instead use : build and : build_stubbed to reduce dependence on the Database. This makes the test run faster and more stable.

Eliminate unnecessary associations

In the above example we have Factory:

Every time we create a comment object, a post object will be created as well. This will affect the performance of the test case because it is not always necessary to use its association.

To avoid this, we can fix the factory to:

Now whenever you want to create a comment with a post just:

Use before (: all) to remove let! unnecessary

If the test sample in the first example has more test cases:

At this time let! will create a comment object for each case (a total of 3 objects) while maybe we just need to use one. We can edit the code as follows:

Now all testcase will use the same comment object.

However, you should be cautious when using before (: all) , in this case, doing the “global” comment object between test cases, test cases can change the properties of this object, leading to mistakes. skew the results of other test cases.

Use Mock and stub

If you do not want to execute a time-consuming method (such as call API, getting results from another heavily-handled module) you can fake the results returned by stub:

You can use receive_message_chain instead of receive to stub a sequence of methods as follows:

Refer:

https://medium.com/appaloosa-store-engineering/tips-to-improve-speed-of-your-test-suite-8418b485205c

https://relishapp.com/rspec/rspec-core/v/3-6/docs/helper-methods/let-and-let

https://github.com/thoughtbot/factory_bot/blob/master/GETTING_STARTED.md

https://medium.com/@DmytroVasin/speed-up-your-tests-via-build-stubbed-f1926863b3d7

https://www.netguru.com/blog/9-ways-to-speed-up-your-rspec-tests

Share the news now

Source : Viblo