Last June I had the pleasure to present at SMX Advanced about one of my favorite topics: improving the collaboration between SEOs and developers.
How often do you learn about a noindex meta robots tag in the wrong pages released to production and causing massive SEO traffic drop?
Let’s learn how we can prevent this error and similar ones from happening in the first place.
Automated testing in professional development
Modern professional developers need to add new features or fix bugs at a fast pace and often rely on automated testing to keep their code quality high.
During my session, I mentioned this as a perfect place to catch some SEO errors early, before their damage is too expensive.
In this article, we are going to explore this concept in detail, review some practical examples and outline the responsibilities of the developer and the SEO.
The anatomy of the front end of a modern web application
The front-end of modern web applications is generally built in a modular way using controllers, views, and components.
Controllers route page requests to the correct view of the app and the views are what you see when the page loads.
The views are further broken down into components. For example, in a search page, the grid of search results could be powered by one component.
These components can be rendered on the server-side, on the client-side or on both sides as it is the case of hybrid rendering solutions.
It is important to understand these concepts because not every app controller, view or component requires SEO input or automated tests.
One way to tell is to ask if the component’s functionality should be visible or not to search engine crawlers.
For example, all components or actions behind a login form are not in the scope of SEO because search engine crawlers can’t see them.
The different types of automated tests
Automated testing is a broad topic, but when it comes to SEO concerns, there are two main types of automated tests we need to learn about: unit tests and end-to-end tests.
Developers generally write unit tests to perform individual component and method level checks. The idea is to verify each part of the application works as expected separately and in isolation.
However, while the individual parts can operate correctly, they could fail when put to work together. That is where integration tests (a.k.a. end-to-end tests) come into place. They test that the components can work together too.
We should write both types of tests to check for SEO issues during development.
Let’s review some practical examples.
Writing SEO unit tests
In preparation for my presentation, I coded an AngularJS app that monitors Google Trends topics. I focused on trying to optimize it for basic SEO best practices.
In Angular, we can use Jasmine to write unit tests. Let’s review what unit tests look like and what we can do with them.
As an example, let’s look at the Category Topics component in our app, which is responsible for listing the Google Trends topics for a selected category.
We added these unit tests to check for basic SEO tags.
The tests above make sure the component sets proper canonical URLs, page titles and meta descriptions.
You could easily extend this list to include other meta tags like meta robots and hreflang tags.
After you write tests like these, you generally need to execute them after you update the app.
Here is how you run them using Jasmine. In Angular, you type the command: ng test
Here is what the output looks like.
As developers add new features to the website or app and then run the tests, they can get immediate feedback when they forget to add important SEO tags or introduce incorrect ones.
Part of your ongoing work as an SEO is to make sure new relevant components are covered by unit tests.
Writing SEO integration tests
Next, let’s review some of the integration tests that I coded for our app so you can see what they look like.
In Angular, we can use Protractor to run end to end tests.
You might be wondering why we need two different tools to run automated tests?
End-to-end tests run exclusively on a web browser by automating the browser so it performs the scripted actions we specify. This is very different from unit testing where we could run just the specific back end/front end code that we are testing.
If we look at our example app’s category topics page, you can see we added end-to-end tests to check for prerendering issues.
One simple check we added was to make sure the key meta tags like title and meta description didn’t come back null after rendering. Another test would be to check the server-side tags and client-side rendered tags are not different as it could cause cloaking issues.
Here is how you run them using Protractor. In Angular, you type the command: ng e2e
I didn’t cover this topic during my talk, but it is worth mention it. Most development teams that write automated tests, also implement a technique called continuous integration.
Continuous integration allows developers to push their code changes to a code repository and have each commit trigger a suite of automated tests. If the tests pass, the code is packaged for release and deployed automatically. But, if any of the tests fail, the packaging and release pipeline is halted.
Some continuous integration tools like CircleCi require you to add a simple test definitions file to your code repository, add the project to their service and they will run all automated tests, including the deployment pipeline, plus include reporting.
As an SEO practitioner, you could ask your dev team to give you access so you can review SEO tests that fail and review SEO test coverage to recommend any missing tests.
Catching SEO errors during development can save companies a lot of money and headache, and it is a shared responsibility between developers and technical SEOs.
I created these two tables to help define some of the different responsibilities for unit tests and integration tests.
Resources to learn more
I used Angular examples, but automated testing is an established discipline in professional development. You can find equivalent tools and processes in most frameworks.
Here are a few to investigate further for your specific dev stack.