Question:
In my application, I am using entity-framework version 6.1.3 to work with the mssql database.
There is a question of covering your code with tests.
Please tell me how to test for this bundle.
It comes to my mind to create a local test database, fill it with data and test methods on this database, with this approach, I can test both data retrieval methods and CRUD methods.
I also heard that in order to test methods for working with the database, you can create a generic
repository public interface IRepository<T> where T: class { }
and for testing slip a fake
repository with test data.
For now, I'm leaning more towards the first scenario, i.e. creating a local test database, which will be subject to the same changes as the real database (due to the migration mechanism in ef).
Tell me how correct will be the testing method described by me? I'd love to hear about other ways.
Answer:
Testing is the process of researching and testing software (software) that has two main objectives: to make sure that the software works and meets the requirements, and to identify situations in which the behavior of the software is incorrect, undesirable, or does not meet the initial requirements.
You are considering two testing options. In order to identify a more suitable one, it is necessary to find out the pros and cons of both approaches and, based on the results obtained, make a choice. I'm just giving you advice and you decide.
Option 1
Creation of a local test database, which will be subject to the same changes as the real database (due to the mechanism of migrations in EF)
This approach may exist, but looking at it, questions arise, but are you ready to sacrifice some of the shortcomings of this approach? The disadvantages I would include:
- Direct dependence of tests on the data stored in the database
- Data intersection for multiple tests. There are situations in tests when we simulate an error or expect incorrect behavior – this is quite normal. But what about in this case? We will have data both good and bad .
- Dependence on migrations. There are several subsections here. First : if we forget to make a migration, the tests will fall. Second : you must always remember that you need to do a migration for tests as well. Third : maintenance of such tests. What will the new programmer do?
- What if the database suddenly crashed ? Tests fail again.
- This approach cannot be called simple, it has its own difficulties.
- I think that this is also worth entering, I saw in the comments: To check the migration, you can always keep a backup of the desired version
Option #2
To test methods for working with the database, you can create a generic repository public interface IRepository where T: class { } and for testing slip a fake repository with test data.
This is a more convenient testing option, in my opinion. Let's look at why:
- We do not depend on the data in the database, since the data is prepared in the tests themselves.
- The data does not intersect, we always know that the tests only work with what we palm off on them.
- Simulating situations where we expect an error does not break our tests and does not lead to problems.
- Ease of use. You don't need to do migrations. There is a lot of documentation that will illustrate examples of using mocks (fakes).
- Testing speed. Mocks (fakes) have a very big advantage here. They work much faster.
There is a certain drawback of this approach, as I was told – this is testing the logic that is embedded in the database: indexes, concurrent access, etc.
Option #3
You can combine these approaches, bring something in between. For example, before starting to write data to the database – this is data preparation. Then work with a specific database in which our data is located, that is, a kind of database for tests. The main thing is not to forget to clean up after yourself – delete the data that is used for the test. This approach is rather cumbersome and also not simple.
Using this approach implies writing an auxiliary bun that will help . This will help you test CRUD methods. But here another question arises: who will test the auxiliary utility? So there is such an approach.
Well, one more question: Are you going to test your code or EF?
If you develop according to Test Driven Development , then the use of fakes greatly simplifies development.
I do not want to specifically focus on one option, I just want to advise you to make a choice that will be more correct and will not cause problems in the future. So that after a while you do not look back at the work done and do not say to yourself " Why didn't I go the other way? ".
The choice must be made based on the task at hand. Using only one approach is unlikely to succeed – most likely it is necessary to use several approaches.