CppUTest Recent Experiences 168
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.
Software on the Cheap 262
When it comes to software, you get what you pay for.
Makefiles, what are you doing with them? 155
Half a year ago, I took some exercises written in Java and ported them to C++. At that time I punted on writing makefiles and decided to reply on an IDE (Visual Studio). That worked fine but recently we almost had a customer that was going to take this class and, bless their heart, use the command line.
Turns out they are going to use visual studio, so I can shelve this, but I figured I’d get feedback on what I have created for a makefile. Since I have not written a makefile for 12ish years, I figured things have changed. They have, but I suspect they have even more.
What follows are my environment assumptions and the makefile. I’d appreciate any suggestions.
FWIW, I wrote this makefile because it turns out fully building all files takes longer than just building what has changed. I know this seems obvious, but it is not always the case with small projects like this. There is some point where the project becomes big enough to warrant dependency-based building. The exercise meets that criteria. Sometimes the time taken to evaluate build changes is enough overhead that it can be safely removed in lieu of a full build. This is a consideration when creating custom build files for legacy-based refactoring efforts.
Mocking Mocking and Testing Outcomes. 383
The number of mocking frameworks has proliferated in recent years. This pleases me because it is a symptom that testing in general, and TDD in particular, have become prevalent enough to support a rich panoply of third-party products.
On the other hand, all frameworks carry a disease with them that I call The Mount Everest Syndrome: “I use it because it’s there.” The more mocking frameworks that appear, the more I see them enthusiastically used. Yet the prolific use of mocking frameworks is a rather serious design smell…
Dependency Injection Inversion 1859
Dependency Injection is all the rage. There are several frameworks that will help you inject dependencies into your system. Some use XML (God help us) to specify those dependencies. Others use simple statements in code. In either case, the goal of these frameworks is to help you create instances without having to resort to new
or Factories.
I think these frameworks are great tools. But I also think you should carefully restrict how and where you use them.
UI Test Automation Tools are Snake Oil 411
It happens over and over again. I visit a team and I ask about their testing situation. We talk about unit tests, exploratory testing, the works. Then, I ask about automated end-to-end testing and they point at a machine in the corner. That poor machine has an installation of some highly-priced per seat testing tool (or an open source one, it doesn’t matter), and the chair in front of it is empty. We walk over, sweep the dust away from the keyboard, and load up the tool. Then, we glance through their set of test scripts and try to run them. The system falls over a couple of times and then they give me that sheepish grin and say “we tried.” I say, “don’t worry, everyone does.”
It’s a very familiar ‘rabbit hole’ in the industry. It’s sort of like the old days when you’d find a couple of classes generated by a CASE tool in every code base you visited if you looked hard enough. People started with the merry notion that they were going to round-trip code with some CASE tool and they learned (like most lucky teams do) that it just doesn’t pay for itself, it’s not worth the time or the frustration. UI Test Automation tools are in the same category. Personally, I think that in this day and age selling them is irresponsible. Developing them open-source? Well, let your conscience be your guide, but really, even though people can use them responsibly, they hardly ever do because these tools are sold with a dream, a very seductive and dangerous one.
The Dream
Janet comes into work in the morning and she sits down at her super-duper testing console. She presses a button and the testing system springs to life. The application comes up all at once across ten monitors. Cursors move, selections are made (silently) and tests run against the user interface magically, as if some eager set of ghost elves took control, mischievously burrowing through the nooks and crannies of the application, running scripts to completion, and making little notes whenever there is a failure. Janet sits back in her chair, waiting for the elves to report back to her. She stirs her coffee gently.
The Reality
Janet hasn’t gone home yet. It’s 2AM and she has to report completion of all her test cases at a meeting in the morning. She thinks she’s past the last configuration issue but she’s not sure. For the last hour, she’s been trying to make sure that a particular button is pressed at step 14 of her script, but quirky latency on the server is preventing it from happening consistently. Sadly, she has to run the script from the beginning each time. Oh, and five hours ago she discovered UI changes which invalidated 30% of the regression tests. Most of the changes were easy but she still has 12 cases to go and her 9AM meeting looms ahead of her.
This gap between the dream and the reality is not a matter of flawed execution, it’s endemic. Here’s the scoop.
UI Test Automation Tools are Brittle
You might not think this is fair but it is, really. I haven’t seen one of these tools yet which isn’t susceptible to missed events or timing madness. It just happens. The fact of the matter is, it is hard to sit on the outside of an application an instrument it. It’s a very technology sensitive problem. You need to hook into either the OS or the browser or both. Neither are ever really built from the ground up for that sort of access.
UI Based Testing Is Not the Solution That Vendors Imply It Is
This is the big issue, the one which really hurts the industry. The fact of the matter is that UI based testing should be used for UIs: that’s it. You should not be testing your full application end-to-end through a UI Testing tool. First of all, that sort of testing couples some of the most important tests in your system to one of the most volatile parts of it. It’s easy for us to see business logic as volatile, but really, the UI is the thing which twists and ripples in the winds of change. When customers want new features, often those features involve new workflows. When usability experts discover better ways of models of interaction, an agile business seizes upon them and makes the changes—if they can. You’d be surprised at the number of applications which continue to sport out of day user interfaces simply because the development organization is terrified of throwing away all of their regression tests which (by the way) go through the UI. Even if you’re not a consultant like me, visiting teams and seeing their development processes, you can see hints from the outside. Think of every website or shrink-wrap application which has “the same old workflow” and a UI that has become more cluttered over the years. Often it’s because of that lock-in.
UI Based Testing Takes More Staff and Time Than You Expect
This, really, is the most common failure case. It’s the case which explains the dust on the testing box’s keyboard. Someone, usually disconnected from the development organization, decides that “hey, we need to solve the testing problem. We have too many people doing manual testing. It’s taking forever.” So, they do their research, find a vendor with with a good licensing model and a good pitch and then they push it on the development organization. They are, of course, looking to reduce staff so when they realize that translating all of those manual tests to the tool is very labor-intensive, they are taken aback. But, of course, it is just a temporary cost, right? But, then it takes far longer than they expect. Remember Janet’s story? It’s really hard to catch up with a UI-Based testing tool. It’s hard to even stay in place with one. Typically it takes a number of people to do UI-Based automated testing for a development team in sync with an iteration and worse, they’ll always lag behind a bit because you can’t really write UI-based tests ahead of time the way you can with FIT and other beneath-the-UI testing tools. From what I’ve seen UI-based testing, done diligently, takes the effort of about one tester for every two to three developers. That’s what it seems to cost amortized across all of the maintenance of UI-induced test breakage. Oh, and by the way, if think you are going to save labor using record and playback? Nope, you aren’t. It doesn’t work.
Solutions
The fact of the matter is, you can use these tools effectively, but in a very narrow space. It’s nice to be able to test the UI—by itself. However, this sort of thing requires an architectural change.
In general, UIs are too volatile for end-to-end testing. Teams that do it well, typically develop a small task-focused scripting layer and build tests on top if it so that the actual tests don’t touch the UI directly. But, if they happen across that technique, they are lucky. Still, it isn’t an ideal solution. You really want to be below the UI working against an API which exposes the business logic. And, because of that nearly mystical synergy between testability and good design, that API layer is often useful for many things other than testing.
Conclusion/Challenge
I recognize that I’ve been rather vicious in the this blog. If you develop these tools for a living, you might not think it’s fair. But consider this. If you don’t think I’m being fair, take a look at how your tools are marketed. In particular, show me where the product literature discourages end-to-end testing through the tool. Otherwise, well, you know, you are probably developing snake-oil.
The Polyglot Tester 153
Behavior Driven Development, and it’s emphasis on the Given / When / Then structure of specification has been well accepted by many parts of the software industry. Tools such as JBehave, Cucumber, GivWenZen, have taken a prominent role, and rightly so. After all, it’s hard to argue with the elegance of simple statements such as:
Given that I am a user named Bob with password xyzzy
When I log in with username Bob and password xyzzy
Then I should see “Welcome Bob, you have logged in”.
Yes, it’s hard to argue with it, but argue I shall…
Name that refactoring: 2 - Version 2 48
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.
Name that refactoring: 1 - Version 2 48
Here is an update to the first name that refactoring based on feedback. How about this?
Step 0: Method with embedded dependency
Step 1:Extract method to move dependency to another method
Step 2: Subclass and override method with new code that does not have original dependency
So what do you think? Better or worse?
What about using the star in other image? In general, the star could represent the dependency we’re trying to get rid of.
Name that refactoring: 2 77
Ok, so I’m getting good feedback on the first picture. Now for a series of pictures.
How do you interpret this series?