Maximising Code Quality in Magento
E-commerce websites are one of the less fault tolerant online systems. The ability for customers to transact as part of a smooth and intuitive process directly affects our clients’ bottom-line so any problems in that process begin to affect confidence very quickly. At StudioForty9, we’re always on the look out for new methods and tools to help improve our code quality, so that our clients can sleep easily.
This blog aims to help potential and existing clients understand how we test their online stores. It will also be useful for developers looking to put some bits of icing on the cake of the Magento learning curve.
There are three aspects to code quality that I will write about along with some small examples of how StudioForty9 have implemented aspects of them to improve the confidence in the systems we build. These are: External Quality, Internal Quality and Tracking Quality Over Time.
External Quality is all about what the customer sees and his/her experience on the client’s website. Is all of the functionality working as specified? Is the customer able to achieve their goals easily?
A common way to approach ensuring that External Quality exists is to generate lots and lots of automated browser tests. Using tools, such as Selenium (http://docs.seleniumhq.org/) that take instructions and perform them in a real browser, we can check that all of the core functionality is working as expected before and after every change to the system.
However, writing all those instructions takes time, and even requires a new language that Selenium understands to be learned. That’s not a problem where there is a dedicated QA or Testing department, but that can also introduce issues of communication between client, developer and tester.
Hence a couple of tools that have really taken off in the past 12-18 months are Behat (http://behat.org/) and Mink (http://mink.behat.org/). Behat is a tool for BDD (Behaviour Driven Development) that allows you to write human-readable stories that describe the behaviour of your application. Mink is the tool that sits between these user stories and the browser automation tool (e.g., Selenium). These are, of course, PHP tools (based off Ruby’s Cucumber project), so where better to use them than with Magento?
Here’s a very simple example Scenario:
Scenario: Add Product to Cart
- Given I am on the homepage
- When I click on the “Designer Sunglasses” link
- Then I should be on “/designer-sunglasses.html”
- When I press the “Add to Cart” button
- Then I should be on “/checkout/cart”
- And the “Designer Sunglasses” product should be in my cart
This is a very simple user journey. However, the beauty of it is that it is expressed in very simple English which we can turn this into a test that actually runs in a browser to see if the system functions as expected. Not only do we know if it works today, but there is no future overhead for running it as often as you like, so we know that it continues to work from this point forward.
So the first part of developing a new feature for a site, once the specifications and functionality have been talked through with the client and some wireframes have been drawn up, is turning these “artefacts” into Features and Scenarios that we can then use for automated testing. And then we test. And it all fails – and then we begin to write our code* (disclaimer – please see section PHPUnit below) – and we know we’re done when all of the tests pass.
Another great thing is that it simplifies cross-browser testing. The same scenarios can be used to test in Firefox, Chrome, IE, Safari, etc. with just a simple configuration change.
In StudioForty9 we’ve rolled out this methodology to many of our Magento projects so that changes only get pushed to to staging or production environments when all of the automated tests are “green”.
If External Quality is about what the customer or client sees, Internal Code Quality is the developer’s birds eye view. It’s about how well structured the code is, how easy is it to change and maintain over time, etc. Of course, the Internal Quality is bound to affect the External Quality. If the code is a mess, chances are there’s some bugs in there, and when there are, they are going to be even harder to track down.
The de facto standard in PHP for building high quality code is practicing TDD (Test Driven Development) using PHPUnit (http://phpunit.de/). This is a much more precise and faster form of automated testing that can ensure that the logic of the code written acts as it is supposed to. However, when faced with a huge system like Magento where a lot of client requests can be small user interactions, it can be hard to know where to start with PHPUnit – it’s a far cry from the Bank Account examples that are used in books and examples on the subject.
Fortunately, a module exists to smoothen out the apparently steep learning curve. EcomDev’s PHPUnit (https://github.com/EcomDev/EcomDev_PHPUnit) module comes with lots of documentation to explain how to unit test the various parts of a custom Magento module. In this way, a developer can start off by unit testing their configuration (/etc/config.xml) and Model classes, where often the most important bugs are found, while using Selenium for testing user interaction. Later on, once the developer is comfortable with using PHPUnit with Magento, they can move on to testing their Blocks and Controllers for page rendering and user interaction (to a certain extent).
On top of PHPUnit, there are a number of other static analysis tools (PHPCPD, PHP_CodeSniffer, PHPDCD, PDepend, PHP Mess Detector, PHP Documentor, PHP Lines of Code, PHP Code Browser) for PHP that will give feedback to the developer as to the quality of the code.
Tracking Quality Over Time
We can pull these tools for testing both the internal and external quality of our code using a Continuous Integration Server. Popular examples are Jenkins (http://jenkins-ci.org/) and Travis (https://travis-ci.org/). These integrate with our Version Control system, (either Mercurial (http://mercurial.selenic.com/) or Git (http://git-scm.com/) so that any time a new piece of code is committed to the repository, the suite of tests is run to ensure that nothing has inadvertently broken and that the client’s specifications are being met. Having these tests run after every code change means we can track the quality of code over time, using graphs and statistics to make sure that the Code Quality metrics are kept to a consistently high standard.
This is obviously a very brief blog post on a big area – whole books have been written on this subject. But it’s the kind of web development process that is increasingly essential in big eCommerce projects where new code is going live on a daily basis and downtime and bugs means immediate lost revenue. And it’s the kind of development process that I believe will become a basic expectation of clients in years to come, in the same way as we have certain expectations of civil engineers that their bridges won’t fall down.