The user experience. All of us talk about how we want a better user experience. Most of us don’t get to do that. After all, for most of us, the users of our application come from a different domain, they are not developers. And so, we build the application with our view of how we think people will use it. If there’s a customer representative in the project, we raise the probability that we will be more accurate in our vision.
I’m lucky to be in a company, that has developers for customers. There’s no need to build the bridge between the two worlds, right?
Well, not completely true. If we look at the details, we are not completely the users of our application. We provide APIs, which we write tests for, but we don’t cover all user scenarios. Another examples are the documentation we’re writing, or the error messages. When we review them, we do our best to make sure they are clear enough for the user, but we can’t be certain who the reader of the documentation will be.
From time to time, I get into the user’s shoes. I write examples, or add-ins, or other code that users need solution for. I sometimes find things I didn’t know work, or I could them better. And I also find out about the customer pains.
For example, when I worked on the CThru example, I started by thinking – It’s a great case to show off CThru, it’s designed for doing cross-system stuff, it should be a breeze.
Then playing with it, I found not everything is rosy. Here’s an example: I wanted the return type of the method being called, in order to create a recursive fake object from that type. The current CThru implementation does not expose that.
So I thought: Basically, I don’t need the real type, I can use ReturnRecursiveFake instead – it takes care of the type internally. If I want to go over all types and methods, I can’t use the type-safe APIs, that’s where the non-public, string based APIs are best. Turns out that the non-public API for WhenCalled are missing the ReturnRecursiveFake we have in the type-safe version.
No problem – I’ll iterate on the stack trace, get to the method being called, and get the type from there. Now that I have the type I can use Isolate.Fake.Instance on it… No, I can’t. It doesn’t have an overload which is not statically-typed. (Which, by the way, goes back to a decision we took when we started working on the API, not to have two ways to do the same thing).
At that point, I decided to pull out the big guns: reflective API. I can do everything with them, except for creating recursive fakes, which I can do myself. Then I remembered how many cases we’ve covered in the recursive fake implementation. And decided to leave that out. I finally decided on the partial implementation that I posted about.
What have I learned?
- You find interesting stuff when you’re dog-fooding. I should do it more.
- It’s great to see what your customer ask from your product. Even greater to take it to the test.
- Although we have quite a comprehensive framework, some cases require additional APIs and functionality.
- You never can know everything in advance.
- Too few people know about CThru, and that’s a shame, since you can do great cool stuff with it.
Are you dog-fooding your application?