I got pretty experienced with testing controllers, my question here is though, aren't we supposed to test the data context as well, and how ? I mean, there are a lot of relationships and constraints coming from the DB that simply testing controllers does not cover.
On the other hand, testing against the DB is not considered a good practice - what then ? Simply testing without db.SubmitChanges() or what ?
IMHO you should not test the DataContext. Hopefully Microsoft have already done this, so testing that SubmitChanges will persist data into the DB is pointless for me. You should do integration or web testing where you would define a specific scenarios and verify the output from the application.
When it comes to testing your repositories, the typical approach is to create an in-memory database that can be torn down and rebuilt for each time you run your tests. By using this approach, you will always know what the data will look like so you can more easily make assertions against it. In addition, you won't be touching your real data, which is always a positive. Sqlite is the most popular one out there in the .NET space for this.
Yes, you should do integration testing of your data context to ensure that any "code" that you put in the database itself works -- uniqueness constraints, triggers, etc. This doesn't imply that you should do your unit testing against the database, however. Having said that, any code you put in your model classes should be unit tested. Usually, you can do this without having to test against the database directly. For example, any validation code should be able to run without requiring that you actually insert or update the DB.
Related
I'm new to testing in rails and I don't understand why or when I should use fixtures (or factory) rather than just seeding my test db and querying it to run the tests?
In many cases, it should be faster and easier to have the same data in dev and test env.
For example, if I want to test an index page, should I create 100 records via a factory or should I seed the db with 100 records?
I someone could clarify this, it would be great.
Thanks!
This is actually a deeper question of how to test efficiently, and you will find a lot of different opinions.
The reason to avoid a database in your unit tests is merely speed. Database operations are slow. It might not seem slow with one test, but if you have continuous integration going (as you should) or when you made a quick change and just want to see what happens, those delays add up. So prefer mocks to truly unit test code.
Then your own integration tests should hit an in-memory database rather than your real database--for the same reason, speed. These will be slower than your mocked tests, but still faster than hitting the real database. When you're developing, the build-test-deploy cycle needs to be as fast as possible. Note that some people call these unit tests as well. I wouldn't, but I guess it is just semantics.
These first two kinds of tests are by developers for developers.
Then the testers will hit the real database, which will be populated with test data defined by the testers and subject-matter experts. There are lots of clever ways to speed this up as well, but this will be the place where they test the integration of your code with the production-like database. If all your in-memory database tests passed and something goes wrong here, then you know it has to do with something like database configuration, vendor-specific SQL, etc. rather than something fundamentally bad. You will also get your first taste of what the performance is like.
Note that everything I've said here is a matter of debate. But hopefully it clarifies what you should consider about when to do certain things and why.
We are doing a new project, for all devices and browsers compatibility we have decided to use asp.net mvc 4, Html5, css 3, for communicating with Database Entity Framework we want to use.
Our senior members(Manager, DBA(they are also new to mvc 4, EF)) in the team asking us to write every thing will be in the stored procedures while communicating Database so that maintenance becomes easy.
Is it the correct match if we go like that(MVC4+ EF + stored procedures)? Will i not get maintenance and performance if i go with Code first reverse engineering(because database tables are ready i want to do like that), Please reply.
Below is the flow we want to do, please correct me
As Database is already ready, so first we will write the stored procedures for communication with DB.
New Mvc 4 project and will add .edmx file(EF) and select tables and Stored procedures
in mvc controller or web api we write the consuming stored procedures
There is nothing technically wrong with ASP.NET MVC + EF + Stored Procedures approach, from the first sight.
But my experience show, is that typically it's huge overkill. The common problem I see is the conflicting interests between developers and DBA's. In most worst scenarios all DB releated stuff are controlled by DBA, so if developer what to add/change some feature he needs to wait for implementation of it by DBA (or wait for approve, which could also take long).
So, I personally see that as more bureaucratic way of development.
My own perpective is to be more agile on development and tools like Code First matches that. Stored Procedures could still play major role, while code/performance optimization, but not something to start with.
I agree that using stored procedures in the database is a good approach. Centralizing data validation and calculations in the database ensures data integrity. Client-side validation is important for the user experience but you must also ensure that you test the data validity in the database.
Using Entity Framework, you can generate entities which relate directly to tables in your database, or else you can design entities which use procedures for insert/update/delete operations rather than simple table updates.
In MVC you will use the entities as models to manage your data interactions.
Good luck
This is my personal view. I am sure others might have different ones. Since you are asking this question I am hoping you are open for discussions, otherwise I wouldn’t have bothered as this topic is like a religious discussion as lots of people have very strong opinions and are not likely to change them.
Personally I don't think stored procedures are meant to write business logic. They should be used for writing data access logic. I would only use a stored procedure if I want to optimize an expensive query such as a dynamic search but nothing else. You will get slightly less performance if you have your logic in the domain model, but its not even noticeable in most situations.
One of the strong arguments for writing business logic in stored procedures is because you can easily change some logic by changing your stored procedure. But should we really go and change the business logic of a deployed application without doing proper testing. What will happen if you accidently do a mistake? Doing a deployment is not such a big deal now with continuous builds and I don’t think as a professional developer you should take that risk.
When you decide to write your logic in stored procedures, you give up all the object oriented concepts and you end up writing some procedural code that we wrote maybe 10 years ago. C# language has come a long way now and you will not be able to use those new language features in heart of your application which is business logic. You also loose the visual studio features to refactor code, advanced and easy debugging features etc.
I also don’t like the idea of having triggers as it’s not visible in source code. Imagine someone new in your team trying to add a new feature some time later and if he doesn’t know that a trigger exists, he might write some incorrect logic.
If your application contains some complex business logic, (I am sure most applications do) you should have a domain model that contains not only just properties of your entities, but also your logic. Otherwise you will be falling in to the anti-pattern called anemic data model.
You will not be able to test your business logic by writing unit testing if you have your logic in stored procedures.
You will also not be able to deploy your business logic to multiple servers if you have them in stored procedures if your site becomes really successful.
You will also not be using all powerful capabilities of Entity framework and LINQ if you have all your logic in your stored procedures. You actually don’t need an ORM Mapper if that is the approach you are going to take.
This is what I would recommend for your project.
Even though you already have the database, you can still use code first approach of Entity framework. You can download the EF code first reverse engineer power tool and have the code first code auto generated for you. This is going to be a one off thing and after than if you have any more changes, you can directly do to the database and update the code first code accordingly. Fluent API is bit confusing at first, but you can easily learn that from the generated code.
Do not access your data context from the controller. Have a repository layer that will contain all your data access logic. You can access the repository from your controller. (This allows you to unit test your code by mocking the repository). There are lots of video tutorials on how to use the repository pattern on asp.net site.
Your domain model is going to be the entities that got generated from the Entity framework. Try to have your business logic in those models. It takes a little while to get use to the domain model pattern. But one you get used to it you will start to appreciate its benefits.
Hope this helps.
I have started recently using SpecFlow and I have 2 basic questions I need to clarify, also to confirm I am on the right way:
As I understand, it is a must that all the input data (test parameters for the scenarios) to be provided by the tester, the same about the test data (input data for the tables involved in the test scenarios)
Are there any existing tools for a quick way of generating test data (inserting it into the DB) ? I am using Entity Framework as part of the Data access layer. I was wondering about some tool that would read the data from a file or probably some Desktop application to provide values for the table's fields (which could also then generate a file from which some other tool could read all the data and generate all the required objects etc).
I also had a look at Preparing data for a SpecFlow scenario - I was thinking if there is already a framework which would achieve insert\delete of test data to use alongside with SpecFlow.
I don't think you are on the right track. SpecFlow is a BDD tool, but in some ways it only covers part of the process. Have a read of http://lizkeogh.com/2013/07/01/behavior-driven-development-shallow-and-deep/ and see if any if the scenarios sound familiar?
To move forwards I would recommend you start with http://dannorth.net/introducing-bdd/ to get a good idea of how it all began. Now lets consider your points;
The tester provides all the test data. Well yes and no. The idea is that between yourself and the feature expert, you are able to have a conversation that provides all the examples that you need to develop your feature. If you don't involve yourself in that conversation, then yes all the data will come from the other side, but the chances are it won't be such high quality as if you are able to ask the right questions and guide the conversation so the data follows a structure that you can code tests too.
As an example here, when I first started with BDD I thought I could get the business experts to write the plain text scenario files with less input from the development, but in practice the documents tended to be less useful than when we were involved. Not because they couldn't write decent specifications, but actually because they couldn't refactor them to reuse bindings etc. We were still needed to add our skills into the process.
Why does data go into a database? A good test is isolated to the scope that it is testing. For a UI layer test this means that we don't have a database. For a business tier test we shouldn't be reliant on the database to get data either.
In practice a database is one of the most difficult things to include in your testing because once any part of the data changes you cause cascading test failures.
Instead I would recommend making your features smaller and provide the data for your test in the scenario or binding. This also makes having your conversation easier, because the fiftieth row of test pack is not something either party is going to remember. ;-) I recommend instead trying to give you data identities, so "bob" might be individual in a test you can discuss, and both sides understand what makes him an interesting example.
good luck :-)
Update: With regard to using a database during testing, my experience is that there are a lot of complexities that make it a difficult choice to work with. Consider these points,
How will you reset the state of your data between tests?
How will you reset the state if one / some tests fail?
If you are using branches or even just if two developers are making changes at the same time, how will you support multiple test datasets?
How will you handle two instances of the tests running at the same time (don't forget the build server)?
Have a look at this question SpecFlow Integration Testing with Database Patterns which includes some patterns that you can use.
Things started off simple with my fake repositories that contained hard-coded lists of entities.
As I have progressed, my shared fake repositories have become bloated. I am continually adding new properties and new entities to these lists. This is making it extremely difficult to maintain and it is also difficult to see what the test is doing. I believe this is an anti-pattern called "General Fixture".
In researching ASP.NET MVC unit tests, I have seen two methods for preparing repository fixtures that are passed on to the controllers.
Create hard-coded fake repositories that are shared among all tests
Mock parts of the repositories within each test
I'm tempted to explore option #2 above but I've read that it's not a good idea to mock repositories and it seems quite daunting in the scenarios where I'm testing a controller that operates on collections (i.e. with paging/sorting/filtering capabilities).
My question to the community...
What methods for preparing repository fixtures work well beyond rudimentary examples?
I dont think you should only be choosing one of the two options. There are cases when using a fake repository would be better, and there are cases when mocking would be better. I think you should assess what you need on a case by case basis. For example, if you are writing a test for a UsersService that needs to call an IUserRepository.DoesUserExist() that returns a boolean, then you wouldnt use a fake repository, its easier just to Mock a call to return true or false.
Moq is awesome.
For a similar reason on a new project I'm looking into using an ORM (NHibernate in my case). That way I can point it at an "in-memory" SQLLite instance (rather than SQL Server) and it should be far easier to set up / maintain (I hope). That way I will only need to mock the repository if I have a requirement to test particular scenarios (such as time-outs, etc)
If you are using your Unit Tests for TDD, download Rhino Mocks and use optione #2.
For the most part, we go with test specific repository mocks. I've never seen advice not to do this myself and I find that it works great. For the most part, our repository methods and therefore our mocks only return single models or lists of models (not data contexts) so it is easy to create the data specific for each test and isolated to each query. This means that we can mock whatever data we like without affecting other tests or queries in the same test. It is very easy to see why the data was created and what it is testing.
I have been on teams have also decided to create shared mock data from time to time as well. I think the decision was generally made because the routines generated dynamic queries and the data required to mock all of the tests resulted in a good portion of the database being duplicated. However, in retrospect, I probably would have suggested that only the resulting queries need to be checked, not the contents returned from the database. And thus, no data at all would be mocked though, it would have required some code changes. I only mention this to illustrate that if you can't see to find a way to make option 2 work, maybe there is a way to refactor the code to make it more testable.
I am new to the whole unit testing stuff, so please excuse my lack of experience. I've read a lot of materials saying that no test should depend on others to do, i.e unit tests be completely independent form each other. Can you really do that in reality? I am having the following example: I have a few entity classes depending on each other, based on a certain database schema (I am using Linq- to SQL to generate them) Now, if I want to test each model class I have to build an object of the model class , build a test object of each of its dependencies, assign them to the object's properties and then persist the object before checking the context and asserting that it actually works.
This obviously makes it much harder to make tests that do not depend on each other, or do not run in a specific sequence (I do not an instance of type Content to be created before I have at least one instance of type ContentType) Dependency, at least on a model level is present and cannot be avoided.
Please, criticize me a lot, if you think that I am wrong. I want to learn.
P.S. Just to mention that I am working on an ASP.NET MVC app and testing with NUnit if that makes sense
Yes, you can really do this in reality.
The key to be able to isolate each unit is in writing loosely coupled code. Taking a dependency on LINQ to SQL (L2S) classes is not loosely coupled, which explains your problems.
You would be better off defining a set of interfaces behind which you can hide your L2S code. The Domain Model then works on those interfaces instead of directly on the L2S classes.
Yes, unit test should (and can) be independent. The problem you describe is about dependency. Dependency should be resolved using Dependency Injection frameworks (see AutoFac, Ninject projects).
The other thing is that your Database should be mocked using mock objects (see Moq, Rhino Mocks projects). You need to test all your code even if you database is disconected.
Other thing is that Unit test should test only one functionality not all your process.
What you describe here is not unit tests but integration test. Because the data model of your application is tightly coupled with the database your tests probably test the database functionality and not the "datamodel".
This is perfectly fine - just keep in mind that integration tests need setup (in your case database) and take longer to run.
You also probably have unit tests for your controllers that can be completely isolated from other components and do not need database to run, these are the unit tests you talk about.
If you do not test actual database functionality you can use fake/mock object to replace the external classes - in fact the tests created with the initial MVC project have an hand rolled fake objects along that do exactly that.
Another way to "isolate" your external dependencies is to warp the Linq2Sql code with your own class and fake these class calls using Mocking framework.