Ruby on Rails on Minitest



Similar documents
Part II. Managing Issues

Rake Task Management Essentials

Testing Frameworks (MiniTest)

Introduction. What is RAID? The Array and RAID Controller Concept. Click here to print this article. Re-Printed From SLCentral

Survey of Unit-Testing Frameworks. by John Szakmeister and Tim Woods

Unit Testing. and. JUnit

Ruby on Rails. a high-productivity web application framework. blog.curthibbs.us/ Curt Hibbs <curt@hibbs.com>

Introduction to Open Atrium s workflow

Ruby On Rails A Cheatsheet. Ruby On Rails Commands

Intro to scientific programming (with Python) Pietro Berkes, Brandeis University

Continuous Integration

Testing Python. Applying Unit Testing, TDD, BDD and Acceptance Testing

JRuby Now and Future Charles Oliver Nutter JRuby Guy Sun Microsystems

Testing Rails. by Josh Steiner. thoughtbot

Drupal + Formulize. A Step-by-Step Guide to Integrating Drupal with XOOPS/ImpressCMS, and installing and using the Formulize module

Power Tools for Pivotal Tracker

Development Environment and Tools for Java. Brian Hughes IBM

Java course - IAG0040. Unit testing & Agile Software Development

Digital Marketing Manager, Marketing Manager, Agency Owner. Bachelors in Marketing, Advertising, Communications, or equivalent experience

Welcome to the Force.com Developer Day

ESA FAQ. Self Administration Frequently Asked Questions

12Planet Chat end-user manual

My Secure Backup: How to reduce your backup size

Build Automation for Mobile. or How to Deliver Quality Apps Continuously. Angelo Rüggeberg

Everyday Lessons from Rakudo Architecture. Jonathan Worthington

Software Testing with Python

Solution Spotlight KEY OPPORTUNITIES AND PITFALLS ON THE ROAD TO CONTINUOUS DELIVERY

Google Drive: Access and organize your files

Appendix 1: Adaptable Templates

PART IV Performance oriented design, Performance testing, Performance tuning & Performance solutions. Outline. Performance oriented design

Secrets to Automation Success. A White Paper by Paul Merrill, Consultant and Trainer at Beaufort Fairmont, LLC

Web Applications Security: SQL Injection Attack

How to Perform a Break-Even Analysis in a Retail Store A Step by Step Guide

Web development... the server side (of the force)

How to Outsource Without Being a Ninnyhammer

Managing User Accounts and User Groups

Accelerate Your Rails Site with Automatic Generation-Based Action Caching. Rod Cope, CTO and Founder OpenLogic, Inc.

The Cucumber Book. Extracted from: Behaviour-Driven Development for Testers and Developers. The Pragmatic Bookshelf

Stack Allocation. Run-Time Data Structures. Static Structures

Transcription. Crashplan vs Backblaze. Which service should you pick the short version

Continuous Integration and Bamboo. Ryan Cutter CSCI Spring Semester

Development at the Speed and Scale of Google. Ashish Kumar Engineering Tools

JUnit - A Whole Lot of Testing Going On

Lecture 17: Mobile Computing Platforms: Android. Mythili Vutukuru CS 653 Spring 2014 March 24, Monday

TU04. Best practices for implementing a BI strategy with SAS Mike Vanderlinden, COMSYS IT Partners, Portage, MI

Software Engineering Techniques

Gallio: Crafting a Toolchain. Jeff Brown jeff.brown@gmail.com

Building Your Firewall Rulebase Lance Spitzner Last Modified: January 26, 2000

Unit Testing Strategies

Upping the game. Improving your software development process

System Level Integration and Test Leveraging Software Unit Testing Techniques

Computer Forensics for Business Leaders: Building Robust Policies and Processes Transcript

Jazz Source Control Best Practices

CS193j, Stanford Handout #10 OOP 3

How to Get of Debt in 24 Months

>> My name is Danielle Anguiano and I am a tutor of the Writing Center which is just outside these doors within the Student Learning Center.

ISVforce Guide. Version 35.0, Winter

How Safe does my Code Need to be? Shawn A. Prestridge, Senior Field Applications Engineer

Multi-Factor Authentication: Do I Need It, and How Do I Get Started? [And If I Do Need It, Why Aren't Folks Deploying It?]

Build management & Continuous integration. with Maven & Hudson

Progressive Enhancement With GQuery and GWT. Ray Cromwell

Web Frameworks. web development done right. Course of Web Technologies A.A. 2010/2011 Valerio Maggio, PhD Student Prof.

Java Troubleshooting and Performance

Continuous Delivery on AWS. Version 1.0 DO NOT DISTRIBUTE

Building, testing and deploying mobile apps with Jenkins & friends

The programming language C. sws1 1

Course Goals. Solve Non-Technical Customer problem Server side: Ruby on Rails Client side: HTML, CSS, AJAX, JavaScript Deploy using cloud computing

Web Hosting: Pipeline Program Technical Self Study Guide

An Oracle White Paper July Oracle Primavera Contract Management, Business Intelligence Publisher Edition-Sizing Guide

Test Driven Development

Real Time Programming: Concepts

Resource Monitoring During Performance Testing. Experience Report by Johann du Plessis. Introduction. Planning for Monitoring

Generating Marketing Leads Via Marketing Forums

How To Design Your Code In Php (Php)

Cucumber and Capybara

High Level Design Distributed Network Traffic Controller

Achieving business benefits through automated software testing. By Dr. Mike Bartley, Founder and CEO, TVS

Building Applications Using Micro Focus COBOL

Using collaboration to enable the innovators in your organization. Welcome to the IBM CIO Podcast Series. I'm your host, Jeff Gluck,

Testing, Debugging, and Verification

JUnit. Introduction to Unit Testing in Java

Monitoring, Tracing, Debugging (Under Construction)

Next Generation Tech-Talk. Cloud Based Business Collaboration with Cisco Spark

Jenesis Software - Podcast Episode 2

A lap around Team Foundation Server 2015 en Visual Studio 2015

Sponsored by: Speaker: Brian Madden, Independent Industry Analyst and Blogger

THE ROAD TO CODE. ANDROID DEVELOPMENT IMMERSIVE May 31. WEB DEVELOPMENT IMMERSIVE May 31 GENERAL ASSEMBLY

Ruby on Rails. Object Oriented Analysis & Design CSCI-5448 University of Colorado, Boulder. -Dheeraj Potlapally

Hudson Continous Integration Server. Stefan Saasen,

Co-Presented by Mr. Bill Rinko-Gay and Dr. Constantin Stanca 9/28/2011

CS 2112 Spring Instructions. Assignment 3 Data Structures and Web Filtering. 0.1 Grading. 0.2 Partners. 0.3 Restrictions

Transcription:

Ruby on Rails on Minitest 1

Setting Expectations Introductory Talk. Very Little Code. Not going to teach testing or TDD. What & why, not how. 218 Slides, 5.45 SPM. 2

WTF is minitest? 3

What is Minitest? Replacement for ruby 1.8 s test/unit. Originally 90 lines of code, only test/unit basics. Available as a gem, and ships with ruby 1.9.1 & up. Meant to be small, clean, and very fast. Now ~1600 loc, unit, spec, benchmarks, mock/stub, plugins, etc. 4

6 Parts of Minitest runner The heart of the machine minitest/unit TDD API minitest/spec BDD API minitest/mock Simple mocking API minitest/pride IO pipelining example minitest/bench Abstract benchmark API 5

2 Parts of Minitest runner The heart of the machine minitest/unit TDD API minitest/spec BDD API minitest/mock Simple mocking API minitest/pride IO pipelining example minitest/bench Abstract benchmark API 6

minitest/test 7

Test Cases are Classes 8

Tests are Methods 9

Test Example require "minitest/autorun" class TestThingy < Minitest::Test def test_do_the_thing assert_equal 42, Thingy.do_the_thing end end 10

Test Example require "minitest/autorun" Simple Subclass class TestThingy < Minitest::Test def test_do_the_thing assert_equal 42, Thingy.do_the_thing end end 10

Test Example require "minitest/autorun" Simple Subclass class TestThingy < Minitest::Test def test_do_the_thing assert_equal 42, Thingy.do_the_thing end end Simple Method 10

Test Example require "minitest/autorun" Simple Subclass class TestThingy < Minitest::Test def test_do_the_thing assert_equal 42, Thingy.do_the_thing end end Simple Method Magic Free! 10

Positive Assertions assert assert_kind_of assert_respond_to assert_empty assert_match assert_same assert_equal assert_nil assert_send* assert_in_delta assert_operator assert_silent*+ assert_in_epsilon+ assert_output*+ assert_throws* assert_includes+ assert_instance_of assert_predicate+ assert_raises* 11 +not in testunit *no negative equiv

Negative Assertions refute+ refute_kind_of+ refute_respond_to+ refute_empty+ refute_match refute_same refute_equal refute_nil refute_send refute_in_delta+ refute_operator+ refute_silent refute_in_epsilon+ refute_output refute_throws refute_includes+ refute_instance_of+ refute_predicate+ refute_raises 12 +not in testunit

Why all these extra assertions? They're more expressive! assert! obj refute obj assert collection.include? obj assert_includes obj, collection out, err = capture_io do do_something end assert_equal "output", out assert_equal "", err assert_output "output", "" do do_something end 13

assert_equal diffs: 1) Failure: test_failing_simple(testsimple) [example.rb:8]: Expected: 42 Actual: 24 2) Failure: test_failing_complex(testcomplex) [example.rb:23]: --- expected +++ actual @@ -22,7 +22,7 @@ "line 22", "line 23", "line 24", - "line 25", + "something unexpected", "line 26", "line 27", "line 28", 14

But... 15

Where is refute_raises? 16

Same place as refute_silent. 17

refute_silent This block of code must print something. What it is, I don't care. How is this assertion of value to anyone? Assert for the specific output you need. 18

refute_silent This block of code must print something. What it is, I don't care. How is this assertion of value to anyone? Assert for the specific output you need. 19

refute_raises This block of code must do something. What it is, I don't care. How is this assertion of value to anyone? Assert for the specific result you need. 20

It's Useful No it isn't. Implies side effects and/or return values have been checked. Or aren't important (always false otherwise, why write the code?). Falsely bumps code coverage metrics. False sense of security. 21

It's More Expressive No it isn't. Writing the test was the act of expression. It is an explicit contract in any test framework that unhandled exceptions are an error. The test's mere existence explicitly states: "there are no unhandled exceptions via these pathways". 22

I've been having this argument for years 23

Some people will never be convinced 24

Stand Back 25

def check_everything assert_something_output do assert_nothing_raised do assert_some_side_effect do assert_some_response do yield end end end end end 26

def check_everything assert_something_output do assert_nothing_raised do assert_some_side_effect do assert_some_response do yield end end end end end 2015 Ryan Davis All Rights Reserved ISO 9001 Enterprise Certified Available for $$$$ 26

27

minitest/spec 28

Testing DSL 29

Test Cases are `describe` blocks 30

Tests are `it` blocks 31

Spec Example require "minitest/autorun" describe Thingy do it "must do the thing" do _(Thingy.do_the_thing).must_equal 42 end end 32

But 33

In Reality 34

`describe` blocks are Classes 35

`it` blocks are Methods 36

Spec Example require "minitest/autorun" describe Thingy do it "must do the thing" do _(Thingy.do_the_thing).must_equal 42 end end 37

Specs Transform: require "minitest/autorun" class TestThingy < Minitest::Test def test_0001_must_do_the_thing _(Thingy.do_the_thing).must_equal 42 end end 38

Specs Transform: require "minitest/autorun" Simple Subclass class TestThingy < Minitest::Test def test_0001_must_do_the_thing _(Thingy.do_the_thing).must_equal 42 end end 38

Specs Transform: require "minitest/autorun" Simple Subclass class TestThingy < Minitest::Test def test_0001_must_do_the_thing _(Thingy.do_the_thing).must_equal 42 end end Simple Method 38

Specs Transform: require "minitest/autorun" Simple Subclass class TestThingy < Minitest::Test def test_0001_must_do_the_thing _(Thingy.do_the_thing).must_equal 42 end end Simple Method Magic Free! 38

Positive Expectations must_be must_be_close_to must_be_empty must_be_instance_of must_be_kind_of must_be_nil must_be_same_as must_be_silent* must_be_within_delta must_be_within_epsilon must_equal must_include must_match must_output* must_raise* must_respond_to must_send* must_throw* 39

Negative Expectations wont_be wont_be_close_to wont_be_empty wont_be_instance_of wont_be_kind_of wont_be_nil wont_be_same_as wont_be_silent wont_be_within_delta wont_be_within_epsilon wont_equal wont_include wont_match wont_output wont_raise wont_respond_to wont_send wont_throw 40

All for Free must_equal is assert_equal wont_equal is refute_equal etc. 41

Advanced Testing 42

Randomization Baked In 43

Preventing Test Order Dependencies 44

parallelize_me! 45

Use gem, not stdlib Randomize Test Order 5 4 Write custom assertions 6 7 Refactor to reusable testcases 8 Benchmark Tests Turn up the test + spec 3 9 Forced Parallelization Disallow meaningless assertions 2 Fast Test Runner 1 0 11 10??? Require Proof of Success? test levels 46

Design Rationale 47

It's Just Ruby 48

Look! Ruby! require "minitest/autorun" class TestThingy < Minitest::Test def test_do_the_thing assert_equal 42, Thingy.do_the_thing end end 49

Less is More 50

assert_in_delta def assert_in_delta e, a, d = 0.001, m = nil n = (e - a).abs msg = message(m) { "... failure message..." } assert delta >= n, msg end 51

assert_in_delta def assert_in_delta e, a, d = 0.001, m = nil n = (e - a).abs msg = message(m) { "... failure message..." } assert delta >= n, msg end message takes a block to defer calculation until an assertion fails 51

assert_in_delta def assert_in_delta e, a, d = 0.001, m = nil n = (e - a).abs msg = message(m) { "... failure message..." } assert delta >= n, msg end message takes a simple assertion is all that is needed block to defer calculation until an assertion fails 51

assert_in_delta def assert_in_delta e, a, d = 0.001, m = nil n = (e - a).abs msg = message(m) { "... failure message..." } assert delta >= n, msg end Only 2 other methods need to be understood: assert (9) & message (6) simple assertion is all that is needed message takes a block to defer calculation until an assertion fails 51

Indirection is the Enemy 52

Just 2 Hops module Minitest::Expectation def must_equal(*args) ctx.assert_equal(*args) end end module Minitest::Assertions def assert_equal exp, act, msg = nil msg = message(msg, E) { diff exp, act } assert exp == act, msg end end 53

No Magic Allowed 54

Thriving Plugin Ecosystem minitest-chef-handler minitest-metadata minitest-reporters minitest-rails-capybara minitest-rails minitest-matchers guard-minitest capybara_minitest_spec minitest-spec-rails minitest-colorize minitest-capybara minitest-rg spork-minitest minitest-ci (& many more) 55

Rails & Minitest 56

The Official Rails Stack uses Minitest 57

Each Release 58

Peels back the testing onion https://www.flickr.com/photos/darwinbell/303874154 59

Encouraging better testing practices 60

Peeling onions make you cry https://www.flickr.com/photos/marleahjoy/13153221935 61

Right? 62

(Hopefully) Not Here 63

Rails 4.0 minitest 4.x 64

Impact? Zero 65

Rails 4.1 minitest 5.x 66

Impact? Zero 67

Rails 4.2 random order 68

Some Impact? 69

Good Thing! 70

Future Rails Should track minitest. 71

As a Rails Dev 72

What does all of this mean? 73

Hopefully... 74

Nothing 75

ActiveSupport ::TestCase 76

Basic Architecture Minitest::Test ActiveSupport::TestCase MyThingyTest 77

Per-test database transactions 78

Fixtures # In fixtures/categories.yml about: name: About # In fixtures/articles.yml one: title: Welcome to Rails! body: Hello world! category: about 79

Declarative Forms setup do end #... teardown do end #... test test name do end #... 80

Extra Assertions assert_difference assert_valid_keys assert_deprecated assert_nothing_raised 81

Wait? What?!? 82

Don't Worry! def assert_nothing_raised(*args) end yield 83

Don't Worry! def assert_nothing_raised(*args) end yield Actual Implementation 83

Unit Testing require 'test_helper' class ArticleTest < ActiveSupport::TestCase test "should not save article without title" do article = Article.new refute article.save end end 84

ActionController ::TestCase 85

Basic Architecture Minitest::Test ActiveSupport::TestCase ActionController::TestCase MyControllerTest 86

Actions get post delete etc 87

State request response session flash 88

Assertions assert_response assert_redirected_to assert_template 89

Functional Testing class ArticlesControllerTest < ActionController::TestCase test "should get index" do get :index assert_response :success assert_not_nil assigns(:articles) end end 90

ActiveDispatch ::IntegrationTest 91

Architecture Minitest::Test ActiveSupport::TestCase ActionDispatch::IntegrationTest MyIntegrationTest 92

Assertions Tons 93

Integration Testing class UserFlowsTest < ActionDispatch::IntegrationTest test "login and browse site" do https! get "/login" assert_response :success david = users :david post_via_redirect "/login", username: david.username, password: david.password assert_equal '/welcome', path assert_equal 'Welcome david!', flash[:notice] https! false get "/articles/all" assert_response :success assert assigns :articles end end 94

http:// guides.rubyonrails.org/ testing.html 95

Very Simple 96

Very Powerful 97

Leverages Minitest 98

Test Randomization 99

Parallelization 100

Enforce Better Testing 101

Troubleshooting 102

I want to use minitest, but I prefer spec-style 103

Simple 104

minitest-rails 105

minitest-spec-rails 106

Lets you do this: describe User do let(:user) { User.create!... } it "does the thing to the stuff" do user.username.must_match(/.../) end end 107

I upgraded to rails 4.2 and now I have failures 108

AKA: you broke all my shit 109

Not as Simple 110

Test-Order Dependency Bug 111

ran: a, b, c = pass ran: b, a, c = fail 112

Easy! 113

But, I have hundreds of tests! 114

Not so Easy 115

minitest-bisect 116

Helps you isolate and debug random test failures 117

118

118

I'm used to RSpec + factory-girl + this + that + kitchen sink + everything 119

A lot of stuff Just Works 120

Look for plugins in readme / gems 121

My Suggestion? 122

Less Complicated Testing 123

Try It 124

You Might Like It 125

Change Takes Time 126

Why use minitest? 127

Why Test? aka It slows me down 128

Not Going to Bother 129

Lost Cause 130

I'd rather help other people 131

Everyone Uses RSpec 132

Obviously Not 133

The Official Rails Stack uses Minitest 134

DHH uses minitest 135

tenderlove uses minitest 136

Jeff Casimir & cohort teach minitest at Turing School 137

nokogiri, haml, god, newrelic_rpm, sqlite3 138

etc 139

Functional Differences with RSpec 140

Unique Features of RSpec Test metadata & metadata filtering. Implicit subject, described_class, etc. Fancier expectations, negation, etc. before(:all) & around(:each). Shared contexts & example groups. Fancier mocking. Fancier reporting. 141

Unique Features of RSpec Test metadata & metadata filtering. Implicit subject, described_class, etc. Fancier expectations, negation, etc. before(:all) & around(:each). Shared contexts & example groups. Fancier mocking. Fancier reporting. 141 Basically, it's Fancier

Unique Features of Minitest Unit & Spec Style Testing. Über-Duper fast and lightweight. Easy to understand whole library. minitest/pride. Benchmark tests. First to randomize parallelize_me! & minitest/hell Clean & easy plugin system. Smallest mock/stub framework. 142

Unique Features of Minitest Unit & Spec Style Testing. Über-Duper fast and lightweight. Easy to understand whole library. minitest/pride. Benchmark tests. First to randomize parallelize_me! & minitest/hell Clean & easy plugin system. Smallest mock/stub framework. Simple, Pragmatic 142

Unique Features of Minitest Unit & Spec Style Testing. Über-Duper fast and lightweight. Easy to understand whole library. minitest/pride. Benchmark tests. First to randomize parallelize_me! & minitest/hell Clean & easy plugin system. Smallest mock/stub framework. Simple, Pragmatic and a bit Snarky 142

Cognitive differences with RSpec 143

Myron Marston 144

Great Comparison 145

I'm one of the RSpec developers, and have never used minitest, so take my biases into account when reading this answer. By and large, RSpec's power comes from the fact that it reifies so many testing concepts into first class objects. Where Test::Unit and Minitest use simple methods for making assertions, RSpec uses first-class matcher objects that support negation, self-description and more. RSpec's examples are first-class objects that support rich metadata; minitest/spec compiles it blocks down into simple methods, which don't support the same sort of rich metadata. RSpec supports specifying shared behaviors using a first-class construct (shared example groups) that accepts arguments; w/ minitest you can use inheritance or a mixin to re-use tests, but it doesn't have the same sort of first-class support. RSpec has an explicit formatter API (and there are many third party formatters that use it); I'm not aware of minitest having the same sort of first-class formatter API. As somebody who is constantly running tests and practicing TDD all day long, I find the power RSpec gives me to be very useful. Many people find it to be overkill, though, and there is an added cognitive cost to the extra abstractions. Here are some specific features RSpec has that I believe minitest lacks: before(:all) hooks (note this is a power user feature of RSpec that should rarely be used; I've only used it on a few occasions in many years of using RSpec) around(:each) hooks Shared example groups Shared contexts Rich metadata support that can be used to control which examples get run, which example groups shared contexts get included in, which example groups modules get mixed into and more. 146 Integrated support for a wide range of mocking features w/ rspec-mocks; Minitest::Mock

2 Answers I'm one of the RSpec developers, and have never used minitest, so take my biases into account when reading this answer. By and large, RSpec's power comes from the fact that it reifies so many testing concepts into first class objects. Where Test::Unit and Minitest use simple methods for making assertions, RSpec uses first-class matcher objects that support negation, self-description and more. RSpec's examples are first-class objects that support rich metadata; minitest/spec compiles it blocks down into simple methods, which don't support the same sort of rich metadata. RSpec supports specifying shared behaviors using a first-class construct (shared example groups) that accepts arguments; w/ minitest you can use inheritance or a mixin to re-use tests, but it doesn't have the same sort of first-class support. RSpec has an explicit formatter API (and there are many third party formatters that use it); I'm not aware of minitest having the same sort of first-class formatter API. As somebody who is constantly running tests and practicing TDD all day long, I find the power RSpec gives me to be very useful. Many people find it to be overkill, though, and there 146

Ruby on Rails on Minitest Apparently, I'm @tenderlove https://farm4.staticflickr.com/3522/3274006022_0c72c24508_o.jpg 147

Ruby on Rails on Minitest Apparently, I'm @tenderlove https://farm4.staticflickr.com/3522/3274006022_0c72c24508_o.jpg 147

TL;DR 148

By and large, RSpec's power comes from the fact that it reifies so many testing concepts into first class objects. Where Test::Unit and Minitest use simple methods for making assertions, RSpec uses first-class matcher objects that support negation, self-description and more. RSpec's examples are firstclass objects that support rich metadata; minitest/spec compiles it blocks down into simple methods, which don't support the same sort of rich metadata. RSpec supports specifying shared behaviors using a first-class construct (shared example groups) that accepts arguments; w/ minitest you can use inheritance or a mixin to re-use tests, but it doesn't have the same sort of firstclass support. http://stackoverflow.com/questions/12470601/minitest-and-rspec 149

Myron thinks this is why RSpec is great 150

I think it is everything wrong with RSpec 151

We're Both Right 152

"Do I contradict myself? Very well, then I contradict myself, I am large, I contain multitudes." Walt Whitman 153

By and large, RSpec's power comes from the fact that it reifies so many testing concepts into first class objects. Where Test::Unit and Minitest use simple methods for making assertions, RSpec uses first-class matcher objects that support negation, self-description and more. RSpec's examples are firstclass objects that support rich metadata; minitest/spec compiles it blocks down into simple methods, which don't support the same sort of rich metadata. RSpec supports specifying shared behaviors using a first-class construct (shared example groups) that accepts arguments; w/ minitest you can use inheritance or a mixin to re-use tests, but it doesn't have the same sort of firstclass support. http://stackoverflow.com/questions/12470601/minitest-and-rspec 154

Minitest RSpec Example Groups Examples Reuse Expectations 155 * my interpretation, not a quote

Minitest RSpec Example Groups compiles describe blocks down into simple classes* reifies testing concepts into first class objects* Examples Reuse Expectations 155 * my interpretation, not a quote

Minitest RSpec Example Groups compiles describe blocks down into simple classes* reifies testing concepts into first class objects* Examples compiles it blocks down into simple methods examples are first-class objects Reuse Expectations 155 * my interpretation, not a quote

Minitest RSpec Example Groups compiles describe blocks down into simple classes* reifies testing concepts into first class objects* Examples compiles it blocks down into simple methods examples are first-class objects Reuse you can use inheritance or a mixin specifying shared behaviors using a first-class construct Expectations 155 * my interpretation, not a quote

Minitest RSpec Example Groups compiles describe blocks down into simple classes* reifies testing concepts into first class objects* Examples compiles it blocks down into simple methods examples are first-class objects Reuse you can use inheritance or a mixin specifying shared behaviors using a first-class construct Expectations use simple methods for making assertions uses first-class matcher objects 155 * my interpretation, not a quote

Minitest RSpec Example Groups compiles describe blocks down into simple methods reifies testing concepts into first class objects Examples compiles it blocks down into simple methods examples are first-class objects Reuse you can use inheritance or a mixin specifying shared behaviors using a first-class construct Expectations use simple methods for making assertions uses first-class matcher objects 156

Minitest RSpec compiles describe blocks Example Groups Class 1st Class Object down into simple methods reifies testing concepts into first class objects Examples compiles it blocks down into simple methods examples are first-class objects Reuse you can use inheritance or a mixin specifying shared behaviors using a first-class construct Expectations use simple methods for making assertions uses first-class matcher objects 156

Minitest RSpec compiles describe blocks Example Groups Class 1st Class Object down into simple methods reifies testing concepts into first class objects compiles it blocks down into Examples Method 1st Class Object simple methods examples are first-class objects Reuse you can use inheritance or a mixin specifying shared behaviors using a first-class construct Expectations use simple methods for making assertions uses first-class matcher objects 156

Minitest RSpec compiles describe blocks Example Groups Class 1st Class Object down into simple methods reifies testing concepts into first class objects compiles it blocks down into Examples Method 1st Class Object simple methods examples are first-class objects you can use inheritance or a Reuse Subclass or Include 1st Class Object mixin specifying shared behaviors using a first-class construct Expectations use simple methods for making assertions uses first-class matcher objects 156

Minitest RSpec compiles describe blocks Example Groups Class 1st Class Object down into simple methods reifies testing concepts into first class objects compiles it blocks down into Examples Method 1st Class Object simple methods examples are first-class objects you can use inheritance or a Reuse Subclass or Include 1st Class Object mixin specifying shared behaviors using a first-class construct use simple methods for Expectations Method Call 1st Class Object making assertions uses first-class matcher objects 156

Ruby on Rails on Minitest 1st Class You keep using that term. I do not think it means what you think it means. 157

A language construct is said to be a FirstClass value in that language when there are no restrictions on how it can be created and used: when the construct can be treated as a value without restrictions. FirstClass features can be stored in variables, passed as arguments to functions, created within functions and returned from functions. In dynamically typed languages, a FirstClass feature can also have its type examined at run-time. http://c2.com/cgi/wiki?firstclass 158

Minitest RSpec Example Groups Class 1st Class Object Examples Method 1st Class Object Reuse Subclass or Include 1st Class Object Expectations Method Call 1st Class Object 159

Minitest RSpec It's Just Ruby Example Groups Class 1st Class Object Examples Method 1st Class Object Reuse Subclass or Include 1st Class Object Expectations Method Call 1st Class Object 159

Minitest RSpec It's Just Ruby Reinvents the Wheel Example Groups Class 1st Class Object Examples Method 1st Class Object Reuse Subclass or Include 1st Class Object Expectations Method Call 1st Class Object 159

Nested Describes describe A do before { :a } it "runs :a" describe B do before { :b } it "runs :a, :b" end end 160

Nested Describes describe A do Inherited "methods" before { :a } it "runs :a" describe B do before { :b } it "runs :a, :b" end end 160

Nested Describes describe A do Inherited "methods" before { :a } it "runs :a" describe B do before { :b } it "runs :a, :b" end end NOT Inherited "methods" 160

Are A & B classes? Is Nesting like Subclassing? 161

Classes? class TestA < RSpec::Spec def before super :a end class TestB < TestA def before super :b end def test_runs_a; end undef_method :test_runs_a end end def test_runs_a_b; end 162

Classes? class TestA < RSpec::Spec def before super :a end class TestB < TestA def before super :b end def test_runs_a; end undef_method :test_runs_a end end def test_runs_a_b; end 162

Are before/after like included modules? 163

Modules? class TestA < RSpec::Spec module BeforeAfter def setup super if respond_to? :super :a end end class TestB < RSpec::Spec module BeforeAfter def setup super if respond_to? :super :b end end include TestA::BeforeAfter include TestA::BeforeAfter include TestB::BeforeAfter end def test_runs_a; end end def test_runs_a_b; end 164

This is basically Another Object Model 165

That's Confusing if you're just learning Ruby/OO 166

Encourages new users to handwave 167

To not know what #describe or #it actually are or do 168

Here's the Magic Incantation to do X 169

Any sufficiently advanced technology is indistinguishable from magic. A.C. Clarke 170

RSpec: It s actually Magic

Many people find it to be overkill, though, and there is an added cognitive cost to the extra abstractions. Myron Marsten, from previous post 172

Indeed 173

*/lib Minitest RSpec Multiplier # Files 14 177 12.64 Flog 2,005.0 13,274.3 6.62 Lines of Code 1,589 15,095 9.50 Lines of Comment 1,063 7,566 7.12 Comment + Code 2,652 22,661 8.54 Comment/Code 0.66 0.50 N/A 174

14000.0 Flog 10500.0 7000.0 3500.0 0.0 Minitest RSpec 175

30,000 Lines of Code Lines of Comment 22,500 15,000 7,500 0 Minitest RSpec 176

177

TEST TEST TEST TEST 177

TEST TEST TEST vs TEST 177

TEST TEST TEST vs TEST 177

Many people find it to be overkill, though, and there is an added cognitive cost to the extra abstractions. Myron Marsten, from previous post 178

Not just cognitive! 179

Performance differences with RSpec 180

All those abstractions? 181

Reinventing the wheel? 182

Has a Real Cost 183

Combined RSpec Results Combined Minitest Results 100.00 pos rs time 1neg rs time 50neg rs time 100neg rs time pos rs memory 1neg rs memory 50neg rs memory 100neg rs memory 300.00 1.80 pos mt time 1neg mt time 50neg mt time 100neg mt time pos mt memory 1neg mt memory 50neg mt memory 100neg mt memory 100.00 75.00 225.00 1.35 75.00 Time (s) 50.00 150.00 Memory (MB) Time (s) 0.90 50.00 Memory (MB) 25.00 75.00 0.45 25.00 0.00 500 1500 2500 3500 4500 5500 6500 7500 8500 9500 0.00 0.00 500 1500 2500 3500 4500 5500 6500 7500 8500 9500 0.00 # tests # tests 184

Combined RSpec Results Combined Minitest Results 100.00 pos rs time 1neg rs time 50neg rs time 100neg rs time pos rs memory 1neg rs memory 50neg rs memory 100neg rs memory 300.00 100.00 pos mt time 1neg mt time 50neg mt time 100neg mt time pos mt memory 1neg mt memory 50neg mt memory 100neg mt memory 300.00 75.00 225.00 75.02 225.00 Time (s) 50.00 150.00 Memory (MB) Time (s) 50.04 150.00 Memory (MB) 25.00 75.00 25.06 75.00 0.00 500 1500 2500 3500 4500 5500 6500 7500 8500 9500 0.00 0.08 500 1500 2500 3500 4500 5500 6500 7500 8500 9500 0.00 # tests # tests 185

But Ryan... 186

Who cares? 187

Passing rspec is fast enough 188

Bug? 189

Bug? Refactor? 189

Bug? Refactor? Anything else goes wrong? 189

You Pay 190

For Completeness: 191

Minitest vs RSpec, time & memory (assertions) 0.60 mt time rs time 0.45 Expectation Time (s) 0.30 0.15 Speed 0.00 1000 6000 11000 16000 21000 26000 31000 1 test, # assertions 36000 41000 46000 50000 192

Minitest vs RSpec, time 9.00 6.75 mt time rs time Method Time (s) 4.50 Execution 2.25 0.00 1000 5000 9000 # tests, 0 assertions 13000 17000 21000 25000 29000 33000 37000 41000 45000 49000 193 Speed

Linear 194

Don't reduce examples or expectations 195

If you want a speed up 196

Switch to minitest 197

Or never, ever refactor. 198

Summary 199

At the end of the day 200

As long as you test 201

I don't care what you use 202

Use the best tool for your job 203

Hopefully, I've shown 204

The technical merits of Minitest 205

Choose what works for you 206

Not because it seems popular 207

Maybe there's fewer articles about MT because there's less need for them? 208

MT is much easier to understand. 209

MT users aren't missing. 210

They're busy Getting Stuff Done. 211

Choose what works for you 212

Who knows? 213

Try It 214

You might like it 215

After All 216

It's Just Ruby 217

Thank You 218

Thank You (hire me) 218