# building the right things with mobiusloop `mobiusloop` provides continuous feedback to people on whether they are **building the right things**, not just **building things right**. Most product development tools focus on **building things right** meaning on time, on budget and with high quality. `mobiusloop` is different. It uses a simple language to define the desired business and product goals, such as Increase Customer Conversion or Improve App Responsiveness. Then `mobiusloop` uses automation to measure and report on progress towards these goals daily, weekly or whenever you want. With `mobiusloop` teams get realtime feedback on whether their new features are delivering the expected value. Leaders get clear visibility on whether their investments are delivering the desired return. Everyone gets feedback on whether they are **building the right things**. Use `mobiusloop` with methods like [Objectives and Key Results (OKR's)](https://www.amazon.com/Radical-Focus-Achieving-Important-Objectives-ebook/dp/B01BFKJA0Y) and [Mobius](http://mobiusloop.com) to define and measure the value of your product or service. ## how it works Today many teams write automated feature tests using open source tools like [Cucumber](http://cucumber.io). They write these tests in a simple, readable format using the [Gherkin](https://cucumber.io/docs/reference) language. Whenever these tests are run, teams get realtime feedback on the quality of their product. `mobiusloop` takes this concept and applies it to strategic business and product goals. Instead of tests that report on product quality when run, `mobiusloop` reports on progress towards desired goals. Under the covers `mobiusloop` is built on [Cucumber](http://cucumber.io) and consists of three main parts: 1. `.goal` files 1. step definitions 1. custom `Scale`'s #### 1. `.goal` files To start, leaders and teams agree on their objectives and the measurable outcomes that define success. Frameworks like [Objectives and Key Results (OKR's)](https://www.amazon.com/Radical-Focus-Achieving-Important-Objectives-ebook/dp/B01BFKJA0Y) and [Mobius](http://mobiusloop.com) encourage qualitative statements (problems or objectives) together with quantitative measures of success (outcomes or key results). Using `mobiusloop`, leaders and teams collaboratively write these in a `.goal` text file. Here's an example: ```ruby Objective: Reach a million paying customers by Q3 2016! Key Result: Increase Journal Readership Given a baseline of 500,000 readers on Oct 1, 2015 And a target of 1,000,000 readers by Oct 1, 2016 When we measure progress with "Total Readers Scale" Then report progress towards target ``` Here's another one: ```ruby Problem: Slow app response times are causing us to lose customers Outcome: Improve App Responsiveness Given a baseline of 4.5 seconds average response time on May 1, 2016 And a target of 1.5 seconds average response time by Jun 30, 2016 When we measure progress with "Peak User Performance Scale" Then report progress towards target ``` The syntax is based [Gherkin](https://cucumber.io/docs/reference), the language used to write Cucumber acceptance tests. `mobiusloop` introduces a four new keywords to Gherkin: **Objective**, **Problem**, **Outcome** and **Key Result**. Each `.goal` file contains **one** Objective or Problem and **one or more** Outcomes or Key Results. When the `.goal` files are run from a command line, they report progress towards your targets like this: ```ruby Objective: Top a million paying customers by Q3 2016! Key Result: Increase Journal Readership to 1,000,000 Given a baseline of 500000 readers on "Oct 1, 2015" And a target of 1000000 readers by "Oct 1, 2016" When we measure progress with "Total Readers Scale" Success! found 820,000 readers in 1.2 seconds! Then report progress towards targets Hooray! You are on track! 64% progress to target using 61% of the time (222 days) 36% remaining to target in 143 days ```` Progress is reported as text or optionally saved in a [web page](results.html) for sharing. With `mobiusloop` teams can measure progress towards their goals daily, weekly, monthly or whatever cadence makes sense. Integrating `mobiusloop` into your continuous delivery pipeline helps measure the impacts of each new release on your outcomes or key results. #### 2. step definitions Under the covers, `mobiusloop` is built on a forked copy of [cucumber-ruby](https://github.com/cucumber/cucumber-ruby). It uses Gherkin to parse the `.goal` file and call Cucumber [step definitions](https://github.com/cucumber/cucumber/wiki/Step-Definitions). `mobiusloop` ships with one step definition [mobius_steps.rb](lib/mobiusloop/mobius_steps.rb) that can be modified or extended. In `mobius_steps.rb`, the lines beginning with `Given` save the baseline and target values. The line beginning with `When` creates an `Outcome` with a custom `Scale`, sets the baselines and targets, then calls the `measure` method to perform the measurement. The line beginning with `Then` reports the progress towards targets. This `Given, When, Then` syntax is identical to Gherkin, easing the learning curve for teams already using Cucumber. Teams can either use `mobius_steps.rb` or create their own step definitions. #### 3. custom `Scale`'s At creation time, each outcome (or key result) is associated with a custom `Scale` of measure. `Scale`'s are the code that collects your data in your environment to report progress. `mobiusloop` ships with a few example scales, however teams are encouraged to create custom scales to meet their needs. To create a Scale, create a new Ruby class that extends `Scale` and then implement the `measure` method. Next, update the `.goal` file to reference your new `Scale` class. When `mobiusloop` parses this line: ```we measure progress with "Total Readers Scale"``` it creates a new instance of the Ruby class `TotalReadersScale` and calls the `measure` method, which returns a new `Measure`. In this example, you would implement the method `collect_total_readers` with your custom logic. ```Ruby require 'mobiusloop/scale' require 'mobiusloop/measure' class TotalReadersScale < Scale def measure total = collect_total_readers Measure.new(total) end end ```` ## getting started Adding `mobiusloop` to your product is easy, but requires some command-line chops. If this section looks like Greek, then as nicely as possible ask a developer on your team to help. **Note:** Currently only Linux and OSX are supported platforms. Windows will be added in the future. **TODO:** Simplify the installation steps to `gem install mobiusloop`. For now download the source and build a .gem locally. Download the [source code](https://github.com/ryanshriver/mobiusloop-ruby) into a working directory (e.g. /workspace/mobiusloop-ruby) If [Ruby](https://www.ruby-lang.org/en/), [gem](https://rubygems.org) and [bundle](http://bundler.io) are not installed, install them first. Then from the working directory, run these commands: $ gem build mobiusloop.gemspec $ gem install mobiusloop-0.1.1.gem Replace `mobiusloop-0.1.1.gem` with whatever version was built. Finally, create a symbolic link for the `mobiusloop` command. First locate your ruby executable path: $ gem env Look for the value of `EXECUTABLE DIRECTORY`, something like `/usr/local/Cellar/ruby/2.2.3/bin/`. Then create a symbolic link: $ ln -s improve our digital customer experience. - Let's only start with one `Outcome`, so delete from `Outcome: Increase Published Articles` to the end of the file - Now update your `Outcome:` keeping it short and sweet. Something like Improve Response Time Now save the file and run again: $ mobiusloop Cool, now we have multiple running goals! As you add more `.goal` files to `goals/` folder, `mobiusloop` runs them. If you only wanted to run one `.goal`, you could do that easily: $ mobiusloop goals/increase_readers.goal We don't need the example anymore, so let's remove it: $ rm goals/increase_readers.goal #### Define baselines and targets Open `improve_response_time.goal` again and let's update the baselines and targets. Let's pretend as of last October your app's home page takes 4.5 seconds to load. That's your baseline. Make a change: - In the row starting with `Given`, change 50000 to 4.5 Your product owner has said sub-second is how fast it should load. That's your target. Make another change: - In the row starting with `And`, change 1000000 to 1 Finally, your unit of measure is not "readers", so let's fix that: - Change "readers" to "seconds" for both target and baseline rows Now save the file and run again: $ mobiusloop This works, but the scale says we have 820,000 seconds! That's not right, so let's fix it. #### Define scales Open `improve_response_time.goal` again and let's change the scale to record response times, not total readers. - In the row starting with `When`, change "Total Readers Scale" to "Page Response Scale" Now save the file and run again. $ mobiusloop Wow, much better! The "Page Response Scale" requested google.com and compared the response time to your target. How did you do? Depending on your internet speed, hopefully you hit the target. ## Developing with `mobiusloop` Hopefully by now you're getting the hang of it. When developing with `mobiusloop` there are three basic steps: #### Step 1: Create a new `.goal` file in the `goals/` directory You can copy an example or start from scratch. When done, do a dry run to ensure your syntax is valid: $ mobiusloop goals/your_objective.goal --dry-run Replacing `your_objective.goal` with your filename. If there's any syntax problems, fix them and run again until you get a clean run. #### Step 2: Optionally create a step definition `mobiusloop` ships with one step definition `goals/step_definitions/mobius_steps.rb`. If you write your objectives, problems, outcomes and key results in the format above there's no need to create one. However if you want to create your own format, you will need to create a custom step definition. To verify, run: $ mobiusloop goals/your_objective.goal If `mobiusloop` cannot find a matching step definition for your `.goal` file, it will tell you the step definition to create. Copy and paste this into a new file `your_name_steps.rb` and save it to the `goals/step_definitions` folder. For more info on step definitions, see [Cucumber's reference](https://cucumber.io/docs/reference#step-definitions). #### Step 3: Create a new `Scale` Create a new Ruby class to perform the measurement. For example, if your .`goal` file contains "My Custom Scale", the Ruby class would be: ```Ruby require 'mobiusloop/scale' require 'mobiusloop/measure' class MyCustomScale < Scale def measure total = fetch_your_total Measure.new(total) end end ``` Replace the line `total = fetch_your_total` with your custom logic. The last line should be `Measure.new(total)` to return a new measure. We recommend writing unit tests around any custom scales you create to ensure they work as expected before integrating with `mobiusloop` When done, run: $ mobiusloop goals/your_objective.goal To run a single `.goal`, or: $ mobiusloop To run all the `.goal` files in `/goals` folder. ## Advanced Features Because `mobiusloop` is an extension of [Cucumber](http://cucumber.io), there are many features in Cucumber that also exist in `mobiusloop`. A few examples: **Tags** - Use tags to create logical groups of Objectives, Problems, Outcomes or Key Results that you want run together. For example, adding `@mytag` to the line immediately above a definition and running it with: $ mobiusloop --tags @mytag Will only run those Objectives, Problems, Outcomes or Key Results associated with that tag. **Reports** - By default `mobiusloop` outputs the results to the command line. But you can also output reports in HTML, JSON or other formats. See [Cucumber reports](https://cucumber.io/docs/reference#reports) for more details. ## Testing `mobiusloop` is built using a test-first approach. We're proud of our tests, but we're always looking to add more. If you downloaded the source code to `/workspace/mobiusloop-ruby`, you can run the tests using this command from the source code folder: $ rake spec ## Report Defects See a missing test or found a defect? [Let us know](https://github.com/ryanshriver/mobius/issues) by creating a new issue. ## Contributing Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/mobius.