Slide 1

Slide 1 text

metrics.watch | freeGoogleAnalyticsCourse.com Best tools for automated testing in Ruby Jean-Philippe Boily @jipiboily | jipiboily.com Founder of Metrics Watch http://metrics.watch

Slide 2

Slide 2 text

metrics.watch | freeGoogleAnalyticsCourse.com whoami Jean-Philippe “JP” Boily Founder of Metrics Watch SaaS consultant Software Engineer with experience working remotely for US- based SaaS startups Last one was Rainforest QA (YC backed)

Slide 3

Slide 3 text

metrics.watch | freeGoogleAnalyticsCourse.com Metrics Watch Alerts for Google Analytics in near real-time. Support for custom metrics, filters, alert templates, etc. Check us out! http://metrics.watch PS: I have stickers!

Slide 4

Slide 4 text

metrics.watch | freeGoogleAnalyticsCourse.com Let’s talk about testing!

Slide 5

Slide 5 text

RSpec or MiniTest?

Slide 6

Slide 6 text

metrics.watch | freeGoogleAnalyticsCourse.com RSpec, or MiniTest? MiniTest comes with Ruby RSpec is a gem, NOT built-in in Ruby. It’s a DSL.

Slide 7

Slide 7 text

metrics.watch | freeGoogleAnalyticsCourse.com MiniTest Plain Ruby require "minitest/autorun" class TestMeme < Minitest::Test def setup @meme = Meme.new end def test_that_kitty_can_eat assert_equal "OHAI!", @meme.i_can_has_cheezburger? end end

Slide 8

Slide 8 text

metrics.watch | freeGoogleAnalyticsCourse.com MiniTest Spec require "minitest/autorun" describe Meme do before do @meme = Meme.new end describe "when asked about cheeseburgers" do it "must respond positively" do @meme.i_can_has_cheezburger?.must_equal "OHAI!" end end end

Slide 9

Slide 9 text

metrics.watch | freeGoogleAnalyticsCourse.com RSpec DSL that reads like English. Ships with color output & easy to re-run just the failures.

Slide 10

Slide 10 text

metrics.watch | freeGoogleAnalyticsCourse.com Color &failures

Slide 11

Slide 11 text

metrics.watch | freeGoogleAnalyticsCourse.com It just works Reads really well Works really well Has passed the test of time

Slide 12

Slide 12 text

RSpec!

Slide 13

Slide 13 text

metrics.watch | freeGoogleAnalyticsCourse.com The basics require ‘rails_helper' describe Watcher, :type => :model do describe '#alert' do it 'does something' do expect(true).to eq true end it { expect(true).to eq true } end end

Slide 14

Slide 14 text

metrics.watch | freeGoogleAnalyticsCourse.com describe Describe wraps tests, and other describe blocks Can have nested describe

Slide 15

Slide 15 text

metrics.watch | freeGoogleAnalyticsCourse.com it Definition of an example

Slide 16

Slide 16 text

metrics.watch | freeGoogleAnalyticsCourse.com expect What other frameworks call assertions

Slide 17

Slide 17 text

metrics.watch | freeGoogleAnalyticsCourse.com The basics: review require ‘rails_helper' describe Watcher, :type => :model do describe '#alert' do it 'does something' do expect(true).to eq true end it { expect(true).to eq true } end end

Slide 18

Slide 18 text

metrics.watch | freeGoogleAnalyticsCourse.com context Technically same as describe. Different semantic: they define… (drum roll) context! (SURPRISED,HUH?) describe Watcher, :type => :model do describe '#alert' do subject { Watcher.new } context 'when invalid' do it { is_expected.not_to be_valid } end end end

Slide 19

Slide 19 text

metrics.watch | freeGoogleAnalyticsCourse.com before & after setup & tear down describe '#alert' do before do @watcher = Watcher.new(threshold: 11) end after { reset_database } it { expect(@watcher.threshold).to eq 11 } end

Slide 20

Slide 20 text

metrics.watch | freeGoogleAnalyticsCourse.com let & let! memorized helper method `let` is lazy- evaluated, `let!` forces the evaluation describe '#alert' do let(:watcher) { Watcher.new(threshold: 11)} it { expect(watcher.threshold).to eq 11 } end

Slide 21

Slide 21 text

metrics.watch | freeGoogleAnalyticsCourse.com subject & is_expected DRY test with same subject, use “subject” describe Watcher, :type => :model do describe '#alert' do subject { Watcher.new(name:’:wave:') } it { is_expected.to be_new } end end describe Watcher, :type => :model do describe '#alert' do it { expect(Watcher.new(name:’:wave:')).to be_new } end end

Slide 22

Slide 22 text

metrics.watch | freeGoogleAnalyticsCourse.com More expectations .not_to eq .to eq .to be .to be_valid (or any method finishing with a ?) .to change{Watcher.count}.by(1) .to raise_error .to start_with

Slide 23

Slide 23 text

metrics.watch | freeGoogleAnalyticsCourse.com rspec-mock Stubs: allow(watcher).to receive(:alert) Message expectations expect(watcher).to receive(:alert) and much more…

Slide 24

Slide 24 text

metrics.watch | freeGoogleAnalyticsCourse.com Be careful with mocking & stubbing!

Slide 25

Slide 25 text

metrics.watch | freeGoogleAnalyticsCourse.com

Slide 26

Slide 26 text

metrics.watch | freeGoogleAnalyticsCourse.com (spec || rails)_helpers Configure & require stuff. Configure RSpec and other tools.

Slide 27

Slide 27 text

metrics.watch | freeGoogleAnalyticsCourse.com Best practices betterspecs.org

Slide 28

Slide 28 text

Great tools

Slide 29

Slide 29 text

metrics.watch | freeGoogleAnalyticsCourse.com factory_girl Help create test data. FactoryGirl.define do factory :watcher do metric_name "ga:sessions" threshold 100 end end RSpec.describe Watcher, :type => :model do describe '#alert' do let(:watcher) { create(:watcher) } it { expect(watcher.threshold).to eq 11 } end end https://github.com/thoughtbot/factory_girl

Slide 30

Slide 30 text

metrics.watch | freeGoogleAnalyticsCourse.com database_cleaner Keeps your database clean for new test data. RSpec.configure do |config| config.use_transactional_fixtures = false config.before(:suite) do DatabaseCleaner.clean_with(:transaction) end config.before(:each) do DatabaseCleaner.start end config.after(:each) do DatabaseCleaner.clean end end https://github.com/DatabaseCleaner/database_cleaner

Slide 31

Slide 31 text

metrics.watch | freeGoogleAnalyticsCourse.com guard & friends guard guard-rspec terminal-notifier-guard

Slide 32

Slide 32 text

metrics.watch | freeGoogleAnalyticsCourse.com guard Watch your file and do stuff when they change. Highly configurable. https://github.com/guard/guard

Slide 33

Slide 33 text

metrics.watch | freeGoogleAnalyticsCourse.com guard-rspec Run your Ruby specs when saving. Just the one that is related. Can keep running the failing ones. https://github.com/guard/guard-rspec

Slide 34

Slide 34 text

metrics.watch | freeGoogleAnalyticsCourse.com terminal-notifier-guard

Slide 35

Slide 35 text

metrics.watch | freeGoogleAnalyticsCourse.com spring Rails application preloader. It just works™.

Slide 36

Slide 36 text

metrics.watch | freeGoogleAnalyticsCourse.com VCR

Slide 37

Slide 37 text

metrics.watch | freeGoogleAnalyticsCourse.com I’m half kidding…

Slide 38

Slide 38 text

metrics.watch | freeGoogleAnalyticsCourse.com VCR “Record your test suite's HTTP interactions and replay them during future test runs for fast, deterministic, accurate tests.” Records them in cassettes. I’m NOT kidding.

Slide 39

Slide 39 text

metrics.watch | freeGoogleAnalyticsCourse.com VCR Great stuff! Much better than manually mocking. Now RSpec AND MiniTest! https://github.com/vcr/vcr

Slide 40

Slide 40 text

metrics.watch | freeGoogleAnalyticsCourse.com Timecop A "time travel” & "time freezing” gem describe "some set of tests to mock" do before do Timecop.freeze(Time.local(1990)) end after do Timecop.return end it "should do blah blah blah" do end end

Slide 41

Slide 41 text

Concepts

Slide 42

Slide 42 text

metrics.watch | freeGoogleAnalyticsCourse.com Test Driven Development (TDD) Red, green, refactor!

Slide 43

Slide 43 text

metrics.watch | freeGoogleAnalyticsCourse.com TDD: red class Watcher end describe Watcher do it { expect(Watcher.alert?).to eq(true) } end

Slide 44

Slide 44 text

metrics.watch | freeGoogleAnalyticsCourse.com TDD: green class Watcher def alert? true end end describe Watcher do it { expect(Watcher.alert?).to eq(true) } end

Slide 45

Slide 45 text

metrics.watch | freeGoogleAnalyticsCourse.com TDD: refactor class Watcher def alert? value > threshold end end describe Watcher do it { expect(Watcher.alert?).to eq(true) } end

Slide 46

Slide 46 text

metrics.watch | freeGoogleAnalyticsCourse.com TDD When should I TDD, or not?

Slide 47

Slide 47 text

metrics.watch | freeGoogleAnalyticsCourse.com Coverage Percentage of code…that runs during tests. Not that is properly tested! Beware of coverage! I find it useless.

Slide 48

Slide 48 text

metrics.watch | freeGoogleAnalyticsCourse.com CI, CD & CQA Continuous Integration Continuous Deployment Continuous QA (!!!)

Slide 49

Slide 49 text

metrics.watch | freeGoogleAnalyticsCourse.com CI, CD & CQA CI & CD: Circle CI, Codeship, Drone, Jenkins. Continuous QA: Rainforest QA

Slide 50

Slide 50 text

Conclusion?

Slide 51

Slide 51 text

metrics.watch | freeGoogleAnalyticsCourse.com Key takeaways •Use RSpec and betterspecs.org •Know your options & tools •TDD, CI, CD, CQA = win. Get as close. •Improve your workflow •Learn to trust your tests

Slide 52

Slide 52 text

GET AWESOME GIFTS ConFooLove.com • Slides for my two talks at ConFoo • testing toolbox cheatsheet • early invite to join my free email course about distributed teams, for pre-launch freeGAcourse.com • free course “How to get the most out of Google Analytics” • longer trial for Metrics Watch (1 month instead of 14 days)