Mene
Mene

Reputation: 3799

How to test Ecto migrations

I have recently written some Ecto migrations in a Phoenix application.
However, I always tested the migrations manually.

As our migrations grow more complex and need to alter data on our live system, I'd really like to write automated tests before deploying them.

Automatic tests would require:

  1. Reset the database to a point right before the migration
  2. Run migration older than the migration to be tested
  3. Prepare data and insert it to the database
  4. Run migration
  5. Verify results match expectations
  6. Cleanup database to ensure upcoming tests don't clash with the data

We're using ExUnit and ESpec, but I haven't found a way to only apply some migrations prior specific tests.

Is there a way to write automatic tests for Ecto migrations?

Upvotes: 2

Views: 1958

Answers (2)

achempion
achempion

Reputation: 814

I would recommend against putting much logic into migrations. Migrations should change the structure of data layer, not the data itself.

The more direct approach to your issue is to create separate module with data transformation logic and write tests for this module. Then, you can apply migrations and call your module separately to apply transformations.

Also, keep in mind your application should work even if you decide to rollback application to previous release. I.e. if you want to remove column, create new column first, then transfer data and switch your application to use new column. On next deploy you can remove an old column.

You can call your data transformation module via Mix.Task.

Upvotes: 3

Aleksei Matiushkin
Aleksei Matiushkin

Reputation: 120990

This is possible with a bit of manual work. All these tests should have a tag (e. g. @tag :migr) and should be run as a separate test via

mix test --only migr

Details.

The standard tests should be run via

mix test --exclude migr

The latter might be set as a default config, for the former I would create mix alias.


Then you should create your own task, similar to ecto.migrate. It would roll up all the migrations till the specified one (this might be passed as a parameter,) and perform tests you want.


Sidenote: the necessity to test migrations is a very bad sign of the code design in general.

Upvotes: 3

Related Questions