I came across an article on Firstround called ‘Forget Tech Debt…Here’s How to Build Technical Wealth.’ Andrea Goulet introduces us to some of the practices her consultancy uses to dive headfirst into legacy codebases, improve their design, and make them more maintainable.
I’ll call this post “When and How I Use Robolectric” instead of “When and How to Use Robolectric” because a) I don’t like telling people when and how to do things, and b) I use Robolectric less liberally than most developers who use it.
Robolectric is a fantastic tool for ensuring that stuff in your Android app works properly. The problem, as you may have heard me say before, is that it runs slowly. In particular, FragmentTestUtil’s operations are especially time-expensive. Compounding the issue, Robolectric 3.0 currently has a memory leak that causes the heap to get bigger than it should. You won’t notice it on a smaller app, but when the app grows enough for the test suite to hit 600 or 700 Robolectric-assisted tests, the suite will hang or stop running because it runs out of memory before it completes.
So you only have 600-ish Robolectric bucks in the bank, and you spend one every time you write a test with Robolectric. My team at work, and I at home, have experimented with ways to save our Robolectric bucks. The first (main) trick has been to separate as much logic from the Android framework as possible and test that logic with JUnit. We save our precious Robolectric bucks this way, spending them on just a test or two for the places where the logic gets wired into the Android app.
Jurgen Holler and Stephane Nicoll’s SpringOne talk toured the annotations available to enhance the design of our classes in Spring.
Mr. Holler started off with an example service class. We walked through some of the Spring annotations used in it:
@Service — a version of the @Component annotation called a stereotype: it serves to inform developers that this is specifically a component of the service type.
@Autowired — When placed on top of a constructor, allows automatic dependency injection. (Sidenote: on top of the class itself, allows field injection).
@Transactional — A declarative annotation for tapping into a middleware service
Then, things got more advanced. We talked about some of the features of Spring annotations that give developers control over the structure and design of their applications.
In this post, I’ll go over how to configure a brand new Android app to use Robolectric.
The topic of why a developer might want to do TDD is for other posts. This is strictly a how-to on setup.
Two things involved:
1. Make a new Android project
2. Include Robolectric (a unit testing library for Android)
Over Thanksgiving break, I once again had the opportunity to pair with the lovely Coraline Ada Ehmke. This time, instead of working on an existing code base, we started from scratch on something I had spiked out: a CSV parser! The original version worked, but the design contained some duplicate code and included no tests.
I had spent so much time on the original version that I could not imagine letting go of it: I intended to go back and add tests after the fact. The problem with this approach is that it gives the test suite no opportunity to help figure out which code isn’t needed: we write tests, one by one, before we implement them to ensure that we aren’t adding extra code, and also to keep the code’s design flexible and modular: that is, easily testable (well-written code should have a passing test suite regardless of the order in which the tests are run). For that reason, Coraline recommended that we start over from scratch, suggesting that, if there were any really important implementation details that I had learned while spiking, I would remember them.
An IDE can heavily influence the development experience in a language, as I found last week with IntelliJ for Java. This week at Chicago Ruby, Brian and Chris of Hashrocket talked about how the VIM IDE influences the experience of writing in Ruby.
Going from Sublime to VIM is a switch that some of my Rubyist colleagues have chosen not to make because, they explain, the additional bells and whistles of VIM cause more confusion than efficiency. I admit, I’ve had the same impression: the first time I saw VIM, I was watching a presenter demonstrate some Ruby code. I struggled to articulate my questions to the presenter because VIM’s line numbers followed the cursor rather than staying put. That made a bad first impression. I looked forward to coming to Chicago Ruby tonight for a second impression that might make me rethink my position. Unfortunately, that did not happen.
That’s not to say that VIM isn’t awesome and worth a look. Perhaps it is. But, from my perspective, VIM’s opportunities to convert Sublime users lie in places other than those emphasized here. So I humbly offer the following set of reactions to the VIM presentation, from a Sublime user. Here’s what I got from it, and here’s what I wish I got from it.
“Yes, mom. I go there and I code with them. Yes, all day. That’s how it works.”
My mother didn’t completely understand my enthusiasm to spend a day in harness at Pivotal Labs, but she seemed willing to accept my reasoning: namely, that pair programming for that much time with more senior developers to myself would allow me to learn a whole lot of stuff. And it did, in everything from Java to TDD to software design. Here are a few of the choicest lessons I got to learn as a pretend-pivot-for-the-day.
So I got ahead of myself on this one, and described ternary operators in the context of an improvement to some front-end work in the last post. That said, I’ll mention it again here, as I learned the ternary operator syntax from Coraline Ada Ehmke in our last pairing session together. This syntax provides a terse alternative to the if statement. Here’s how it looks:
Last month, I had the experience of building out an app on an extremely tight time schedule. The rapid-fire development, while exciting, left me with technical debt to pay. Luckily, I’ve had the extremely good fortune to work with a master of refactoring and code maintenance, Coraline Ada Ehmke, as I learn how to clean up my controllers, detect problems, and write a tight test harness. I wanted to pay it forward and share some of the lessons that I am learning from her in our process of building code together.
I’ll go over some things that I learned in our last session, with examples:
- controller methods: form and function
- code smells: method names and variable names
- Hash methods: zip and inject
- An array method: map
- “Or Equals”: an introduction to caching and an elegant alternative to instantiating variables outside of loops
- Sugary Ruby syntax: &:, ?, and ranges (they’re not just for integers!)