It seems to me that web developers of different programming languages often share different opinions on this. For example, Ruby web developers (with Rails being the dominant framework) appear to think of controllers as glue code, which should have functional tests, but not unit tests. A similar attitude dominates in the PHP world, yet there has been some initiative (e.g. Symfony2).
However, it also seems that, for example, some ASP.NET MVC developers actually want their controllers to be unit-testable.
What I'd like to know is if that actually works in web development. Are controllers worth unit testing? Does designing them to be unit-testable noticeably cripple development speed in non-trivial applications? Also, have any web frameworks tried to enforce controller unit-testability? Personal experiences are welcome.
Short answer: "Yes" with an "If," long answer: "No" with a "But."
These days I tend to miss controller-level unit tests in favour of strong unit-test coverage of models and business objects and functional-test coverage with Cucumber. The assumption here is that the controllers are very light-weight objects routing data into underlying models that encapsulate the vast majority of business logic.
However, I still do tend to have some very light coverage of some of the control flow at the controller level. It just tends to be more of a sanity-check.
One of the issues with controller-level testing is that you often either have to mock or generate a large number of models and objects in order to test effectively. Given this, I find it more valuable to push these tests up into the functional layers where the style of testing allows you to more efficiently express these dependencies (either by explicitly following the steps required to generate them through your application itself or through a system like Cucumber's declarative rules).
Everything is worth to be unit tested. In this case it depends on how much of the logic is realized in the controllers... In small project you can have no external logic attached and you may want to make some of the database operations in your controller (like on many Microsoft examples). In bigger solutions you may not need to test the controller as far as it's job is just to invoke specified business logic methods... It's not about if controllers are worth to be unit tested, it's about if the code that they contains is...
One of the best features of the MVC pattern is that the controllers can be tested in isolation of the HTML output by the views. Pages that mix the logic with the HTML output are hard to test, and this is one of the problems that MVC solves - it makes your controller all about logic and you can test it without parsing HTML at all.
Ideally, your controller will get data from separate data access classes, which you can stub out for your tests, so you are just testing the logic. Essentially you isolate your controller from the database in the same way MVC isolates it from the view - then the tests are easy because you don't need a database with test data either.
Related
The symfony 2 installer gives a best practice directory structure, but not a lot is said about how these directories should be used, where does each piece of code belong, sure the symfony framework narrows it down to views, entities and controllers, services etc. but more often then not, programmers end up putting a DQL query inside a controller and some logic to handle a specific task, while this does the job, there has to be a better method, even beyond symfony's out of the box directory structure, currently on a quest for better design pattern that would modularize and reuse as much as possible
On this quest, found a couple good articles on the interwebz, and spent a day on it, came up with a plan to separate all DB interactions to repositories, all logic to services, and keeping the controller 'thin' which acts as a central point for calling methods from repository and calling services. sounds good, will be modular and code can be reused.... BUT
This somehow moves away from OOP concepts and right into procedural programming, not that there is anything wrong with it, its just not leveraging the powerful concepts of OOP
Could making the objects more 'powerful' by adding in more functionality make it better? the services by definition should do a unit of task, will my approach make them big and ugly
a few good points on this blog here but could't really make out what they were trying to suggest as a solution
In general, the more behavior you find in the services, the more
likely you are to be robbing yourself of the benefits of a domain
model. If all your logic is in services, you've robbed yourself blind
-Martin Fowler
to summarize is Service oriented approach not leveraging the concepts of OOP? and how could this be supplemented
One of most important thoughts which you can find in Fowler's "Patterns of Enterprise Application Architecture", is that you should use right tools for your job. Depending on the complexity of your problem and domain, one or the other design pattern/architectural pattern may perform better. And following that way, in contrast to old frameworks (ZF1, SF1), SF2+ doesn't force you to go for any architectural pattern or organizing your business logic in specific way. You can even put everything outside bundles structure. So the best thing, which you can do, is to try learn more about design patterns (generally). And then, when you need, you will be able to pick one which will work best for your case.
You may want to look at:
mentioned earlier "Patterns of Enterprise Application Architecture", especially chapter: "Domain Logic Patterns".
The Four Architectures that will inspire your programming short review of different architectures.
any of books covering DDD, like: E.Evans "Domain-Driven Design", V.Vernon "Implementing Domain-Driven Design" or S.Millett and N.Tune "Patterns, Principles and Practices of Domain-Driven Design"
Domain-Driven Design in PHP decent book covering implementation of DDD patterns in PHP application, with some examples based on SF.
The Clean Architecture in PHP implementation of The Clean Architecture for PHP, focusing a lot on framework independence (with examples for ZF2 and Laravel).
With Domain Driven Design it creates fat model layers, and also calling a lot of services inside your controller may modularize your code, it still has its own set of challenges, it makes the design harder to create, and at some point there will be too many service calls inside the controller, what can actually be done is to use a few concepts from DDD.
two things to remember before starting DDD is :-
cohesion - modules that change together
coupling - modules that are dependent on each other
You need to lessen the coupling and recognize the cohesion and design the project according to it, main goal is to allow adding and removing or enable/disable/recombining of modules in future, in case you decide to alter the project
instead of having bundles depend on each other use interfaces instead
namespace MyProject\UserBundle\Activity ;
use MyProject\NotificationBundle\Notification;
use MyProject\MailBundle\Mail;
where UserBundle is coupled with NotificationBundle and MailBundle use interfaces that abstract the bundles instead
namespace MyProject\UserBundle\Activity ;
use MyProject\ServiceBundle\NotificationInterface;
use MyProject\ServiceBundle\MailInterface;
Main concepts of DDD are
value objects - an object that holds some data and is passed back and forth and does not focus identity but rather on the data that it holds, value objects can be used in symfony using embeddables
Entity - an object that holds some data but is dependent on an identity value rather than its data value
Repository - use of repository classes to make database operations make it possible to change the implementation later on, as it is centralized to one place
Aggregate - when several object belong together like a number of things that belong to a single category (eg: songs that belong to a genre), the entire collection of objects are treated as one and to make alteration to these objects would be thought on single aggregate object
Domain Events - any change in the state of the domain/data is regarded as an event, in symfony there are Event Listeners and Subscribers which can stand in for domain events, this is one of the most important concepts of DDD, filter also a great deal of improvement to the code
services - services are callable modules of code that do a unit of work, services allow code to be reused and are easier for testing and updating, services in symfony should contain the domain logic and the service layer can get pretty fat, this along with events make the code faster and more maintainable
Factory patter - this patter uses a 'factory' object that generates a different object, by doing this the name of the second object is abstracted, this helps when refactoring the code
these are generalized concepts that need to be applied to code that is highly situational, proper DDD requires the code to be modular which is a challenging task to achieve and need some experience on the engineer's part.
as already stated by others, books by 'martin fowler', ' V.Vernon' design patterns by ' gang of four' etc would be a good read
First of all there are best practices where to place files/components: http://symfony.com/doc/current/cookbook/bundles/best_practices.html.
Secondly http://symfony.com/doc/current/best_practices/business-logic.html:
In Symfony applications, business logic is all the custom code you write for your app that's not specific to the framework (e.g. routing and controllers). Domain classes, Doctrine entities and regular PHP classes that are used as services are good examples of business logic.
So you are not forced to use any architecture for your business logic.
Regarding your question - you can implement objects with operations and declare them as services (or use them directly, but in this case when you want to replace some functionality you'll need to rework more code).
there are always a lot of principles of software designing and we select what we think is more correct and makes more sense for a project and Symfony doesn't force us to use some special design pattern.
I wrote in PHP a learning management system for a small private school. It started a while ago when a lot of programming stuff was new to me. It is mostly scripts and includes based and doesn't contain classes or any MVC style organization, but it has grown big. What I am trying to do is to organize the current code without rewriting, so that it is good for fast iterations.
So far I changed it so that every role has its own folder/index/actions and all of them use one shared lib.php file to do sql queries and other related actions.
I talked to couple of MVC folks and considered PHPCake and Tonic as an option, but those seem to change dramatically what I already have. I am not sure if it just in my practice, but I just don't see how MVC will make it easier for me to develop faster. Can someone give tips or experience advise/opinions or maybe some helpful links. Thanks.
MVC can be a useful framework for developing applications into logically separated components in a somewhat 'natural' way. It can increase your ability to develop quickly based mainly off the fact that some portions of the framework will end up being reusable and allow you to leverage that fact to develop new views and similar quickly. However, it is not necessary to use any particular framework or scheme to develop quickly as it can be done with a properly designed application of any nature.
An important thing to consider when developing an application in such a manner is code reuse. For example, making it simple to display pages with common layouts through a centralized mechanism, or having user-related functions placed into a user class/function set which can be reused site-wide instead of having individual functionality to handle it on each page.
In terms of modifying an existing application, I would focus on trying to centralize the components you are able to and making use of those components henceforth. This also makes modifying routines simpler because instead of potentially changing functionality on many areas of the codebase, you can change it in a single location and effect the application as a whole.
Trying to make a pattern fit a problem is a very silly approach. Patterns are what code is not what what the code should be. In any object-oriented project presenting a user interface there will be instances of models, views and controllers - but there will also be lots of other patterns in the code - observers, decorators, iterators and more. They are useful learning constructs (e.g. "Here's how to implement a factory to build objects from relational data") and (human) language constructs (e.g. "That database connection class should be implemented as a singleton"). They are not design constructs.
so that every role has its own folder/index/actions
Unless you've got a rather unusual definition of 'role', this architecture makes no sense. The most common criteria for dividing up high-level functionality are separation of concerns and grouping around common data sources.
You've mentioned frameworks - trying to adapt existing code to fit into a framework is usually a bad idea - it won't fit. They can be of benefit in structure your application and reducing the amount of effort if you sse them from the start of the project. Not from the middle / end.
Put the new code you write under test. As the old code isn't, put it under test part-by-part as well. At the moment you've put everything under test, you should be fine for faster iterations.
I've been learning Zend and its MVC application structure for my new job, and found that working with it just bothered me for reasons I couldn't quite put my finger on. Then during the course of my studies I came across articles such as MVC: No Silver Bullet and this podcast on the topic of MVC and web applications. The guy in the podcast made a very good case against MVC as a web application architecture and nailed a lot of what was bugging me on the head.
However, the question remains, if MVC isn't really a good fit for web applications, what is?
It all depends on your coding style. Here's the secret: It is impossible to write classical MVC in PHP.
Any framework which claims you can is lying to you. The reality is that frameworks themselves cannot even implement MVC -- your code can. But that's not as good a marketing pitch, I guess.
To implement a classical MVC it would require for you to have persistent Models to begin with. Additionally, Model should inform View about the changes (observer pattern), which too is impossible in your vanilla PHP page (you can do something close to classical MVC, if you use sockets, but that's impractical for real website).
In web development you actually have 4 other MVC-inspired solutions:
Model2 MVC: View is requesting data from the Model and then deciding how to render it and which templates to use. Controller is responsible for changing the state of both View and Model.
MVVM: Controller is swapped out for a ViewModel, which is responsible for the translation between View's expectations and Models's logic. View requests data from controller, which translates the request so that Model can understand it.
Most often you would use this when you have no control over either views or the model layer.
MVP (what php frameworks call "MVC"): Presenter requests information from Model, collects it, modifies it, and passes it to the passive View.
To explore this pattern, I would recommend for you begin with this publication. It will explain it in detail.
HMVC (or PAC): differs from Model2 with ability of a controller to execute sub-controllers. Each with own triad of M, V and C. You gain modularity and maintainability, but pay with some hit in performance.
Anyway. The bottom line is: you haven't really used MVC.
But if you are sick of all the MVC-like structures, you can look into:
event driven architectures
n-Tier architecture
And then there is always the DCI paradigm, but it has some issues when applied to PHP (you cannot cast to a class in PHP .. not without ugly hacks).
From my experience, the benefits you get from an MVC architecture far outweighs its costs and apparent overhead when developing for the web.
For someone starting out with a complex MVC framework, it can be a little daunting to make the extra effort of separating the three layers, and getting a good feel as to what belongs where (some things are obvious, others can be quite border-line and tend to be good topics of discussion). I think this cost pays for itself in the long run, especially if you're expecting your application to grow or to be maintained over a reasonable period of time.
I've had situations where the cost of creating a new API to allow other clients to connect to an existing web application was extremely low, due to good separation of the layers: the business logic wasn't at all connected to the presentation, so it was cake.
In the current MVC framework eco-system I believe your mileage may vary greatly, since the principles are common, but there are alot of differences between, for instance, Zend, Django, RoR and SpringMVC.
If there are truly other good alternatives to this paradigm out there... I'm quite interested in the answers!
Sorry for the slight wall of text!
I think it would depend on what you're trying to do, personally. Magenta uses MVC pretty successfully, and it makes it fairly easy to add new functionality or modify existing.
Of course if you're trying to make something fairly simple, going with an MVC architecture could be overkill.
It's all preference. I have worked with old structures like XTemplates and Smarty and have now moved on to Codeigniter and Kohona. I like them very much and they work very well for everything I do on the web. For phone applications I can set up controllers for the functions that are needed to do it's data pulls as well. Working both in the Linux world and Windows World, for building ASP.NET Web Sites I don't see other way of building websites beside using MVC. Web Applications Projects in Visual Studio are still used but I prefer not to anymore. MVC Projects via Visual Studio is so easy to use and set up. You can right click on your controller methods and create views automatically. In every structure there is a good and bad but it's up to the developer to use whatever meets their needs.
I've started from scratch a new application using TDD and PHPUnit. It is going to be a MVC application. I've started my tests from the Model. That was fun and i didn't have too much problems.
Now I want to create my views/models. But the question is: How do I test my controllers? What about views? My controller will use my tested models and my future views.
Thanks.
There are three broad categories of testing for each of the layer in the MVC. The unit tests for models, functional tests for the controllers and the UI testing for the views.
Unit tests are the easiest to write. They are cheap in terms of time and do not require too many dependencies to be stubbed/mocked.
Functional tests on the other hand are a bit expensive compared to an unit test. In a given scenario, if you had covered enough in your application for the models using unit test, you can relax a bit in the functional testing part. However, you should still be having a good code coverage - 100% to be ideal for your controller methods as well.
The last is the UI testing which is the costliest of all tests. You can probably use Selenium for browser based testing and try to automate it with your language. You may have to have a RC sever running in the background to achieve this. But trust me, if you cover the first two parts - unit and functional, this can be made optional if not no.
And it is advised to have a CI - Continious Integration setup with a code coverage utility that gives a trending on the % of code covered through tests.
When you are running the tests , you should be using only the class under test. Other objects should be replaced with mocks or other fake structures.
You do this, because ( for example ) when you write a test for controllers action , you will have provide some values for said action, and then check if the correct data is passed to the view and models.
This is one of the reasons why you should avoid use of global state ( in form of static calls or global variables ) in your code.
Some links you might find useful
The Clean Code Talks - Unit Testing
The Clean Code Talks - Global State and Singletons
The Clean Code Talks - Don't Look For Things!
As a PHP/Web Developer, I'm a huge fan of MVC (Model-View-Controller). I love building an app on a solid foundation which definitely separates business logic, presentation logic, and flow of control.
However, I do a lot of work as well on server-side-only apps, which merely process data and log the process and any relevant results (such as import scripts, data migration scripts, web services, TCP socket servers, etc). There is no need for a big fancy MVC framework in these cases.
I realize that MVC can still be applied here, but it seems like overkill. Besides a raw procedural approach or a random mash-up of class objects, are there any specific Architectural Design Patterns out there especially suited to data-processing, run-once, and server daemon type applications?
If I understand correctly, the applications you're talking about don't have a user interface beyond the shell command line. If that's the case, you can still use MVC at the software architecture level - your View will simply be trivial. Your Controller will similarly be trivial, since there are very few actions to propagate between the Model and the View.
Of course, with a trivial View and Controller it might as well not be any pattern at all. I don't see an issue with that (at the level you're talking about). The key is to take an interface-based approach (much as you would with MVC) and this will tend to give a better design in the end; one which may easily be adapted to a different user interface or means of invocation if required in the future.
I guess you need to start by asking yourself what's the problem you want to solve (with these patterns you're looking for)
Once you know this, you might find something useful here:
http://martinfowler.com/eaaCatalog/
Since it is data processing related, I assume that you have some kind of data store, you can look at Repository and DTO (Data Transfer Object) architectural patterns.
More generically, some of the design patterns in GoF catalogue will also suit you such as Singleton for run-once, Facade for abstracting the processing logic, Strategy for different processing logic, State Machine maybe for the daemon