{"id":322,"date":"2010-12-01T22:13:31","date_gmt":"2010-12-02T05:13:31","guid":{"rendered":"http:\/\/blog.monnet-usa.com\/?p=322"},"modified":"2010-12-13T20:22:01","modified_gmt":"2010-12-14T03:22:01","slug":"ab-test-your-ruby-camping-web-app-using-abingo-part-1","status":"publish","type":"post","link":"https:\/\/blog.monnet-usa.com\/?p=322","title":{"rendered":"A\/B Test Your Ruby Camping Web App Using ABingo (Part 1)"},"content":{"rendered":"<style>\n\t\t\t\t\t\th3 {\ttext-decoration: underline; }<\/p>\n<p>\t\t\t\t\t\th4\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfont-size: 1.1em;\n\t\t\t\t\t\t\tmargin:0 50px 0 15px;\n\t\t\t\t\t\t}<\/p>\n<p>\t\t\t\t\t\th5 \n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tmargin:0 50px 0 50px;\n\t\t\t\t\t\t}<\/p>\n<p>\t\t\t\t\t\t.download_panel\n\t\t\t\t\t\t{\n\t\t\t\t\t\tbackground-color: #EDD6AD; \n\t\t\t\t\t\tcolor: #555555; \n\t\t\t\t\t\tfont-weight:bold;\n\t\t\t\t\t\ttext-align:center;\n\t\t\t\t\t\tmargin:0 50px 0 50px;\n\t\t\t\t\t\tpadding:6px;\n\t\t\t\t\t\t}<\/p>\n<p>\t\t\t\t\t\t.details_table \n\t\t\t\t\t\t{border: 1px solid #f0f0f0;\n\t\t\t\t\t\tborder-spacing: 1px;\n\t\t\t\t\t\tbackground-color:white;\n\t\t\t\t\t\tmargin-left: 40px;\n\t\t\t\t\t\t}<\/p>\n<p>\t\t\t\t\t\t.details_table tr\n\t\t\t\t\t\t{\n\t\t\t\t\t\tvertical-align: top;\n\t\t\t\t\t\tborder-bottom: 1px solid LightGoldenRodYellow;\n\t\t\t\t\t\t}<\/p>\n<p>\t\t\t\t\t\t.details_table th\n\t\t\t\t\t\t{\n\t\t\t\t\t\tbackground-color:lightgray;\n\t\t\t\t\t\t}<\/p>\n<p>\t\t\t\t\t\t.details_table td\n\t\t\t\t\t\t{\n\t\t\t\t\t\tborder-bottom: 1px solid LightGoldenRodYellow;\n\t\t\t\t\t\t}<\/p>\n<p>\t\t\t\t\t\t.blog-msm-ad {\n\t\t\t\t\t\t\tbackground-color: #919191;\n\t\t\t\t\t\t\tborder-top: 6px solid #E2E2E2;\n\t\t\t\t\t\t\tcolor: white;\n\t\t\t\t\t\t\tdisplay: block;\n\t\t\t\t\t\t\theight: 40px;\n\t\t\t\t\t\t\tmargin-left: 12px;\n\t\t\t\t\t\t\tmargin-top: 20px;\n\t\t\t\t\t\t\tpadding: 10px;\n\t\t\t\t\t\t\twidth: 537px;\t\t\t\t\t\t\t\n\t\t\t\t\t\t}<\/p>\n<p>\t\t\t\t\t\t.blog-msm-ad1 {\n\t\t\t\t\t\t\tfloat: left;\n\t\t\t\t\t\t\twidth: 310px;\n\t\t\t\t\t\t}<\/p>\n<p>\t\t\t\t\t\t.blog-msm-ad2 {\n\t\t\t\t\t\t\tfloat: right;\n\t\t\t\t\t\t\twidth: 225px;\n\t\t\t\t\t\t}<\/p>\n<p>\t\t\t\t\t\t.blog-msm-ad a {\n\t\t\t\t\t\t\tcolor: #A0D1F1;\n\t\t\t\t\t\t\tfont-weight: bold;\n\t\t\t\t\t\t}<\/p>\n<\/style>\n<h3>Intro <\/h3>\n<p>Over the past few months, while listening to <a href='#tz'>TechZing<\/a>, a fantastic podcast for web startup entrepreneurs, the concept of <a href='#abwp'>A\/B Testing<\/a> keeps coming up as key technique to track and <b>measure conversion<\/b> of site <b>visitors<\/b> into potential or true <b>customers<\/b>. Performing A\/B testing implies:\n\t\t\t\t\t<\/p>\n<ol>\n<li>Selecting <b>content variations<\/b> or <b>use case variations<\/b> to test<\/li>\n<li>Identifying a couple <b>alternatives<\/b> for each test (a.k.a. experiments)\n<p>\t\t\t\t\t\t<i>Example of an experiment on the wording of a call to action button:<\/i><br \/>\n\t\t\t\t\t\t<img src='.\/wp-content\/media\/camping-abingo\/camping-abingo-abtests-call-to-action-button.png'  width=\"90%\" \/>\n\t\t\t\t\t\t<\/li>\n<li><b>Trigger<\/b> a test on a given page by <b>selecting an alternative<\/b> for a given user<\/li>\n<li><b>Track<\/b> any resulting <b>conversion for a given user<\/b> on a targetted page<\/li>\n<li>Measure the <b>participation<\/b> in our tests<\/li>\n<li>Measure the <b>conversion<\/b> in our tests<\/li>\n<\/ol>\n<div  class='download_panel'>Click <a href='#abcasrc'>here<\/a> if you want to skip straight to the <a href='#abcasrc'>ABingo Camping Plugin source code<\/a><\/div>\n<h3>A\/B Test Solutions<\/h3>\n<p>Google provides very basic A\/B Testing capabilities as part of the Google Analytics <a href=\"#abgg\">Website Optimizer<\/a>. The downsides of that approach are:<\/p>\n<ul>\n<li>The tests (experiments), their alternatives, and corresponding urls have to be defined on the Google site<\/li>\n<li>The resulting &#8220;test tracking Javascript snippets&#8221; have to be copy\/pasted inside your own site<\/li>\n<li>All the data remains locked in Google&#8217;s databases (although you can export it)<\/li>\n<\/ul>\n<p>If your web application is built on Ruby on Rails, you are in luck, as <a href=\"#pmz\">Patrick McKenzie<\/a> has created <a href=\"#abingo\">ABingo<\/a>, an excellent A\/B testing framework plugin. ABingo even includes a dashboard to view the test participations and conversions. <\/p>\n<p>Since I am a big fan of the lightweight Ruby <a href='#rc'>Camping Micro-Framework<\/a>, what I needed was an <a href='#tacaab'>ABingo Camping plugin<\/a>. Since none existed I emailed Patrick McKenzie to get his blessing and started to <a href='#abcasrc'>adapt<\/a> his plugin!<\/p>\n<h3 style=\"page-break-before:always;\">Starting With The End In Mind<\/h3>\n<h4>ABingo Test Application<\/h4>\n<p>To illustrate the usage of ABingo, we&#8217;ll use a simple tester representing a fictitious <b>SAAS Application<\/b>. From the <b>home<\/b> page we&#8217;ll be able to access the <b>landing<\/b> and corresponding <b>sign-up<\/b> pages that we want to <b>experiment with<\/b>.<br \/>\n\t\t\t\t\t\t\t<img src='.\/wp-content\/media\/camping-abingo\/camping-abingo-test-nav-flow.png'  width=\"80%\" \/><br \/>\n\t\t\t\t\t\t\tWe&#8217;ll also provide sign-in\/sign-out options and a  link to the <b>ABingo dashboard<\/b> if the signed in user is the administrator.\n\t\t\t\t\t<\/p>\n<h4>Objective: Increasing Our Sign-Ups<\/h4>\n<p>To increase our sign-ups we will be experimenting first with different <b>calls to action<\/b> in our sign-up button.<br \/>\n\t\t\t\t\tOur experiment named <b>call_to_action<\/b> will randomly vary the text of the button. We track the selected option and track the conversion on our sign-up page. After running our experiment for a while we will be able to see on the dashboard which option generated the most conversion!<\/p>\n<h4>The Conversion Funnel<\/h4>\n<p>The <b>path<\/b> taken by a group of customers from the various options (A\/B\/C) of the <b>landing<\/b> page to our <b>sign-up <\/b> page is called a <b>conversion funnel<\/b>:<br \/>\n\t\t\t\t\t<img src='.\/wp-content\/media\/camping-abingo\/camping-abingo-abtests-funnel.png'  width=\"90%\" \/>\n\t\t\t\t\t<\/p>\n<h3 style=\"page-break-before:always;\">High-Level Implementation Synopsis<\/h3>\n<p>Once ABingo is integrated in your application, tracking and measuring the conversion funnel will consist of 2 basic steps:<\/p>\n<h4>Selecting an alternative for a given experiment<\/h4>\n<p>In the <b>landing view<\/b> code we will invoke the ABingo <b>ab_test<\/b> API to choose an alternative for the <b>call_to_action<\/b> experiment based on an array of text options:<\/p>\n<pre class=\"brush: ruby\">\r\n\tdef landing\r\n\t\t# ...\r\n\r\n\t\tsignup_text = ab_test(\"call_to_action\", \r\n\t\t\t\t\t\t\t\t[ \t\"Sign-Up Now!\",\r\n\t\t\t\t\t\t\t\t\t\"Try It For Free Now!\",\r\n\t\t\t\t\t\t\t\t\t\"Start Your Free Trial Now!\",\r\n\t\t\t\t\t\t\t\t])\r\n\t\t\r\n\t\ta :href=>\"\/signup\" do\r\n\t\t\tdiv.signup_btn!  signup_text\r\n\t\tend\r\n\t\t\r\n\t\t# ...\r\n\tend\r\n\t\r\n<\/pre>\n<p>It&#8217;s that easy! And as a side note an experiment alternative can be a simple boolean, an array of arbitrary values, or even a hash of options.<\/p>\n<p><\/p>\n<h4>Tracking the conversion for our experiment<\/h4>\n<p>In the <b>SignUp<\/b> controller, before rendering the signup view we will invoke the <b>abingo!<\/b> API to indicate that a conversion just occurred on our <b>call_to_action<\/b> experiment:<\/p>\n<pre class=\"brush: ruby\">\r\n\tclass SignUp < R '\/signup'\r\n\t\tdef get\r\n\t\t\tbingo! \"call_to_action\"\r\n\t\t\t\r\n\t\t\trender :signup\r\n\t\tend\r\n\tend\r\n<\/pre>\n<h4>Fun With Experiments!<\/h4>\n<p>Now that you have seen how ridiculously simple it is to setup and track an experiment you'll want to try to run different types of experiments such as for example:<\/p>\n<ul>\n<li>different styles (size, color) for the sign-up button<\/li>\n<li>special offers<\/li>\n<li>different ways to present pricing options<\/li>\n<li>etc.<\/li>\n<\/ul>\n<p>Example of a landing page with a <b>special_promo<\/b> experiment:<br \/>\n\t\t\t\t\t\t<img src='.\/wp-content\/media\/camping-abingo\/camping-abingo-abtests-multiple-content-areas.png'  width=\"70%\" \/>\n\t\t\t\t\t<\/p>\n<h3>Reviewing A\/B Test Results With The ABingo Dashboard<\/h4>\n<p>The dashboard consists of a couple routes built using Camping controllers and views. Although we will walk through the setup of such a dashboard in our prototype app in a later article, here is a teaser screenshot:<\/p>\n<p>\t\t\t\t\t<img src='.\/wp-content\/media\/camping-abingo\/camping-abingo-dashboard.png' \/><\/p>\n<p>The conclusions we can draw from these experiments are:<\/p>\n<ol>\n<li>For the <b>special_promo<\/b> experiment, the \"true\" alternative results in the most conversions (%)<\/li>\n<li>For the <b>call_to_action<\/b> experiment, the \"Start Your Free Trial Now!\" alternative results in the most conversions (%)<\/li>\n<\/ol>\n<p>You can try the demo app yourself at: <a href=\"http:\/\/camping-abingo.heroku.com\/\">http:\/\/camping-abingo.heroku.com\/<\/a>.<\/p>\n<h3  style=\"page-break-before:always;\">So What? <\/h3>\n<ol>\n<li>A\/B testing is a key practice to improve usability as well as user conversion on a web application.<\/li>\n<li>Patrick McKenzie's <a href='#abpmk'>ABingo<\/a> is a powerful A\/B testing framework for Ruby apps.<\/li>\n<li><a href='#abpmk'>ABingo<\/a> makes it easy to define and execute experiments with multiple alternatives.<\/li>\n<\/ol>\n<p>This introduction to ABingo should have given you a feel for how easy it is to add A\/B testing capabilities to a Ruby <a href='#rc'>Camping<\/a> web application using the <a href='#tacaab'>ABingo Camping plugin<\/a>. <br \/>\n\t\t\t\t\tIn a subsequent post I will cover the specific implementation steps to add ABingo to our test application. Stay tuned!\n\t\t\t\t\t<\/p>\n<p>\t\t\t\t\t<a name='abcasrc'><\/a><\/p>\n<h5>Source Code<\/h5>\n<div   class='download_panel'>All source is available on GitHub:<\/p>\n<ul>\n\t\t\t\t\t\t<a href='http:\/\/bit.ly\/camping-abingo'>Camping ABingo <b>Plugin<\/b> library<\/a><br \/>\n\t\t\t\t\t\t<a href='http:\/\/bit.ly\/cgabtst'>Camping ABingo <b>Test<\/b> Example<\/a>\n\t\t\t\t\t<\/div>\n<p>\t\t\t\t\t<a name=\"referencesandresources\" ><\/a><\/p>\n<h3>References and Resources<\/h3>\n<h5>A\/B Testing<\/h5>\n<ul>\n<li><a name='abwp' href='http:\/\/en.wikipedia.org\/wiki\/A\/B_Testing'>A\/B Testing Definition on Wikipedia<\/a><\/li>\n<li><a name='abbasics' href='http:\/\/elem.com\/~btilly\/effective-ab-testing\/'>Effective A\/B Testing Basics (by Ben Tilly)<\/a><\/li>\n<li><a name='abgg' href='https:\/\/www.google.com\/analytics\/siteopt\/siteopt\/help\/overvw.html'>Google Website Optmizer<\/a><\/li>\n<li><a name='abpmk' href='http:\/\/www.bingocardcreator.com\/abingo'>ABingo A\/B Testing Framework (by Patrick McKenzie)<\/a><\/li>\n<li><a name='pmk' href='http:\/\/www.kalzumeus.com\/'>Patrick McKenzie's Blog<\/a><\/li>\n<li><a name='abpmktz' href='http:\/\/techzinglive.com\/page\/479\/79-tz-interview-%e2%80%93-patrick-mckenzie-optimize-this'>Patrick McKenzie Interview On TechZing Podcast<\/a><\/li>\n<\/ul>\n<h5>Camping<\/h5>\n<ul>\n<li><a name='rc' href='http:\/\/github.com\/camping\/camping'>Ruby Camping Framework<\/a><\/li>\n<li><a name='tacaab' href='http:\/\/github.com\/techarch\/camping-abingo'>Camping-ABingo repository on GitHub<\/a><\/li>\n<\/ul>\n<h5>Miscellaneous<\/h5>\n<ul>\n<li><a name='tz' \thref='http:\/\/techzinglive.com'>TechZing Podcast for web startup entrepreneurs<\/a><\/li>\n<li><a name='lita' \thref='http:\/\/www.dehats.com\/drupal\/?q=node\/58'>Lita, a SQLite administration tool<\/a><\/li>\n<\/ul>\n<h5>My Other Related Posts:<\/h5>\n<ul name=\"myotherrelatedposts\">\n<li><a href='https:\/\/blog.monnet-usa.com\/?p=223'>Visualize Application Metrics on NewRelic for your Ruby Camping Application<\/a><\/li>\n<\/ul>\n<div class=\"blog-msm-ad\">\n<div class=\"blog-msm-ad1\">\n\t\t\t\t\t\t\tIf you enjoyed this post, I would love it if you could check out <a href=\"http:\/\/bit.ly\/myskillsmap\">mySkillsMap<\/a>, my skills management app.\n\t\t\t\t\t\t<\/div>\n<div class=\"blog-msm-ad2\">\n\t\t\t\t\t\t\t\t<a href=\"http:\/\/www.myskillsmap.com\/signup?opt=trial&#038;origin=tabg\"><br \/>\n\t\t\t\t\t\t\t\t\t<img src='.\/wp-content\/media\/msm\/start-your-free-trial-now.png'  \/><br \/>\n\t\t\t\t\t\t\t\t<\/a>\n\t\t\t\t\t\t<\/div>\n<\/p><\/div>\n","protected":false},"excerpt":{"rendered":"<p>Intro Over the past few months, while listening to TechZing, a fantastic podcast for web startup entrepreneurs, the concept of A\/B Testing keeps coming up as key technique to track and measure conversion of site visitors into potential or true customers. Performing A\/B testing implies: Selecting content variations or use case variations to test Identifying [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[39,3,28],"tags":[40,56],"class_list":["post-322","post","type-post","status-publish","format-standard","hentry","category-ab-testing","category-ruby","category-ruby-camping","tag-ab-testing-2","tag-ruby"],"_links":{"self":[{"href":"https:\/\/blog.monnet-usa.com\/index.php?rest_route=\/wp\/v2\/posts\/322","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.monnet-usa.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.monnet-usa.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.monnet-usa.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.monnet-usa.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=322"}],"version-history":[{"count":6,"href":"https:\/\/blog.monnet-usa.com\/index.php?rest_route=\/wp\/v2\/posts\/322\/revisions"}],"predecessor-version":[{"id":327,"href":"https:\/\/blog.monnet-usa.com\/index.php?rest_route=\/wp\/v2\/posts\/322\/revisions\/327"}],"wp:attachment":[{"href":"https:\/\/blog.monnet-usa.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=322"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.monnet-usa.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=322"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.monnet-usa.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=322"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}