Tdd for the iPhone: Continued 368
After a week in Israel and the UK, I got back to this series. I’ve switched to using XCode 4, but as it is not officially released, the videos I recorded using it were a bad idea to upload.
Back to XCode 3: http://www.vimeo.com/album/1472322
iPhone and Tdd: The Video Series Begins 261
http://www.vimeo.com/album/1472322
Title says it all. Well, I’ll add that this was take #20 (or so). It’s rough getting back in to video recording mode. I will do more in this series.
And I barely know Objective-C, so as the series progresses, I’ll expect some help on better practices.
Info Please: Tdd and Pair Programming 281
I often get asked to provide background materials on TDD and Pair Programming.
Here are a few I often cite, but can you point me to some more? Are there any that you particularly like/dislike?
I would like both for and against. I prefer research or experience rather than rants, though if the rant is funny…
Thanks!
—
(This is taken from a recent email I sent.)
Start Here
- http://en.wikipedia.org/wiki/Pair_programming
Good overview and sites studies.
Then here
- http://accu.org/index.php/journals/1395
A 1975 study of “two-person programming teams” reported a 127% gain in productivity and an error rate that was three orders of magnitude less than normal for the organization under study. [Crosstalk]
Pairing in Education
- http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.89.6834&rep=rep1&type=pdf
Other Articles
- http://www.stsc.hill.af.mil/crosstalk/2003/03/jensen.html
iPhone Development with Unit Testing 263
I’m finally getting back to iPhone development. The environment is taking some getting used to and it took me some time to get to a reasonable working environment.
I’m starting to document that. I plan to have both written and video tutorials. For now, I’ve got some rough notes put together. Have a look and feedback is appreciated: http://schuchert.wikispaces.com/iPhone.SettingUpTheEnvionment
CPP And OOD: The Least You Need To Know 273
I’ve put what I’ve been writing up, available for free. Not sure if I’ll ever try to get it published dead-tree form.
http://schuchert.wikispaces.com/cpptraining.CppAndOodTheLeastYouNeedToKnow
Feedback appreciated.
Have a great weekend.
Quick Intro To BDD Style Table Syntax 286
Here it is a over a year after I wrote several FitNesse tutorials. Several months back Bob added some new ways to write scenarios using a placeholder syntax and an alternative way to render script tables. What you end up with is something just a little less table-like.
This is a very quick and dirty writeup I’ve been meaning to put together for nearly half a year. So while it’s not pretty, it works, shows the basics and may make you aware of something you didn’t know was there – unless you’ve been reading the release notes.
Alternative Script Table Syntax
Comments and requests welcome.
Brett
Selection of tools for otherwise free content, Your Opinion 154
The Question
Should I be concerned that free content I release on my wiki, or the videos I release, use paid-for tools?I expect people will also answer a secondary question: which tool I should use for Ruby. I’m interested in that as well, however my primary question is the general one of whether I should stick to free tools for the free content I release.
The Background
I’m planning on recording a few BDD videos for Ruby and I’ve hit a bit of a roadblock.- Eclipse Helios doesn’t cut it for running RSpec out of the box
- I understand that The Aptana plugin might support RSpec, however in the past when I’ve used that plugin, it felt like kudzu
- IntelliJ 9.0.3 doesn’t seem to work out of the box either
- RubyMine works out of the box, but it’s not free
- RubyMine Early Access Program is free, but neither stable (less of a concern) nor long-lasting (I assume the license to use it expires)
- I’m not familiar with another cross-platform option for tools other that vi/emacs(I’m a vi user)
At least for the stuff I typically release that is. If it were just some video I expected people to watch and not replicate, then I’d be less concerned about the toolset. However, I hope people will use what I’ve released by attempting to replicate it. I don’t want people to have to buy tools to replicate free material. The one exception I can think of is using ReSharper for .Net-baed languages. Since people are already paying big $$ for the IDE in that case (mono developers probably excluded), adding ReSharper doesn’t seem like a big deal.
Since I’d like people to have the option of “repeating the experiment”, the tool selection adds another dimension of importance to me. Should it be? If I were working on a product, I’d consider tool cost a wash. If something will make me more productive and I’m going to be working on it for more than a few weeks, that justifies a tool purchase. I’ve personally spent $$ to make myself more efficient when I could not get my company/customer to pay for a particular tool. But this seems different. It seems like a barrier to entry.
Question Repeated
So what’s your opinion? If I’m releasing something for free, should I strive to find a decent toolset that’s free?And I’m also interested in the implied question: What toolset should I use? Can you recommend a toolset that will work on OS X, Linux, and Windows XP/7? I’ve got the command line already and vim. If you can recommend free tools to make that better, I’d like to hear it. If you can recommend something that works for either Eclipse or the community edition of IntelliJ, that’s fine as well. Should I give Aptana another try? Does is RadRails plugin not take over Eclipse?
The 4-contact points of software development 178
- Write no production code without a failing test
- Write just enough of a test to fail
- Write just enough production code to get the test to pass
This list doesn’t include refactoring, which is typically an assumed activity. In fact, some people refer to these rules as “red, green, refactor”. An even older version of this, from the Smalltalk community, is Red, Green, Blue. (Why Blue for refactor? I think someone was thinking RBG for a color space, luckily they didn’t try to use CMYK or LAB!)
In this simple model, there two kinds of code: test & production. There are two kinds of activity: writing & refactoring. Interestingly, at one level it is all code. The thing that distinguishes both sets is intent.
The intent of a test is to demonstrate or maybe specify behavior. The intent of production code is to implement (hopefully) business-relevant functionality.
The intent of writing code is creation. The intent of refactoring code is to change (hopefully improve) its structure without changing its behavior (this is oversimplified but essentially correct).
If you mix those combinations you have the 4-limbs of development:- Writing a test
- Writing production code
- Refactoring a test
- Refactoring production code
An important behavior to practice is doing only one of these at a time. That is, when you are writing tests, don’t also write production code. Sure, you might use tools to stub out missing methods and classes, but the heart of what you are doing is writing a test. Finish that train of thought before focusing on writing production code.
On the other hand, if you are refactoring production code, do just that. Don’t change tests at the same time, try to only do one refactoring at a time, etc.
WHY?
First an analogy that almost always misses since most developers don’t additionally rock climb.
When rock climbing, a good general bit of advice is to only move one contact point at a time. For this discussion, consider your two hands and two feet as your four contact points. Sure, you can use your face or knee, but neither are much fun. So just considering two hands and two feet, that suggests that if, for example, you move your right hand, then leave your left hand and both feet in place.
This gives you stability, a chance to easily recover by simply moving the most recent appendage back in place and, when the inevitable happens, another appendage slips, you have a better chance of not eating rock face. If you move more than one thing at a time, you are in more danger because you’ve taken a risky action and reduced the number of points of contact, or stability.
Will you sometimes move multiple appendages? Sure. But not as a habit. Sometimes you need to take risks. The rock face may not always offer up movement patterns that make applying this recommendation possible. Since you know the environment will occasionally work against you, you need to maintain some slack for the inevitable.
Practicing Test Driven Development is similar. If you change production code and tests at the same time, what happens if a test fails? What is wrong? The production code, the test, both, neither? An even more subtle problem is that tests pass but the test is fragile or heavily implementation-dependent. While not necessarily an immediate threat, it represents design debt that will eventually cause problems. (This also happens frequently when tests are written after the production code as it’s seductively easy to write tests that exercise code, expressing the production’s code implementation but fundamentally hiding the intent.)
Notice, if you had only refactored code, then you know the problem is in one place. When you change both, the problem space actually goes from 1 to 3 (4 if you allow for neither). Furthermore, if you are changing both production and test code at the same time and you get to a point where you’ve entered a bottomless pit, you’ll end up throwing away more work if you choose to restore from the repository.
Are there going to be times when you change both? Sure. Sometimes you may not see a clear path that gives you the option to do only one thing at a given time. Sometimes the tests and code will work against you. Often, you’ll be working in a legacy code base where there are no tests. Given that the environment will occasionally (or frequently) work against you, you need to maintain some slack.
Essentially, be focused on a single goal at any given time: write a test. then get it to pass. clean up production code & keep the tests first unchanging and then passing.
I find that this is a hard thing both to learn and to apply. I frequently jump ahead of myself. Unfortunately I’m “lucky” enough when I do jump ahead that when I fail, I thoroughly fall flat on my face.
This approach is contextual (aren’t they all?). Every time you start working on code, you’ll be faced with these four possibilities. Each time you are, you need to figure out what is the most important thing in the moment, and do that one thing. Once you’ve taken care of the most important thing, you may have just promoted the second most important thing to first place. Even so, reassess. What is the most important thing now? Do that.
Good luck trying to apply this idea to your development work. I’m interesting in hearing about it.
Is it worth killing trees over another C++ Book? 152
I’ve taught a few C++ courses recently to people primarily moving from C to C++. I know C++ has been around for years and it’s not in vogue like it was 15 years ago. I stopped using it full time in 1997. Even so, there’s been quite a bit of work on the library and language standard. And there are still a lot of places developing new systems with C++. I know some people are still be learning C++ in school.
In my most recent classes, I’ve been teaching students who have recently taken a class on OO A & D based on the work of Craig Larman. The C++ class attempts to follow that class by dovetailing into what it covers. Because of this, I did not use ObjectMentors’ standard C++ and OOD class. Good as it is, it has different starting assumptions. I instead wrote a class, using two problems as the entire basis of all the material I cover. I know, “not build here syndrom.” It pained me to do this, I did my research and I considered retro-fitting the OM course. The discrepancy was too large to consider reuse. And refactoring the existing class to accomodate changes, which I also considered, wasn’t practical. Looking back I made the right decision.
So this course has a few key design elements:- Problem focused
- Test oriented (sometimes test-first, other times test-driven, occasionally refactor-oriented)
The problem-focus limits the topic coverage. If something about the language doesn’t come up somewhat naturally (not contrived) in the two projects I use, I don’t cover the material. For example, I don’t mention placement new, I only cover Multiple Inheritance if asked about it. I also try to focus on classes in the standard library. For example, std::array, std::vector, std::map, std::shared_ptr.
Additionally, there’s an early focus on testing. That’s another thing that’s different from how I taught C++ say before 1995 – I really didn’t teach it from 1995 – 2007, so no comments on what I might have done differently in that span of years.
To give you an idea of how early the focus is on test, I only show cout if asked. The first main() calls CommandLineTestRunner::RunAllTests and everything after that runs within a unit test. the last time I taught the class, I demonstrated tests executing with cslim, but still, a test focus.
I have them use unit tests as a way to experiment with the language. In one example, I have them write tests that force a method to become virtual that was not virtual before. In another case, I do the same thing with a virtual destructor. I have them test from raw pointers into shared_ptr and then update their code accordingly.
Because of the test focus, I make certain recommendations that impact overall class design. That means learning C++ with designs supporting testability early on. In C++ this means (among other things):- Dependency Injection (OK, this is not just C++)
- Virtual functions and by corollary a virtual destructor
- Storing pointers because 1. calling methods through an auto object are not virtually dispatched, and 2. you cannot put references in the standard collections
- Use std::shared_ptr to avoid memory leaks, which are detected by the unit testing tool I have them use.
I take the class to a certain level, but I make it clear I’m just scratching the surface. I believe it’s not really possible to learn C++ in a 1-week class. You can get the beginnings of proficiency and be in a good position to continue learning – that’s an assumption I state up front after the students have had their first exercise – about 5 minutes into the start of the class. I try to only go into detail as the students ask questions, but at times I just want to really open up the beast and get into what’s really happening.
To address this, I’ve started novelizing the class I’ve been teaching. I’m following the same outline as the class, but I dive under the surface and at times get to quite a bit of detail that I would not typically get into in a 4.5 day class.
I know this material will augment the class. This will give my students three sources of information:- The class itself, which is exercise-driven
- Online videos
- A novelization of the class, going into much more detail
The thing I’m wondering is, would the book be worth making more generally available? I’m writing it so that it can stand on its own. There’s a certain advantage to knowing my students have taken the previous OO A & D class I mentioned because it uses a problem that I’ve used on and off since 1992. This allows me to give examples from a problem they have looked at in the past and then at the current problem. I’ve not yet made references to that problem in the book I’m writing. I could, I just have not done so yet – it’s more natural in the second problem and I’m still working on the first problem (and therefor the first half of the book). I’m certain I can make those references without the previous class experience. (It’s the Monopoly problem.)
In any case, I need to do some research. If I do start the publishing process, a key step involves competitive research. Can you recommend any books published for the first time this century (really in the past 7 years) that have any of these characteristics:- Cover a minimal set of C++, enough for decent OO solutions
- Have any kind of emphasis on test – at least half the book?
- Cover the language strictly through a problem-based approach rather than from a language perspective?
- Involve deliberately making mistakes and observing those mistakes to learn how the language works?
Additionally, can you recommend any great C++ books? I can list many of the ones I’ve read and enjoyed, but the last time I bought a book for myself on the topic, Amazon did not exist as an online company.
Independent of whether I deal with trying to get this thing published as a printed book, I’m going to finish it because I think it will be useful to my students. I suspect I’ll be teaching this class in the future, so I will find it useful in the future as well. If I don’t attempt publishing it through a major publisher, I’ll put it on my wiki at the very least. Though it’s going to be quite a bit more effort than my typical wiki articles.
But the question I keep coming back to, is this: Is there really a need for this book dead tree version, or it is primarily useful as supplemental material for a class I teach?
I’d like to hear your opinions.
Game Of Life with @lunivore 179
At the #coderetreat in Orlando I spent an hour programming with @lunivore (Liz Keogh). We worked in Clojure on Conway’s game of life. It was quite an experience!
Liz was not very familiar with Clojure, so I felt I had the advantage. Wrong! By the end of the hour she had taken charge and was programming rings around me. It was a lot of fun; if a bit humbling.
Liz came into the session knowing the structure of the algorithm she wanted to implement. She just didn’t know how to implement it in Clojure. When the starting gun was fired, she showed me a picture of a glider (a standard form in life) and said she wanted this to be the acceptance test.
During the session we wrote only a very few unit tests, each very focussed on one particular part of the problem. The size of the steps was considerably larger than I am used to in Java or Ruby; yet it didn’t seem to matter. Writing functions in clojure is easy, and apparently far less error prone.
We finished 10 minutes before the end of the session, and had some time to refactor.
I’ve posted the code below. I’ve cleaned it up a bit (being unable to leave it alone); but the algorithm remains the same; as are the tests.