How can I unit test my FluentMigrator migrations? - unit-testing

The general advice is I should always test my database migrations, but how to do it seems to be a well kept secret ;)
My chosen framework is FluentMigration.
What I think I want to do is:
Migrate database to N-1.
Save some data.
Migrate database to N.
Read data and verify it's not lost.
Verify other relevant changes
But I can't figure out how to run the migrations from my unit tests.

To kick off the migration in your integration tests just shell out to the migrate.exe command using Process.Start
For example
var migrator = System.Diagnostics.Process.Start("migrator.exe", "/connection \"Data Source=db\\db.sqlite;Version=3;\" /db sqlite /target your.migrations.dll");
migrator.WaitForExit();
If you're using MSTest you'll have to make sure that migrator.exe is included as a deployment item, or that you specify a path to where the .exe lives when you start the process.

Related

How can I run integration tests without modifying the database?

I am making some integration tests for an app, testing routes that modify the database. So far, I have added some code to my tests to delete all the changes I have made to the DB because I don't want to change it, but it adds a lot of work and doesn't sounds right. I then thought about copying the database, testing, deleting the database in my testing script. The problem with that is that it is too long to do. Is there a method for doing that ?
I see two possible ways to solve your problem:
In-memory database e.g. (h2)
Database in docker container.
Both approaches solve your problem, you can just shutdown db/container and run it again, db will be clean in that case and you don't have to care about it. Just run new one. However there are some peculiarities:
In-memory is easier to implement and use, but it may have problems with dialects, e.g. some oracle sql commands are not available for H2. And eventually you are running your tests on different DB
Docker container with db is harder to plugin into your build and tests, but it doesn't have embeded DB problems with dialects and DB in docker is the same as your real one.
You can start a database transaction at the beginning of a test and then roll it back. See the following post for details:
https://lostechies.com/jimmybogard/2012/10/18/isolating-database-data-in-integration-tests/

Techniques to Avoid Problems with Django Migrations?

I'm building an e-commerce website with Django 1.8 and PostgreSQL 9.4. I'm interested in learning what techniques I can use when I change my database to avoid having problems with Django migrations, particularly in the event that I can't get migrations to run and I have to delete my migrations, rebuild my database, and restore from backups.
In development, I've found that when I change my database schema and re-run migrations, they only run successfully about 50% of the time. Clearly I'm doing some things wrong. What's worse is that when migrations don't work, it's not always easy to understand exactly why they failed and how to modify my migration files so that they will run. In those situations, I always have to delete the database and start over. This is acceptable in development but it's not a good strategy when I go into production.
What are some "best practices" or "do's and don'ts" you follow when you modify your model classes/database schema so as to increase the probability that your Django migrations will run? And are there any steps you take to ensure that you can restore your database in the event that your migrations won't run and you have to rebuild the database from scratch? I should add that I'm a one-person startup so I don't have the conflict issues that a team working from the same code base would have.
These Techniques are what I'm using
Work locally in the same environment what I'm working in it on server. Same version of the Django and database server then push the migrations itself, don't ignore it, and migrate on the server using there migrations.
This one I used once that I migrate manually, I created the tables, indices, relations using sql commands manually and it worked properly too.
I prefer the first one more

Django Testing: Does --keepdb reset changes made during tests?

According to the Django docs regarding tests, the --keepdb flag will preserve the the test database for future runs.
https://docs.djangoproject.com/en/1.8/ref/django-admin/#django-admin-option---keepdb
Just to be clear, will any changes made to the database by the tests (ie: object.save() ) be reset automatically? Or will these changes need to be reversed from within the tests?
If you're using Django's default TestCase, all tests are run in a transaction, which is rolled back when the tests finishes. If your database supports transactions, you won't have to clean up anything.
If you're using Django's LiveServerTestCase or TransactionTestCase, all tables are truncated after each test, and the initial data, which is serialized before the test, is reloaded into the test database. This will not preserve any data for migrated apps, only for unmigrated apps.
The --keepdb option will not do anything special with the database. It simply prevents that the test database is destroyed, and if a database is found at the start of the tests, it is used instead of creating a new one. So, any data that is somehow left in the database when the tests finish will be seen as initial data. This is mostly relevant if some error or a user interrupt prevents tests without transactions from cleaning up the database. In that case it may be a good idea to recreate the database.

Django: How to keep the test database when the test is finished?

Some of my requirements are these:
Create a in-memory sqlite3 database.
Read a list, and pull those data from
production database.
Perform unit tests
Remain the test database.
Perform some intelligent UI tests using the same test database.
I am not a pro in test, but these have to achieved, anyone professional who can suggest a best practice in this area?
Thanks very much for your help!
New in Django 1.8
The --keepdb option can be used to preserve the test database between test runs
https://docs.djangoproject.com/en/1.8/ref/django-admin/#django-admin-option---keepdb
You can run:
./manage.py testserver
Your test database will be created, all your tests are run and afterwards the server keeps running, so you can do your ui testing.
hope this helps,
Anton
Persistent Database Test Runner adds a new command called quicktest that will retain the database after the test is run, and use the same when run again.

How do I tell Django to save my test database?

Running Django unit tests is far too slow. Especially when I just want to run one test but the test runner wants to create the entire database and destroy the whole thing just for that one test.
In the case where I have not changed any of my models, I could save oodles of time if Django would not bother trying to create and destroy the entire database, and instead saved it for next time. Better yet, it would be great if the test runner was capable of being able to see which models have changed and only replacing those prior to running tests.
I'd prefer to not have to subclass the test runner myself, but that's what I'm going to have to do if I don't find a solution soon. is there anything like this already in existence?
In django1.8 added new parameter for manage.py test command --keepdb
./manage.py test --keepdb
Have you tried using an in-memory SQLite database for tests? It's much faster than using a disk-based database.
I'm using Djang-nose. If you set a env var REUSE_DB=1 it will not destroy the DB after running tests and re-use that same DB for the next run. Whenever your schema changes, just set REUSE_DB=0 and do one 'full' run. After that reset it to 1 and you're good to go.
https://github.com/django-nose/django-nose