TDD is wasting time if... 149
You have no design sense.
OK, discuss.
Parts 5 and 6 of the 4-part series 49
The title says it all. I was bothered by a few things in the Shunting Yard Algorithm (actually many more things), but I felt compelled to fix two of those things.
So if you have a look at the album, you’ll notice 2 more videos:- Video 5 of 4: Remove the need for spaces between tokens.
- Video 6 of 4: Remove duplication of operators in algorithm and tokenizer.
Hope these are interesting or at least entertaining.
C# TDD Videos - You asked for them 161
Several people asked for them, so here is a series of 4 videos. The first series on the RPN calculator in Java was a bit rough, these are even rougher.
Even so, hope you find them valuable.
Shunting Yard Algorithm in C# Video Album
Comments and feedback welcome.
First Pass Completed: Rough Draft TDD Demonstration Videos 123
As promised, I’ve made a complete sweep through a series of videos. You can find all of them: here.
These videos include several warts and false starts. Depending on the interest and feedback, I’ll redo these at some point in the future.
Question: Should I repeat this series in C#, or some other language? Some people have expressed interest in this. It’s probably 15 hours of work in C#, so I’d need to know it was worth the effort. What’s your opinion on that?
- Getting Started
- Adding Basic Operators
- Removing Duplication
- Extracting to Strategy
- Removing Duplication via Refactoring or Removing Duplication via Tdd using Mockito
- Introducing an Abstract Factory
- Adding a Sum operator
- Adding Prime Factors Operator
- Composing Operators and Programming the Calculator
- Using FitNesse to Program the Calculator
I’ve already received several comments both here on the blog as well as with the videos. I’ll keep track of those comments and incorporate the ones that fit for me.
Each video has a link on its page to download it. However, to download a video, you will have to create an account and log in. So here are the links, these won’t work without first creating an account (I’ll update original blog with these as well):- Getting Started Download
- Adding Basic Ops Download
- Removing Duplication Download
- Extracting to Strategy
- Removing Dups/Refactoring Download
- Removing Dups/Tdd Download
- Abstract Factory Download
- Sum Operator Download
- Prime Factors Download
- Composing Math Operators Download
- Using FitNesse Download
Some Rough Draft TDD Demonstration Videos 192
I’m doing a series of videos on TDD. The ultimate result will be a much more polished version with embedded slides, and such. But as a part of the development process, I’m creating scratch videos.
Much of what you see in these videos will be in the final versions, but those are far in the future relative to this work.
Hope you find them interesting.
Comments welcome.
Here is what is already available:- Getting started
- Adding Operators
- Removing violation of Open/Closed principle
- Removing duplication in operations with a combination of the Strategy pattern and the Template Method pattern
- Adding new operators after the removal of duplication.
- Reducing coupling by using the Abstract Factory pattern, Dependency Inversion and Dependency Injection
- Adding a few more operations
- Allowing the creation of complex “programs” or “macros” by using the Composite pattern – and avoiding Liskov Substitution Principle inherent in the GoF version of the pattern
- Driving the calculator via FitNesse + Slim
Anyway, that’s the plan. I’ll try to add each of these videos over the next few weeks.
Getting Started in Objective-C with XCode 228
As I mentioned in a previous previous blog, I wrote up some notes on getting started practicing TDD using XCode and Objective-C. I’m intending to write a bit more, so the top level of the overall tutorial path starts here: A First Objective-C Project
If you just want to see the details of getting started: XCodeProjectSetup
The biggest change from the previous blog is an embedded video demonstration. If you’re just interested in the video: Getting started
Want to seem more? Something in particular? Let me know.
Comments welcome.
Is TDD Language Neutral? 116
I don’t think that it makes sense to say “teach a TDD class in several languages simultaneously”. TDD is a language-independent technique.
What follows is a slightly changed version of my response. What I’m wondering is this: Do you think the practice of TDD is fundamentally impacted by your programming language?
Read on for my response. You might want to add a comment before reading my response to avoid “group think.”
Based on the original comment, I started with: It seems to me that you’ve not written professionally in many different languages. Or if you have, you’ve not effectively used those different programming languages.
Now let me be a bit more clear. Java and C++ are different languages, to be sure. However, they are both class-based, statically typed languages without lambdas (well C++ and Java will both be getting them, but they don’t have them now).
Contrast Java and C++ with Smaltalk and Self. Smalltalk is class based and supports inheritance but it is dynamically typed. Self is object-oriented, but it does not have classes. In fact, it technically does not have inheritance, but it fully supports OOP. How? Delegation. JavaScript is closer to Self than it is to Smalltalk. But JavaScript, Self and Smalltalk are all closer than C++, Java, C# and Objective-C.
How about the Open/Closed principle? How I interpret that design principle depends on the context (language) in which work. In raw Java, what I think needs to be closed is different than say raw Ruby. If I add Aspect Oriented Programming into the mix (yes, I’ve actually written and deployed systems that used Aspect J – in a limited fashion), then that opens things up a bit, but still not as much as in Ruby.
In Smalltalk, the closest analog to static methods are class methods. However, a class method in Smalltalk is actually an instance method on a class object, which is a subclass of the Class class. (Yes, that’s what I meant.)
Why is this important? When I’m working with legacy code in C++/Java/C#/VB.Net – languages where static methods are never dynamically bound, I avoid using static methods and, in fact, I redesign using what Michel Feathers calls “Introducing an Instance Delegator”.
In Smalltalk, this technique is irrelevant and unnecessary.
In languages like JavaScript, Self, Smaltalk, Ruby, etc., interfaces are not really necessary. Sure you can use them, but they are more for documentation.
Consider templates in C++ versus generics in Java. In Java, generics experience type erasure so you often need to use interfaces with generics – or at least tell the compiler a type it can assume will always be used with a generic. In C++, the most you really need to do is let the complier know that a template parameter is a typename as opposed to a primitive. When the code is compiled, any implied requirements of the type parameter will either be satisfied or not. (Woe be it to you if they are not!)
Why? In Java, generics are syntactic sugar. C++ generates a unique class for each template occurrence. C# is much closer to C++ than Java in this respect. Java got it wrong (in my opinion) – though what they did add did improve the language a bit.
How about moving away from OO languages? Scala is a mixed language, as is F#. Haskel is not. Lisp as well. How you break a problem into parts is (or at least should be) different in these languages. I don’t mean different in syntax, to be sure it will be. I mean how you break a problem into its parts is fundamentally different in pure functional languages than OO languages.
Or consider COBOL. I’ve programmed in it. I can thank COBOL for my touch-typing skills. COBOL is yet a different kind of language. Yes, syntactically, but that’s not the interesting difference. COBOL is a record-oriented processing language. It is well suited to batch processing. AWK is similar in this respect as is SNOBOL. (I’ve used AWK quite a bit, and I’ve used a variant of SNOBOL called SPITBOL as well.)
Let’s continue with a building analogy. If all I have to build is bamboo then I have available to me certain techniques for building a house. If I have steel, I have different alternatives. The design of my house will be directly impacted by the media (language) available.
Additionally, if I’m building on clay versus bedrock, I will also make fundamentally different design issues. When I lived in Texas I had a floating slab foundation, which were common for several reasons: cost, temperature zone, available building materials. Texas was the first place I lived that did not in general have basements. The other option, pier and beam, was no longer practiced in general due to cost.
I’m originally from the Mid-West (Iowa). In Iowa, buildings are built such that their foundation is below the frost line. The frost line was something like 30” (I’m remembering something from 20 – 30 years ago). So all the houses had basements. Or if not basements, half-basements.
The same kinds of things can be said about programming languages as well as their ecosystems as well as the political environment. I’ve already made the language point above. But what about the political environment?
I have worked at places where open source was forbidden. So this rules out Hibernate and Spring. Taking away these tools does not stop me from building a system, but it does have an impact on gross assignment of responsibility, which is an important component of software architecture.
Now, back down to a TDD class. When I teach TDD, I am not teaching just TDD. Furthermore, I am not just talking about TDD. I want students to apply the practice. So I start with a problem – a requirements statement. That does not initially vary with the language. In practice it eventually does for several reasons:
- How far the class can get with the problem is impacted by by their skills as well as the programming language. C++ and vi are slower to work in that Java and Eclipse.
- What you can reasonably do is impacted by both the language as its environment. For example, it is easy to look at a DLL and dynamically find all concrete implementations of an interface in any .Net language. It’s harder to do that in Java, though possible. In C++ it is platform specific.
- There are more…
The students do need to learn the mechanics:
- How to write a test using a particular unit testing framework
- How to write production code
- The shortcut keys of the environment
- The refactoring support in the IDE
But what are the students testing? Units? Sure, let’s go there.
Language affects the units. You are testing units. Different kinds of units, different kinds of responsibilities. Different kinds of responsibilities to be verified, different unit tests.
Things are not so cleanly separated as you would like to imagine.
This very idea can be seen in natural languages. Different languages are better/worse at expressing things. The language you use directly affects how you interpret the world. This actually impacts the physical wiring in the brain. Really, it does.
So I do not agree.
And I challenge you to write the same problem in two fundamentally different languages (e.g. Java and Lisp) using TDD. Then have those two different solutions reviewed by experts in each of those languages.
I claim that if you’ve done an effective job of using those languages, your solutions will be different AND the unit tests you created to get to those solutions will be fundamentally different (not just mechanically different).
If, on the other hands, the unit tests are the same (other than the mechanics), then at least one group of people will say your solution is a bad use of their particular language. You’ll either be programming Java in Lisp or Lisp in Java.
Rudimentary TDD with XCode and Objective-C 155
- Java
- JavaScript
- C++
- Objective-C
In turns out that for what we teach in our TDD class, Java, C++ and Objective-C can be taught at the same time fairly easily. JavaScript, however, not so much. It is a very different (great, but different) beast.
In fact I could add C# to the mix as well, but I’d have to leave out LINQ and Lambdas.
In any case, to teach a class like that, I prefer to have the students do a bit of preliminary work so that they know how to set up their environments. When there’s just one language, I do this on the fly. But when there’s 3, I don’t want 2/3rds of the class waiting while 1/3rd learns how to create a basic project supporting TDD.
The last time I used Objective-C was in 1991, so I needed to figure out how to do this in the environment it is most likely to be used. This turned out to be a bit more work than I expected. I found it all using the good old google-machine, but in pieces. Since there really wasn’t a great (in my opinion) one-stop place that clearly laid out all of the steps, I created one.
This is in a early state. If you have comments, I’d appreciate them. I’ll probably add more. (If you’d like to see more, let me know that as well.) At this point, the basics are pretty much there, so I don’t actually need to do anything else. However, I have taken this just a bit further: This is the top-level of the tutorial
Again, comments and suggestions welcome.
CppUTest Recent Experiences 163
Background
Mid last year I ported several exercises from Java to C++. At that time, I used CppUTest 1.x and Boost 1.38. Finally, half a year later, it was time to actually brush the dust off those examples and make sure they still work.They didn’t. Bit rot. Or user error. Not sure which.
Bit rot: bits decay to the point where things start failing. Compiled programs do have a half-life.
User Error: maybe things were not checked in as clean as I remember. Though I suspect they were, I don’t really have any evidence to prove it, so I have to leave that option available.
To add to the mix, I decided to upgrade to CppUTest 2.x and to the latest version of the Boost library (1.41). I think that broke many several things. But the fixes were simple, once I figured out what I needed to do.
The Fixes
What follows are the three things I needed to do to get CppUTest 2.0, Boost and those exercises playing nicely together.Header File Include Order
First, I used to have the header file for the CppUTest Test Harness, included first. It seems logical, but it caused all sorts of problems with CppUTest 2. That header file, includes a file, that ultimately includes something that uses macros to redefine new and delete. This is done so the testing framework can do simple memory tracking, which lets you know if your unit tests contains memory leaks.I like this feature. Sure, it’s simple and light-weight, but it coves a lot of ground for a little hassle. The hassle? Include that header file last, instead of first. Problem Solved. Well at least the code compiles without hundreds of errors.
Boost Shared Pointer
Rather than hold pointers directly, I used the boost shared pointer class for a light-weight way to manage memory allocation. This is something I would do on a real project as well.Somehow, the updated memory tracking in CppUTest 2.0 found something I had missed when using CppUTest 1.0.
I need to be able to control the date, so I have a simple date factory. By default, the date factory, when asked for the current date, returns the current date. Several unit tests want to simulate different dates. E.g., check out a book on one day, return it 14 days later. To do that, I manipulate the date factory (a form of dependency injection). This works fine, but by default the date factory is allocated using new.
When I replaced the existing date factory, I was not resetting it after the test. It turns out that this did not break anything because I was “lucky”. (Actually unlucky, I like things to fail fast.) CppUTest caught this in the form of not deallocating memory correctly:
- I want to replace behavior
- To do so I used polymorphism
- Polymorphism in C++ requires virtual methods (please don’t correct me by suggesting that overloading is polymorphism, that is an opinion with which I strongly disagree)
- Methods are only virtually dispatched via references or pointers
- References cannot be changed, so I must use a pointer if I want a substitutable factory, which I wanted
- Pointers suggest dynamic memory allocation
To fix this, I updated the setup method to store the original date factory in an attribute and then I updated the teardown method to restore the original date factory from that attribute. That I missed this suggests that my test suite is not adequate. I did not fix this problem for no good reason other than I was porting existing tests, so I left it as is. For the context it will not cause a problem. Pragmatic or lazy? You decide.
One Time Allocation
Here is a simple utility that uses Boost dates and regex:ptime DateUtil::dateFromString(const string &dateString) {
boost::regex e("^(\\d{1,2})/(\\d{1,2})/(\\d{4})$");
string replace("\\3/\\1/\\2");
string isoDate = boost::regex_replace(dateString, e, replace, boost::match_default | boost::format_sed);
return ptime(date(from_string(isoDate)));
}
Now this is somewhat simplistic code. So be it, it serves the purposes of the exercise. I can think of ways to fix this, but there’s an underling issue that exists if you use the regex library from Boost.
When you use the library, it allocates (in this example) 10 blocks of memory. If you read the documentation (I did), it’s making space for its internal state machine for regex evaluation. This is done once and then kept around.
So what’s the problem? Well, when I run my tests, the first test that happens to exercise this block of code reports some memory allocation issues:
c:\projects\cppppp\dependencyinversionprinciple\dependencyinversionprinciple\pat
rongatewaytest.cpp:34: error: Failure in TEST(PatronGateway, AddAFew)
Memory leak(s) found.
Leak size: 1120 Allocated at: <unknown> and line: 0. Type: "new" Content: "
?"
Leak size: 16 Allocated at: <unknown> and line: 0. Type: "new" Content: ?a"
Leak size: 20 Allocated at: <unknown> and line: 0. Type: "new" Content: "êà4"
Leak size: 52 Allocated at: <unknown> and line: 0. Type: "new" Content: ä4"
Leak size: 4096 Allocated at: <unknown> and line: 0. Type: "new" Content: ""
Leak size: 52 Allocated at: <unknown> and line: 0. Type: "new" Content: "êâ4"
Leak size: 20 Allocated at: <unknown> and line: 0. Type: "new" Content: ~4"
Leak size: 32 Allocated at: <unknown> and line: 0. Type: "new" Content: "?à4"
Leak size: 32 Allocated at: <unknown> and line: 0. Type: "new" Content: "h~4"
Leak size: 80 Allocated at: <unknown> and line: 0. Type: "new" Content: "êä4"
Total number of leaks: 10
This is a false positive. This is a one-time allocation and a side-effect of C++ memory allocation and static initialization.
There is a way to “fix” this. You use a command line option, -r, to tell the command line test runner to run the tests twice. If the allocation problem happens the first time but not the second time, then the tests are “OK”.
I didn’t want to do this.
- The tests do take some time to run (30 seconds maybe, but still that doubles the time)
- The output is ugly
- It’s off topic for what the exercise is trying to accomplish
#include <CppUTest/CommandLineTestRunner.h>
int main(int argc, char **argv) {
return CommandLineTestRunner::RunAllTests(argc, argv);
}
#include "DateUtil.h"
#include <CppUTest/CommandLineTestRunner.h>
/** ************************************************************
The boost regex library allocates several blocks of memory
for its internal state machine. That memory is listed as a
memory leak in the first test that happens to use code that
uses the boost regext library. To avoid having to run the
tests twice using the -r option, we instead simply force
this one-time allocation before starting test execution.
*********************************************************** **/
void forceBoostRegexOneTimeAllocation() {
DateUtil::dateFromString("1/1/1980");
}
int main(int argc, char **argv) {
forceBoostRegexOneTimeAllocation();
return CommandLineTestRunner::RunAllTests(argc, argv);
}
Since this one-time allocation happens before any of the tests run, it is no longer reported as a problem by CppUTest.
Before I introduced this “fix”, I spent quite a bit of time to verify that each of the 10 allocations were done by one of the three lines dealing with regex code in my DateUtil class. I used a conditional breakpoint and looked at the stack trace. (I know, using the debugger is considered a code smell, but not all smells are bad.)
Conclusion
I still like CppUTest. I’ve used a few C++ unit testing tools but there are several I have not tried. I don’t have enough face-time with C++ for this to be an issue. I am not terribly comfortable with the order of includes sensitivity. I’m not sure if that would scale.I do appreciate the assistance with memory checking, though dealing with false positives can be a bit of a hassle. There was another technique, that of expressing the number of allocations. But in this case, that simply deferred the reporting of memory leaks to after test execution. In any case, I do like this. I’m not sure how well it would scale so it leaves me a bit uneasy.
If you happen to be using these tools, hope this helps. If not, and you are using C++, what can you say about your experiences with using this or other unit testing tools?
Name that refactoring: 2 - Version 2 44
A few updates applied to the second name that refactoring. Note that I’m using a star to represent a problem dependency. It is the “star” of the refactoring. I’m looking for a better image. I could go with a database icon, but the principle is more general than that. The cloud was confusing. So if you have an idea, please let me know what it is!
Again, thanks for taking a look and giving me the feedback.
Step 0: Problematic Dependency
Step 1: Capture dependency in a single class
Step 2: Raise the abstraction to a domain-level interface
Step 3: Introduce test doubles as needed