A Quick Hack to Writing Testable Code

Write Testable Code

I’ll be the first to admit that I am fairly inexperienced in the practical application of unit testing, or any kind of automated testing. That’s not to say I don’t understand what these things are. I was first exposed to the concept of unit tests back in 2008 and automated browser testing in around 2012. I know the theory of how they work and what the benefits are. It’s just that I’ve never been in a situation where I had the time to learn how to implement these things, so I’ve never really been able to. It was the classic “running alongside your bike” scenario.

That being said, there is something that a very skilled developer I used to work with said to me back in 2012, which I’ve implemented ever since, that I only realised today not only applied to writing better code, but also to writing testable code:

“Every function, or class method, should only do one thing”

Shaine Gordon, CTO at Realm Digital

Let me explain that by means of an example.

Let’s say you need to write a string parser. The parser needs to take a string, convert it to lower case, strip out specific punctuation (full stop, comma and space) and return the string with the first character as upper case.

In PHP, that could look something like this:

function my_string_parser( $string ) {
	$string = strtolower( $string );
	$string = str_replace( array( ' ', '.', ',' ), '', $string );
	$string = ucfirst( $string );

	return $string;
}

Now, the perceptive amongst you might notice the bug. If you don’t see it right away, that’s OK, because that’s the point of this article.

So lets say I now decide to write a unit test to test this function (we’re not digging into TDD just yet). With PHPUnit installed, I might write a test class method that looks something like this:

function test_my_string_parser() {
	$string        = 'My test, string.';
	$parsed_string = my_string_parser( $string );
	$this->assertEquals( 'Myteststring', $parsed_string );
}

Based on the code above, this test would fail. My problem is, at what point in manipulating the string, does my function fail?

However, if I refactor my initial code a little:

function my_string_parser( $string ) {
	$string = my_string_to_lower( $string );
	$string = my_string_remove_punctuation( $string );
	$string = my_string_ucfirst( $string );

	return $string;
}

function my_string_to_lower( $string ) {
	$string = strtolower( $string );

	return $string;
}

function my_string_remove_punctuation( $string ) {
	$string = str_replace( array( ' ', '.', ',' ), '', $string );

	return $string;
}

function my_string_ucfirst( $string ) {
	$string = ucfirst( $string );

	return $string;
}

Granted, it’s a lot more code, but now I can write individual tests for each smaller ‘my_string’ function, and the failing test(s) will point to where the bugs are. I can then fix those bugs, function by function, until my individual tests pass, and then the ‘test_my_string_parser’ test will also pass.

I’m pretty sure this isn’t rocket science, or anything new, but if you’re starting your unit journey, it’s a good place to start.

Unit Tests for your WordPress plugin using WP CLI and PHPUnit

Unit Tests for your WordPress plugin using WP CLI and PHPUnit

Often when I write a blog post, part of the reason I write it is to document things that I tend to forget. This is one of those times.

Requirements:

PHPUnit: At the time of this writing, WordPress only supports the latest stable 7.x version of PHPUnit, and recommends installing it globally.

wget https://phar.phpunit.de/phpunit-7.5.9.phar
chmod +x phpunit-7.5.9.phar
sudo mv phpunit-7.5.9.phar /usr/local/bin/phpunit
phpunit --version

WP-CLI: If you’re developing on WordPress and you’re not using WP-CLI, you are missing out on some amazing tools.

curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
chmod +x wp-cli.phar 
sudo mv wp-cli.phar /usr/local/bin/wp

Set up

Using WP-CLI, you can quickly scaffold some unit tests files for your WordPress plugin.

Inside the WordPress directory of the site you’re building/testing on, run the following command to scaffold the unit test code for your plugin, located at /wp-content/plugins/plugin-name

wp scaffold plugin-tests plugin-name

If you don’t already have a plugin directory, because you’re building the plugin from scratch, you can just run the following command to scaffold some initial plugin code, which includes the unit test code.

wp scaffold plugin-name

Either way, you’ll end up with a ‘tests’ directory inside your plugin directory, which includes the test bootstrap file, and a sample test file.

The next step is to set up the ‘wordpress_test’ database, which the test suite will use when creating mock posts etc. Switch to the plugin directory and run the following comand, replacing ‘root’ and ‘password’ with your local MySQL servers username and password.

bash bin/install-wp-tests.sh wordpress_test root password localhost latest

And you’re done, go forth and write some unit tests for your WordPress plugin.

Travelling the web on the WordPress HTTP API

HTTP API

At WordCamp Europe 2019 in Berlin, I was accepted to present a workshop, which was on the WordPress HTTP API.

Unfortunately we had some WiFi issues, and not all the attendees were able to complete the workshop. Also, there were some folks who were not able to attend at all, due to the workshop being booked out!

This post attempts to solve both problems, by including a link to the GitHub repository, the slides, and 3 videos of me live coding (more or less) the workshop content.

Fair warning, this is the first time I’ve done something like this, so bear with me.

Hopefully using the slides, the GitHub repository and the videos, you’ll be able to complete the workshop and learn a little more about working with web based APIs and WordPress.

You can find the slides here

You can find the GitHub repository here

Below are the videos I’ve recorded of me completing the workshop content.

Part 1
Part 2
Part 3

Some news updates.

News Update

I don’t think I completed my year end review for 2018 or wrote a resolution post for 2019. However a bunch of things have happened so far this year, mostly in the past few months. As it’s almost exactly halfway through the year, I thought it might be cool to share them.

As one door closes…

Towards the end of last year, my wife and I decided to sell the family business we’d been running together since 2011. It was a hard decision to make, but as our boys were growing older we found ourselves less and less inclined to want to work on weekends, which the business required. I’m happy to say that we successfully sold the business earlier this year.

Castos and accelerator funds

Back in December of 2016 Craig Hewitt contacted me looking for someone to help him extend the podcasting plugin he had recently acquired. I’ve been working with Craig ever since, and so I was very pleased to find out the Castos, the company built to support and enhance the plugin was accepted into the TinySeed Accelerator. Which brings me to…

…another opens.

The investment Castos has received has allowed Craig to offer me a full time role in the company. I’ve been the designated lead developer of the project since pretty much just after we launched what was then called Seriously Simple Hosting back in 2017, but now it’s an official position, with all the benefits and responsibilities that go along with it. I couldn’t be happier, because I think we have a great product, and I now get to work with a small group of amazing people, helping our clients and plugin users from all over the world, every day, so I’m looking forward to what the next year holds for us all.

That’s not to say that I won’t be able to continue to work with my clients at Codeable. I’m lucky to have made great relationships with a group of repeat clients and I will continue to serve them in whatever capacity they require.

This position will also give me some security and time to to put into other areas, including expanding my contributions to WordPress, and getting back on the ‘building my own products’ train. Watch this space.

Castos goes to WCEU

Part of the Castos/TinySeed news was that I was able to travel to Berlin and (finally) meet both Craig and fellow Castos developers Danillo and Stefan. It was the first of what looks to become a regular, yearly team retreat. Working along side people remotely in a start up environment is a fun-filled experience, but there’s nothing like actually meeting in person. We know also know who the tallest member of team Castos is, and no, it’s not me! I’m hoping that the next team retreat will include the other members of our team.

The team retreat was timed to coincide with WordCamp Europe, which meant I was able to attend this year again. My favourite thing about WCEU is meeting people in real life, especially those I’ve only ever meet online. It’s always great to see my community team friends, but this year I was able to connect with, and meet in person, an entire years worth of ‘online only’ folks.

Highlight’s of WCEU 2019 was being able to secure a 15 minute chat with Matt Mullenweg, the Codeable experts dinner and group photo, and Monique Dubbelman bringing me some amazing and authentically Dutch stroopwafels, which I now have to find a supplier for locally.

Professionally, 2019 is shaping up to be a pretty awesome year. I have some plans of things I want to accomplish for the rest of this year and the next, but I’m also acutely aware that one cannot succeed at everything. Win or loose, I’m exceptionally excited to be able to at least try.

Thoughts on Unit Testing

I’ve never been someone who understood the value of unit testing. During my programming studies, when I learned new languages like PHP or JavaScript, unit testing was never a topic that came up. The byproduct of a non university, tertiary education I guess?

The first time I discovered unit tests was when I was working with a Python developer in the late 2000s. I can’t remember how it came about, but it was through him that I learned about the concept, how you write the tests first and then write the code to pass the tests. I still didn’t understand the value, so I did some cursory research but generally moved on.

Over the course of the next few years I often saw articles or discussions on unit testing, but the idea of unit testing my code was not something that was a part of any developer position I’ve held in the last 15 years, so I never learned how to, or why I should, write unit tests.

In 2015, when I started developing for WordPress, unit testing came up again, as I looked into contributing to WordPress core. In my search to ramp up my WordPress development knowledge I discovered Know the Code, and one of Tonya’s courses was about unit tests. At around the same time I started using Laravel, which meant eventually finding Laracasts, which also included a course on Unit Testing. Through these places I eventually discovered Grumpy Learning by Chris Hartjes, who has 3 books dedicated to unit testing PHP code.

I’ve since come to appreciate the value and need for unit tests and have committed myself to writing unit tests for all new functionality I code from 2019 onward. At first it was daunting, but today something finally clicked.

It started with a new feature. I needed to verify the extension of a media file path, ignore any query strings that might be appended to that path, and return the correct base name to the actual file. Contrary to my unit testing resolution, I wrote the actual code first, but realised that when it came time to test it, I’d need to do a whole bunch of other work to deploy the code and test it manually, the old fashioned way. I realised this was a great chance to write some unit tests.

During the writing of some simple assertEquals() assertions, I soon realised that my initial understanding of the problem was flawed. By writing a few additional tests for cases I had not originally thought of, I could more thoroughly test my solution and improve it to handle these new situations.

In a round about way, I ended up eventually writing the correct unit tests I should have written in the first place, rewriting my code from scratch to solve these tests, and ending up with a much better overall solution.

The tests themselves and the code solution was trivial. What was important was the realisation that, had I started writing the tests first, my mind would have provided additional cases I might not have thought of. I would therefore be preparing myself to not only come up with a better solution, but with a much faster way to test and confirm it.

Through all this I’m getting a good grasp of which types of problems lend themselves to unit testing and which do not. I also realise that if I’m going to write more unit tests I need to allow myself more time up front to plan and execute proper unit testing. I’m still learning, so things like mocks and stubs are still far off concepts I’m aware of but will need to master. I am however excited to see how this improves as I practice, and how it improves my development output as a whole.

Monitor MySQL command line imports and exports on Ubuntu using Pipe Viewer

If you’ve been working with PHP/MySQL based websites for any amount of time, you’ve probably heard about the MySQL command line tools for importing and exporting your database.

The syntax is quite simple, for exports you run

mysqldump -udbuser -p dbname > dbfile.sql

which exports the database to a file on the local machine. For imports you run

mysql -udbuser -p dbname < dbfile.sql

which imports the contents of the local file (dbfile.sql) into the empty database.

This is usually the quickest way to export a database from one location to import it into another.

One problem I’ve experienced from time to time is exporting and importing large databases. By default the tools don’t output any progress indicator (or anything at all really), and using the -v (verbose) switch outputs every single MySQL command being run from the import file, which is like watching the code in the Matrix.

via GIPHY

Fortunately, there is a way you can run imports and exports and show a progress bar, with Pipe Viewer.

Pipe Viewer is a terminal-based tool for monitoring the progress of data through a pipeline. The Pipe Viewer homepage has all the install commands for the various operating systems, and Ubuntu has an official package for it, so you can install it through apt.

sudo apt-get install pv

Once pipe viewer is installed, you merely need to make two small changes to you import and export commands.

pv dbfile.sql | mysql -udbuser -p dbname
mysqldump -udbuser -p dbname | pv -W > dbfile.sql

And viola! You will be presented with a progress monitor that shows file size imported, time taken, percentage progress. Much better than staring at a blank screen.

Setting up Trusted SSL Certificates for Local Development, Using mkcert on Ubuntu 18.04 with Apache.

Computer Surgery

One of the many little annoyances that I encounter while working on client sites, is when the client has a valid SSL certificate installed on their server, but the HTTPS redirection happens in code instead of at the server level.

This means that even if I export the database with the site urls replaced to match my local environment, or run a search or replace on the local database, the code execution will still try to redirect to the secure version of the domain, meaning I have to first find out where that redirection is taking place, and remove it.

Often it’s done inside the site config, which is pretty quick to comment out, but other times it’s done via a plugin which is harder to find. In the long run it would be infinitely quicker and easier to just have a trusted SSL certifcate installed for the local site. My previous attempts at this meant installing a self signed certificate, but this means it’s not ‘trusted’ by the browser, and you either have to configure your browser to trust the certificate, or get an annoying warning about the site’s certificate not being trusted or secure enough every time you browse to the local site.

Thankfully, after asking around, I was pointed to mkcert “a simple zero-config tool to make locally trusted development certificates with any names you’d like.” It creates a local certificate authority, installs the authority into your local and browser trust stores. It also includes a tool to make local, trusted certificates for any local domain name. All that I have to do is set those certificates up for each local domain.

Installing mkcert is pretty straightforward and the project readme contains instructions for the various operating systems.

Regular Apache Virtual Hosts for local development

Because I use Ubuntu as my OS and Apache as my local webserver, whenever I add a new client site, it’s usually a 4 step process:

I start by creating a new Apache VirtualHost config file, copied from an existing one, and change some site related values

cd /etc/apache2/sites-available/
sudo cp 000-default.conf localsite.conf
sudo nano localsite.conf

The values I change are ServerName, ServerAdmin, DocumentRoot and Directory values. I usually also set site specific log files

<VirtualHost *:80>
        ServerName localsite.test
        ServerAdmin webmaster@localsite.test
        DocumentRoot /home/jonathan/development/websites/localsite
        <Directory "/home/jonathan/development/websites/localsite">
            #Require local
            Order allow,deny
            Allow from all
            AllowOverride all
            # New directive needed in Apache 2.4.3: 
            Require all granted
        </Directory>
        ErrorLog ${APACHE_LOG_DIR}/localsite-error.log
        CustomLog ${APACHE_LOG_DIR}/localsite-access.log combined
</VirtualHost>

Once the config is saved, I enable the new site, and restart Apache

sudo a2ensite localsite.conf
sudo service apache2 restart

The last step is to let my local machine know what IP address to resolve the VirtualHost ServerName value to, in this case localsite.test

sudo nano /etc/hosts
127.0.0.1   localsite.test

Once this is all done, I can browse to http://localhost.test and it will serve the files in the /home/jonathan/development/websites/localsite directory.

Note, if you get a ‘permission denied error’ doing this, the quick way to fix this is to change the user and group that Apache runs as, to your local user.

sudo nano /etc/apache2/apache2.conf
# These need to be set in /etc/apache2/envvars
#User ${APACHE_RUN_USER}
#Group ${APACHE_RUN_GROUP}
User jonathan
Group jonathan

Save that file, restart Apache, and you’ll be good to go.

Adding a SSL layer to a local site

I wasnt sure if the set up of a local, trusted certificate would be any different, and I was pleased to find out this was indeed the case.

Creating the new local Certificate Authority

Once mkcert is installed, the first thing I needed was to create and install the new local certificate authority. Fortunately this only needs to be done once.

mkcert -install

Once you’ve installed the CA, you can issue site certificates against it. I like to place all my site certificates on one place like ssl-certs

mkdir ssl-certs
cd ssl-certs

Then it’s time to create the certificates.

mkcert localsite.test

This creates a localsite.test.pem certificate and a localsite.test-key.pem key, which is used in the Apache SSL config for the site.

Side note, I’ve started using .test for my local domains, because Chrome doesn’t seem to like my use of .local domains until I tell it to. Earlier this year I discovered this is because it’s reserved for link-local host names that can be resolved via the Multicast DNS name resolution protocol. So I switched to .test. Thanks to Andrey Savchenko for pointing this out to me.

Setting up the certs for a local site

First step was to enable the SSL module for Apache. This also needs to only be done once.

sudo a2enmod ssl

Next, I needed to create an SSL version of the local site virtual host config. I started by copying the existing default-ssl.conf and making my changes

cd /etc/apache2/sites-available/
sudo cp default-ssl.conf localsite-ssl.conf
sudo nano localsite-ssl.conf

It’s actually pretty similar to a standard VirtualHost config, except for the checking if the SSL module is installed, the VirtualHost domain and port, and stuff from SSLEngine down. As you can see the certificate and key are specified in the SSLCertificateFile and SSLCertificateKeyFile entries respectively

<IfModule mod_ssl.c>
	<VirtualHost _default_:443>
                ServerName localsite.test
		ServerAdmin webmaster@localsite.test

		DocumentRoot /home/jonathan/development/websites/localsite

		<Directory "/home/jonathan/development/websites/localsite">
            #Require local
            Order allow,deny
            Allow from all
            AllowOverride all
            # New directive needed in Apache 2.4.3: 
            Require all granted
        </Directory>

		ErrorLog ${APACHE_LOG_DIR}/localsite-error.log
		CustomLog ${APACHE_LOG_DIR}/localsite-access.log combined

		SSLEngine on

		SSLCertificateFile	/home/jonathan/ssl-certs/localsite.test.pem
		SSLCertificateKeyFile /home/jonathan/ssl-certs/localsite.test-key.pem

		<FilesMatch "\.(cgi|shtml|phtml|php)$">
				SSLOptions +StdEnvVars
		</FilesMatch>
		<Directory /usr/lib/cgi-bin>
				SSLOptions +StdEnvVars
		</Directory>

	</VirtualHost>
</IfModule>

Once the SSL config is created, I enable it.

sudo a2ensite localsite-ssl.conf

I can then restart Apache, and the SSL secured version of the local site is enabled.

This is something I’ve wanted to get set up for the longest time, so a massive thanks to Filippo Valsorda for creating mkcert.

11 steps to getting the most out of your freelance developers

Working with Freelance Developers

A handy guide for clients working with freelance developers so nobody gets hurt…

Working with freelancers can be, for some, the equivalent of playing with a loaded gun. It can work out, but there are times when it can really affect your business and your life. As a client, you need a handy guide to working with freelance developers to ensure that every person working on the project comes out on top.

Step 01: A clear view

You need to understand your product and its requirements very intricately before you move into a relationship with a freelance developer. You can’t brief something in to someone until you know it really well. This also ensures you have a very clear vision of the final product and will inform all your engagements with your freelancer.

Step 02: Have a basic understanding

You will need some basic knowledge of web and development before you embark on this adventure. Yes, you are hiring a professional to take on your project so theoretically you shouldn’t need to know a thing. The fact is, if you have a modicum of understanding then you will have more realistic ideas around time frames, deliverables and project potential (and the magic Foo of your developer).

Step 03: Budget is everything

Don’t expect your freelance developer to be happy to cut their rates to suit your budget.The work they do is complex and specialised. Instead, be prepared to cut your requirements to fit your budget. That way you are assured of quality work from a reliable developer.

Step 04: Clarify your requirements

This is an extension of Step 01. Why? Because this is the most important step of all – it will cost you money and time if your requirements are vague so spend time on clarifying them. It’s worth it.

Step 05: Develop a clear timeframe

Work closely with your freelance developer to break the project down into achievable phases,each with their own milestones and deliverables. This will ensure that both you and your freelance development team are on the same page and working towards the same goals. This way nobody can say that they didn’t know that X had to be done by Y date…And this includes you providing your development team with the information and materials they need to achieve these goals.

Step 06: Create communication channels

From Slack to Asana to Evernote to Skype – there are plenty of communication and collaboration tools available to help you streamline communication with your freelance developers. Many of these offer timeline and deadline management tools as well, making it really easy for you to track timing and status.

Step 07: Don’t hover

The headline says it all. Science has shown that for every interruption, it takes a person at least 20 minutes to get their concentration back. Every time you interrupt,you slow your project down.

Step 08: Test

Every step, every aspect, every phase – test. Test assumptions, capabilities, developer promises and results. This will ensure that the final product has had most of the kinks ironed out iteratively rather than a messy tangle to unwrap at the end.

Step 09: Feedback

There is bad feedback, there is good feedback and there is great feedback. Learn how to do the last two types of feedback really well. Good feedback is defined as giving the person the information they need to make changes, fix problems, address issues and overcome obstacles with precision. Vague and wishy-washy comments like, ‘Yeah, it doesn’t feel right’ are not helpful. Nor are nasty and antagonistic ones. Nobody puts passion into a project for someone they don’t like.

Step 10: Everything is in writing

From the onset of your project to the phases and timelines to the final deliverables ensure that your project is clearly documented and that all parties have read and signed every document. You do not want to end up at the end of a messy conversation or project with someone saying that something was never clarified.Assume the best, prepare for the worst.

Step 11: Manage expectations

Your developer won’t always be around to leap to your requests or requirements. This is very normal and you may not be their only client. Be patient and trust that they will get back to you and respect your urgency.