Automation and Feature Toggles
A feature toggle is basically a switch (a toggle as it were) to turn on or off a particular feature. From an automation perspective there are [at least] two toggles that make sense. For a fun naming conventiom, lets call then ‘nuke’ and ‘neuter’.
A Nuke toggle would be one that would prevent something from happening, like say inserting a tracking pixel/script into a page. For anything other than production, these things just slow down the server. So things like google analytics, snap engage, etc. could all be disabled which will dramatically increase the speed of page loads for us. You would want a toggle per tracker rather than one monster one so that things can be selectively enabled if the situation warrants it (testing the integration with one of them for instance). Here is some Rails code to illustrate this from an earlier post.
<pre lang="ruby">
<script type="text/javascript">
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script>
<script type="text/javascript">
var pageTracker = _gat._getTracker("<%= omc_google_analytics_account %>");
pageTracker._setDomainName(".element34.ca")
pageTracker._initData();
pageTracker._trackPageview();
</script>
If I was to do this again, I would make it read from a config file rather than the environment so I could have more control over things.
A Neuter toggle is one that leaves things on the page, but disarms them. The example here would be a captcha on a registration page. You want the captcha to appear, but either be short circuited entirely or conditionally. Here is the complete short circuit
<pre lang="java"> @RequestMapping(value = "/captcha/ValidateCaptcha.html", method = RequestMethod.POST)
public String validateCaptcha(Model model, @RequestParam(required = false) String solution,
@RequestParam(required = false) String solutionId, HttpServletRequest request) {
if (null != solution && !("").equals(solution.trim())) {
if (CAPTCHA_STUB) {
model.addAttribute("isValid", "Captcha disabled");
} else {
boolean isValid = validate(solutionId, solution);
if (isValid) {
model.addAttribute("isValid", "Your captcha has been successfully updated.");
}
else {
model.addAttribute("isValid", "try again plz....");
}
}
}
return "captcha.validate";
}
And the conditional one
<pre lang="java"> @RequestMapping(value = "/captcha/ValidateCaptcha.html", method = RequestMethod.POST)
public String validateCaptcha(Model model, @RequestParam(required = false) String solution,
@RequestParam(required = false) String solutionId, HttpServletRequest request) {
if (null != solution && !("").equals(solution.trim())) {
if (CAPTCHA_STUB && ("4444").equals(solution.trim())) {
model.addAttribute("isValid", "Captcha disabled");
} else {
boolean isValid = validate(solutionId, solution);
if (isValid) {
model.addAttribute("isValid", "Your captcha has been successfully updated.");
}
else {
model.addAttribute("isValid", "try again plz....");
}
}
}
return "captcha.validate";
}
Note the inclusion of a message saying that the captcha is disabled. Learned that lesson the hard way… The advantage of the second method is you can do both automated checks on it (by providing 4444 as the captcha value) or manual tests by not using 4444.
Setting up feature toggles tends to greatly decrease the speed of your automation, which in theory you are doing so you get feedback quickly on your product.