[HN Gopher] History of RSpec ___________________________________________________________________ History of RSpec Author : todsacerdoti Score : 68 points Date : 2021-05-09 18:05 UTC (4 hours ago) (HTM) web link (www.stevenrbaker.com) (TXT) w3m dump (www.stevenrbaker.com) | azangru wrote: | > An early mentor of mine, who I do not name here because he has | proven himself to be a self-centred and generally abhorrent | individual | | Ouch! | gamache wrote: | I never met Sapir or Whorf. My hypothesis is that libraries like | RSpec which offer a thin "rephrasing" veneer over the assertion- | based test module are a waste of mental capacity (and this goes | triple for Cucumber and other similar regex-based trash). | | The specification goes in the test title and if necessary, a | comment. Then the programmer writes code to test the spec. I've | never understood what is suboptimal about this. Why do developers | need to be tricked? | bhaak wrote: | This doesn't sound like you ever programmed RSpec tests? | | Edit: To expand on that. I thought I knew and understood the | model-view-controller having only read about it. But only when | I actually used it in early RoR version I truly understood what | kind of advantages and disadvantages this approach had. | | The article explains the reasoning of RSpec and I'd say it | should answer your questions. | judofyr wrote: | > The specification goes in the test title and if necessary, a | comment. Then the programmer writes code to test the spec. I've | never understood what is suboptimal about this. Why do | developers need to be tricked? | | I think there's a combination of things in play here which | caused RSpec to take off: | | - RSpec's matchers were a bit more expressive than the built-in | assertions. This meant not only that you could write | "should_be_greater" and when an error occurs it would present | it in a much nicer way ("expected result to be greater than X, | got Y") than the simple "assert". | | - For many people when getting started with TDD/BDD it _does_ | help to start from a library /toolkit which has the concepts | built-in. A good example is being able to actually write full | sentences for the test name instead of being forced to | summarize in snake_case. | | That said, I do find the current RSpec expectation syntax to be | annoying and over complicated. And that's not because I don't | like DSL, but because I think that this DSL is focused on | making it readable as an English sentence instead of trying to | build its own language with its own primitives. | | Example: expect(result).to eq(3) | | - `eq(3)` I can understand: This creates an assertion. This | knows how to validate the value and how to format the error | message. Having these as standalone objects seem to allow some | pretty cool usages. | | - However, what is expect()? What does it return? What does | that object represent? Why is there a to() method? What other | methods are on `to`? It seems to me that this could have been | solved by a single method: expect_match(result, eq(3)). Yes, it | doesn't read as an English sentence, but it's easy to | understand the components: You have the assertion which is a | standalone object, and then you have the `expect_match` which | checks a result against that assertion. `expect_match` belongs | to the test runner because we want it to fail the test if the | assertion fails. | | And when you look at comparisons it's even worse: | expect(actual).to be > expected | | I've been writing Ruby for over 10 years and immediately I | struggle to parse this line. I guess `be` is a local method | (coming from what module?) which returns an object whose only | purpose is to convert operators into an assertion? To make | things even more confusing, you can also write | `expect(actual).to be`, but that is something completely | different (it passes when the result is truthy). | | And here's the problem: The be() method doesn't actually serve | any useful purpose in the "language" of matchers. It doesn't | provide anything that couldn't have been accomplished within | the existing framework. It's only there as a placeholder to | make the whole expression read as an English sentence instead | of `expect_match(result, gt(3))`. | masklinn wrote: | > It seems to me that this could have been solved by a single | method: expect_match(result, eq(3)). | | Except now you've circled back to the issue rspec originally | tried to solve: getting the result and the reference in the | correct order. | | While I care very little about rspec, that is definitely one | thing to be said for it: the matcher system makes it | extremely obvious and regular: you `expect` a (result) to | (match) a (reference). | 8fGTBjZxBcHq wrote: | Honestly I just like the flow of it a little more aesthetically | and I've never been so restricted on mental capacity that I | noticed the extra burden. Condolences though. | nitrogen wrote: | _Why do developers need to be tricked?_ | | 1. Variations in preferences. Given that every brain is | structured a bit differently, and that every person has | different backgrounds and experiences, it's reasonable to | conclude that different syntax or vocabulary will make things | "click" for different people. This is evidenced by the fact | that there is more than one programming language in daily use. | | 2. Cognitive burden. We're all smart enough to learn whatever | syntax, framework, or vocabulary is necessary to accomplish a | task. But if there is a different way of structuring common | tasks that flows better for someone, then choosing that flow | over something more traditional frees up that tiny extra bit of | mental effort for other tasks. These optimizations accumulate, | so even a very smart person can benefit from doing easy things | in the easiest way for them. Then, teams benefit on top of that | from the reduced communication burden. | blacktriangle wrote: | I'm right there with you on RSpec. We're programmers, we think | in code, we think in the native primitives of the language. Now | you bring in RSpec equality and comparison operators and I have | to go look up RSpecs semantics vs just leveraging all my | existing Ruby knowledge. | | Cucumber otoh is an absolutely amazing tool...in the correct | organization. When used as it was designed, ie analysis's | working with stakeholders to gather requirements which can then | be turned into executable tests for the developers to conform | with is amazing. Its when developers start writing cucumber | features without talking to anybody else that the whole thing | becomes pointless. | jph wrote: | RSpec, Minitest, and Cucumber have a huge history in bringing | Test Driven Development (TDD) and Behavior Driven Development | (BDD) to many developers via Ruby on Rails. All three have | fascinating interactions with language and psychology. | | I believe there's an excellent masters thesis to be written that | investigates the histories of these 3 tools and their adoption | curves. | | The history that I've seen is teams doing 4 steps: try RSpec and | love it, try Cucumber and hate it, try Minitest and eventually | favor it over RSpec because of directness and refactorability, | then much later on revisit Cucumber for inter-team business specs | and love it. | | Along the curve, some teammates would express strong preferences, | some wouldn't care much, and some would actively say only one was | the One True Tool. Areas like this-- much like vim vs. emacs-- | fascinate me because they hint at deep ways we think about code | and work. | nitrogen wrote: | RSpec was the first testing system that "felt right" to me. I had | previously hand-rolled things in C and shell scripts for my C | projects, and used a bit of JUnit, but for whatever reason the | ease of just typing "rspec" and the language change to | expectations instead of assertions was a lot more comfortable. | | So, thanks Steven R Baker and everyone else for making software | better tested and more reliable. | faitswulff wrote: | > I also thought (naively, the historical record has shown so | far) that RSpec wasn't going to be the only lasting contribution | I made to the software industry as a whole. I was insistent, in | 2007, that I wasn't going to be a One Trick Pony. I still like to | hope that I have many tricks left in me, but I'm less confident | that I will be able to move the needle again in a similar way. | I'll be honest: this fact has caused me a lot of sadness over the | years. | | It's humbling to see the creator of a widely used and loved | library express these vulnerable - and relatable - thoughts. | Thank you for RSpec and all that you do, Steven. It changed so | many people's lives for the better. We all do what we can. | barrkel wrote: | Impact is really about being in the right place at the right | time with the right skills. | | If you don't have the skill to find another place and time - | and it is a different, distinct skill which can depend on | social and economic capital for the search - the one chance may | be all you get. It doesn't necessarily speak to your capability | or lack of it. For most of us, it's luck. | LAC-Tech wrote: | Really enjoyed this article. Fascinating to see the resistance to | testing back when he started, and how he used a bit of clever | marketing to change the way people thought about it. | | Interesting that he's very happy with | expect(expected).to.equal(actual) | | I wonder if `assert` or `check` or even `test` makes us think | differently about what we're doing (in the assertion itself, not | in the method name to set up the test). | cxf12 wrote: | The instant I read this headline I thought... Ruby on Rails. | yeskia wrote: | So? | colonwqbang wrote: | I always found it a bit useless to be fussing over phrasing like | this. What does it matter if we call it | | expect(x).to(equal(y)) | | or | | x.should_be(y) | | or | | assert_eq(x, y) | | These are just different ways of saying the same thing. The first | two aren't really better than the last at conveying what's going | on. | | Although I like Ruby and Rspec, this desire for "beautiful code" | and "making the code read like English" never rhymed with me. | masklinn wrote: | > The first two aren't really better than the last at conveying | what's going on. | | Though I've never really liked the verbiage, TFA does correctly | remark that it guides towards the correct parameter ordering in | ways `assert_eq` does not. And depending on the way assertion | errors are formatted, getting the ordering wrong can lead to | odd / awkward messages. | | 'course these days I use pytest which just asks for an `assert` | and takes care of taking apart the expression being asserted, | so it's a non-issue. | kofejnik wrote: | yeah, could never understand what's wrong with assert(x == y). | Why learn yet another awkward DSL on top of all other DSLs and | hidden conventions, which RoR already has a lot (which kind of | turned me away from it) | tmp538394722 wrote: | The first 1/3 of the article explains their historical | motivation for this approach and specifically why this was a | breakthrough for teaching. Names can matter. | | And from a more practical standpoint, RSpec is now much more | than just a different mapping of some key words. | | the DSL rspec landed on can be _very_ concise, which I | appreciate. This is mostly made possible by Ruby's short block | syntax and the ability to nest them. | | One thing this enables is an easy way to define a hierarchy of | concerns with their own nested setup/tear down blocks, which | allows you to easily share code across similar example groups. | | This is nice in and of itself, but it also leads you to | differentiate the "boring setup" code from the "here's the part | I'm actually testing code" which is helpful for clarity when | coming back to old tests. | | These things are sharp knives and can be used poorly, but I've | never yet found a system I like better. | notsureaboutpg wrote: | "making the code read like English" is what doomed Semantic UI. | There was a brief period of popularity for it, but looking at | all the popular Bootstrap-type libraries now, none of them try | to be "semantic" or "read like English" | | Because at the end of the day the function of the code is not | the function of speaking or writing the English language. | | Styling front-end components does not work like the English | language works. I can call something "big" in English and | everyone knows what I mean, but the browser will determine what | an element having the "big" class means based on the context of | its parent elements and its children elements. That difference | makes it extra confusing to use code that's trying to be | "semantic" especially if the "semantics" are trying to hide | more expressive and complicated functionality from the user. ___________________________________________________________________ (page generated 2021-05-09 23:00 UTC)