"How I Learned to Love Testing" presentation
by g on Oct 03, 2017
A few months ago I really hated the idea of testing my code, I just didn't do it. Now I couldn't think of writing a line of code without the proper tests in place.
If you fall into either of these boats you may want to watch this presentation I put together for the Orlando Ruby Users Group. Feedback and comments are always welcome.
View Video Presentation - 30 mins
- Why would you test your code?
- When do you test your code?
- The path to developer enlightenment
- Test Driven Development (TDD)
- Behavior Driven Development (BDD)
- Where'd RSpec come from?
- Running Autotest with Growl
- Live screencast of BDD with Rspec
- What are stubs and mocks?
- How to start testing your code?
Here is the textmate command I use in the video to convert my specifications into RSpec format. Yaml to RSpec.
- Rspec Homepage
- Behavior Driven Development Wiki
- Introduction to RSpec by David Chelimsky
- Why use RSpec - BDD
- Rails With RSpec
- TDD Adoption steps
- Dave Astels announcement of BDD
- the Coad Letter
- BDD is Kinkier then TDD
- Good talk with Dave Astels and Steven Baker
Sorry, comments are closed for this Post, but feel free to email us with your input. We'd love to hear it.
Hey, thanks for sharing the presentation. I’m definitely in the no testing is good testing camp right now, but have that nagging feeling I should be doing more.
Problem is, I keep bouncing off of the code complexity issue.
When coding up a model object, I have to get the interface right, get the internal representation & DB schema right, the code has to handle errors & bugs, etc. etc…
Now, I add testing on top. Not only do I have to do all those things, but I have to now build a whole suite of Mock & Stub objects, and write tests that are in some cases just as hard to come up with and get right as the code I’m testing.
Ok, fair enough, there are some good reasons to do this. BUT, when I want to change something later, I now have two points of failure - the code I’m changing, and all the tests that depend on that code. I haven’t really bought myself all that much security, because if my tests don’t catch the problem well, I’m just as hosed as if I had no tests.
So write good tests, you say. But half my testing behavior is stubs and mock objects! How do I keep them in sync with reality? How do I find all the places I put in a mock for the model I’m redesigning. And don’t I just have to basically duplicate a lot of code and effort to re-synch those items?
I feel like test driven development is focused on the early design phase, but in time would end up consuming more and more of my development effort, without necessarily buying me much.
Sometimes it’s nice to end your day with one failing test. Not a horribly mangled half-finished one obviously, but just a clear bookmark to yourself about where to start working when you pick up a project again.
As for the guy commenting above me, Robb, I think it helps to realize that your code and your tests are not two distinct parts of your application, with code being the only truly important thing. Those two pieces come together to be your application. A lot of refactoring can be done without modifying test code, but some redesigns are going to require changes in both areas as part of the evolution of the entire application. I can say this with certainty: Once it becomes habit, your testing is not going to be the thing holding you back from making application changes. People throw around the term “fearless refactoring” a lot when they talk about well tested code, and it’s true. You can make changes with confidence.
You may also be interested to know that there’s nothing in RSpec forcing you to use mocks. It fully supports fixtures, and/or using your actual model objects. It’s encouraged to use mocking, but if it helps you get your foot in the door to use actual model objects in your tests, you can. Any testing is better than no testing!
Good questions. There are lots of answers.
The reasons you need stubs and mocks is so you can isolate your tests. Your controller tests should only test your controller. If your controller test hit your model, and they fail, there’s no way to tell where they failed. Plus, each test you write should only test a single piece of functionality (usually a single line of code).
There are several huge benefits to having an application with 100% test coverage.
You can refactor and improve your code without worrying about breaking things in 6 places. It’s really amazing how much I take risks in my code now that I have tests in place. Where I used to thing “Well, I know writing it with 8 lines of code will definitely work”.. now I think “I wonder if I can do this in 4 lines, and keep it readable.” I take risks, try new techniques, and I immediately know that they work when all my tests pass.
The amount of time you spend debugging problems in a web application without tests is about 3x the amount of time you spend writing tests. It’s one of those things that doesn’t payoff until you’re late in development.
We in the Agile world are more then aware of the fact that code changes and evolves. We’re asked by our clients to make lots of little fixes here and there. Without tests in place, every time I make a change I’m taking a BIG risk that I’m going to break things. If I have tests in place, I’m less likely to break things, and I’m going to be happier, and my clients will be happier with my work.
Just a few reasons.. I’m sure I could go on.
My comment got so large, I decided I really should be blogging it myself. :)
To summarize, I wish TDD proponents (and toolmakers) addressed later stages of projects, instead of focusing on project start.
Great things about rspec, didn’t know much about it before.
After I install the plugin I still cannot use the generator like you did?
ruby script/generate spec anything Couldn’t find any ‘spec’ generate?
Usually each test should only test a single line of code? Are you serious? So if you have a codebase of 1M lines, you expect to have roughly 1M tests? Shouldn’t you try to stick the test together with the actual lines of code then?
In a typical well tested application you will actually have MORE lines of testing code then application code. This is a good thing. This is why when you run “rake stats” your application gives you a code to test ratio.
Code LOC: 2076 Test LOC: 3453 Code to Test Ratio: 1:1.7
That’s from one of my recent applications. I took a lot of pride in showing that to the client. If you follow RSpec conventions you’ll have several specs which go through each function, and each spec tests one thing, just as I showed in the screencast.
Maybe this will convince me to write a test. Not even lying, I have an app deployed right now and I don’t even know how to write a test or even what the significance of them is. Listening to the first part of this presentation, I don’t feel so bad about it.
I was so sick of everyone yapping to me about testing.
I knew the day would come when someone would convince me otherwise. Not only am I convinced that testing is the way forward, but it actually makes coding so much easier and more enjoyable!
Thanks a lot !
Really great episode! Now Im trying to get the that neat little script working that converts a list into rspec syntax, but Im getting a bunch or error messages when I press the shortcut to convert: “/bin/bash: line 1: require: command not found….etc” I have “Ruby on Rails” selected on the bottom.
Make sure you copy the WHOLE script… not just the part where the code starts. The first #! line tells textmate it’s about to run a ruby script.
I copied the whole script and now Im getting the error: “env: ruby: No such file or directory”.
I tried it both with .yml and .txt files with “Ruby on Rails” selected.
Does something need to be entered into “Scope Selector” in the Command Editor window?
Kristen, My first guess would be that your environment isn’t aware of a ruby interpreter. Perhaps make sure your .bash_profile has ruby in the PATH?
Otherwise I’m out of ideas.
Rob (way up there…)
Your confidence is admirable. But for any given chunk of code that you write, on what do you base your confidence?
I had the code tweaked and it is working now.
I am having similar problems that Kristen is having…my interpreter is in /usr/local/bin so i changed the shebang line to reflect that, but I get access denied…
Thanks for posting this! It was very informative.