Start API redesign with unit testing in mind
I am working on a Class Library project to support ASPX development. I need to be able to unit test the code I write. I also need to write integration tests that hit the database.
It seems impossible... I don't understand how you could have created 60 assemblies and manage to have dependencies all over the place, but you sure did.
Working with a database connection alone spans over 3 or 4 assemblies, with multiple hardcoded dependencies and 'providers' that are not providers (since you can't change them), and reinventions of classes that have been in the .NET BCL since 1.0 (no, you did not have to create your own Connection class).
And everywhere you go it seems that there is a hidden undocumented dependency on the HttpContext through CMSContext. Basically the majority of the Kentico API that you will typically use cannot run outside of a webserver.
I think your programmers have never even heard of unit testing before we started asking about it? (That would explain the many of the bugs I have reported so far.) It makes the whole API unfit for 3rd party development.
Kentico 8 introduced a big change in this area so I’m closing this idea as completed. Please see more information in the comments.
Thank you for the voting and comments.
Ian, currently, most of the developers are using one or more SOLID principles and most of the new code is testable. However, there is still a lot older or legacy code in solution which needs to be rewritten.
Chris, CI etc is another thing which is on our radar for upcoming versions, please contact me directly at email@example.com if you want to hear more details and you can give me feedback on this topic.
Kentico 8 introduces a lot of changes in API regarding to automatic testing. All the changes are described here: http://devnet.kentico.com/articles/test-automation-possibilities-in-kentico-8. Now, we need more specific feedback what to do next, so I created three new ideas for the specific improvements you mentioned in comments:
http://ideas.kentico.com/forums/239189-kentico-product-ideas/suggestions/5867887-remove-dependency-on-httpcontext-in-order-to-test - Removing HttpContext dependency
http://ideas.kentico.com/forums/239189-kentico-product-ideas/suggestions/5867895-make-all-helper-and-context-classes-as-non-static - Making Helper and Context classes as Non-Static
http://ideas.kentico.com/forums/239189-kentico-product-ideas/suggestions/5867908-have-interface-for-every-kentico-api-class-in-orde - Interface for every class in Kentico API
Please vote for these ideas if you see them as important. Also, if you have other ideas what to improve in order to test mor easily please create them and vote for them.
I'm closing this idea because we moved a lot forward with Kentico 8 and now we need more specific feedback what exactly you missing.
Might be well worth making sure all developers involved are familiar with SOLID - just abiding by these principles I think would drastically help. http://en.wikipedia.org/wiki/SOLID_(object-oriented_design)
As part of this I'd highly recommend removing the 'global static' objects. All of the Context objects feel like a major anti-pattern and can make it very difficult to debug code. I understand that they can simplify the API from a usability perspective but they make testing hard and side effects of some actions can modify these contexts under your feet. They basically feel quite unsafe to use.
"Adding interfaces to everything" is about v9 or v10, so about 2 years from now. For now, we are focusing on faking provider calls (which is already available through provider customization), but more importantly on info objects (e.g. UserInfo), so they can be used within unit tests without the database.
Chris Haines commented
Martin - for me, this is about a decision whether to go with Kentico or not. I need to see that this is on the agenda, and also to have some idea of timescale. Do you have any idea at all of v8 release?
The main issues to address is adding interfaces to everything so we can stub/mock. We need to be able to unit test our own modules.
However, there is another piece to this puzzle to consider, and that is VEST (Vertical Slice Testing) - http://codebetter.com/sebastienlambla/2013/07/11/unit-testing-is-out-vertical-slice-testing-is-in/
If you can look at shipping your API with a test-double that is *fast* (in memory SQL, etc.), then we can forget about stubbing & mocking and just test everything against the double.
It's all about a rapid feedback cycle when developing.
So the other piece to this puzzle is the build time. Yikes. And making Kentico CI-friendly. It needs to work with TeamCity. This is just standard developer stuff...
You have all the gadgets and gizmos -- the functionality is very impressive from a business point of view. But to get more developers on board, the developer workflow it has to be much friendlier.
Hi, some parts of it started with v8, but this is a long term process, we are writing unit tests for our own code, and base on them we improve the overall API and allow fakes for particular parts of the system. You will be able to fake HttpContext and Info objects for sure in v8, but other parts I cannot yet tell you, release of v8 is too far yet :-). You can expect these changes continuously throughout following at least 3 next years. We need to be careful to keep the API consistent and backwards compatible as much as we can so the upgrade process is smooth. Let us know what specific scenarios don't currently work for you right now, and we will see if we can prioritize them.
Chris Haines commented
So this is planned... but when will it be implemented?
Pete Lopez commented
Glad to see this is now a planned improvement!
They are very closely related, you just don't see it. The data model of Kentico CMS is data driven, so the attachment (any general data object) cannot be instantiated without the proper database behind. Also, all such objects are closely related to Staging supoport and behave based on Settings. It does not make sense to use them outside of the Kentico CMS database context. To initialize the connection string properly, you need to set it in your app.config or in SqlHelperClass.ConnectionString property, it is in the documentation.