Browsing the archives for the work safe category.

There’s No Time for That! – Testing the Untestable

work safe

As I said earlier, I wanted to talk about other aspects of an event described by Matt Terry about us fixing a bug using a test first mentality.

If you look closely at his retrospective, you’ll notice a problem. Let me give you a hint. Look at the phrase, “The last thing we did was wire up our new methods in the appropriate places.” Got it? NO? Consider how that fits in temporally (time-wise) with the declaration that, “As you’d imagine, now our tests are passing.”

If you’re looking closely, we were actually writing tests against the wrong class. If we had written the tests against the right class, then there would be no need to wire things up. I didn’t see it either at first.

Enough dancing around the point. Here’s some concrete information. The scheduler uses reminders to schedule when an Android alarm or notification needs to occur. There are a few different types of reminders and that’s only important because I use a factory to build the reminders and their sub structures.

Where are the tests? I was testing the factory’s ability to build the correct structure, so that’s where I naturally started adding tests. I ended up duplicating logic for the scheduler in these tests. This turned out to be a problem in an earlier feature when I changed how the reminders were used and didn’t add them to the scheduler until I started system testing. It follows then that I should bring the scheduler in to the tests. That way when I change the way the reminders need to be used, the scheduler will change along side. And we won’t have an, “Awe, crap,” moment where we realized the reason it’s not working is because we only half solved it.

Why didn’t I test the scheduler? Because it was coupled to three things. I used the Android Alarm Manager, the Android Notification Manager, and time. Yes, Virginia, you can be coupled to time. I can uncouple the time at this level the same way I did at the reminder level: pass it in as a method parameter. But where does this stop? In my case I would choose to new up a GregorianCalendar at the Android Activity level. This is also where I would wrap the AlarmManager and NotificationManager so I can pass in test-doubles.

What’s the theory? It’s an application of the Ports and Adapters architecture. Ports and Adapters, also called “Hexagonal Architecture” can be applied in a fractal manner. It is a pattern of separating input and output from a business object. In our case the input is time and the outputs are the Alarms and Notifications. By thinking about this input / output metaphor I can pass in a time and wrappers for Alarms and Notifications that can tell the tests what values the scheduler outputs. Testing made easy! Okay. Easier.

Or, if I want to be cheap about it, I can wrap all three in protected methods and test a subclass of the scheduler that allows for injecting time and record when an alarm is to fire and what notification was displayed. There are a few reasons that this isn’t the best idea, but it is the quickest way to get this huge chunk of code under unit test and not rely on manual or system tests to ensure this code works.

No Comments

We’re Besties! – Pair Programming

work safe

The lead on my most recent project, Matt Terry, wrote a blog post on test first this Saturday that tweaked a few thoughts in my head. There is so much to unpack in that particular event he described, so I’m going to write a couple of blog posts and try to give a few different angles their due.

Now about the story he told. It is true, but …. let’s say it diminishes his role in the situation. I’m going to see if I can’t sing the praises of pair programming.

We found a tricky bug in our scheduler. Matt came over to my desk and we decided to pair on the problem. We started by trying to understand the problem. We chatted over the scenario It was essentially a time race condition. Different components need to know new information at different times. When can we inform these serialized and stored objects the world changed? We wrote some notes and modeled a scenario. Then we wrote some tests. We constantly checked in with each other that our assumptions were correct. We made a point to talk out loud about every thought I was thinking as we coded. We made a point to answer and ask questions. Matt was also great at guilting me in to correct action. There wasn’t a thing he said or did, and he’ll probably be a bit mortified to hear about it. He just had to be in earshot when I muttered, “but that should probably be it’s own method,” and then I’d HAVE to fix the code because the alternative is like walking past trash and NOT picking it up. While someone watches you. Social pressures can be a wonderful thing.

The point is, by being there talking through the whole process we were able to quickly understand the problem and work through the solution. We fixed this far more quickly that either one of us could have on our own. In addition, the solution was better because I wasn’t throwing it over the wall to be reviewed. We wrote the best code we could because we knew we were watching.

All in all, I’m looking forward to pairing with him again. I’m bad at it, but it’s a skill and one I’m starting to find more and more enjoyable as I get better and better at it. Believe it or not, development is an inherently social event and pair programming brings this to the forefront. It increases communication by making it visibly essential to everything.

No Comments

Usul’s Words Have Power, Part 2: Use Cases

work safe

In the near future I’m going to use a word. I’m going to use it as a cornerstone of an argument for something a bit radical. Not very, but a bit. The word is Use Case. Since everyone has an opinion, I’m going to be specific about what I mean.

Use Cases were invented by Ivar Jacobson in the 1980’s as a way to solicit requirements. It is NOT a way to use spare day-old boxes, arrows, and lollipops. While UML has a thing called Use Cases, that ain’t it. I mean a list of actor/system interactions with some context and some deviations. What do I want to use it for? It gives me, a developer, a fuller idea of what I’m actually supposed to build for my customer.

As close as I usually get is, after a conversation with a customer or team lead, is a bulleted list of things to do. It looks a bit like this:

  • Add an activity to my time sheet.
  • Set a start and end time to the activity.
  • Describe the activity.
  • You can’t save the activity if it doesn’t have a description or time range.
  • Choose a time code associated with the activity. There should be a default.
  • Display the activity on the time sheet.

It is generally how I think I’m going to implement the feature in enough detail to get all the corner cases implemented. This is not a Use Case, it’s a todo list. It doesn’t share any information about workflow or context or motivation. In short, I’m left with no empathy for my users. And if I don’t have empathy for my users, how can I try to make their lives, or at least their experience using my software, better?

A Use Case as I want to use term focuses on workflow and on the context surrounding the actions being described. It has the following parts:

  • Title A name to distinguish it from other Use Cases
  • User Intention Describes who, why, and what
  • Precondition Where in the system your interaction will take place
  • Interactions The happy path
  • Extensions How conditions cause the happy path to deviate
  • Postconditions How I expect those interactions to impact the system

Most of these are just prose, the interactions and extensions are tables with two columns, the actor’s actions and the system’s response. Each row is numbered. The Interaction rows are simple numbers. The extensions are numbered with numbers and letters to relate to the interaction they modify.

Great! I’ve created a wonky definition! Now what the heck does that look like?

An example

Add an Activity to a Time Sheet

Tony logs time spent working on the Bryce Co project so Cheryl can bill against the Bryce Co account.

Precondition User is logged in and viewing an editable timesheet

Interactions

User Action System Response
1 User clicks on the new entry button System presents the user with the action entry dialog.
The user’s most recently selected time code is automatically selected
Only time codes the user is authorized to use should be displayed.
Focus is on the date field
2 User enters a date
3 User enters a start time and end time
4 User describes the activity System will enable the ok button
5 User changes the time code
6 User clicks the ok button System removes the dialog
System displays the new record in the time sheet and saves the updated timesheet.

Extensions

User enters none or only one of the start and end time

User Action System Response
2a User enters a date outside the range of the timesheet’s date range System will post a message displaying the valid range and empty the date field
3a System will not enable the ok button until a valid start and end time are present
3b User enters a start time after the end time System will move the end time to 15 minutes after the start time
3c User enters an end time after the start time System will move the start time to 15 minutes before the end time
4a User doesn’t enter a description System will not enable the ok button without a description
5a User clicks on the cancel button System removes the dialog and discards the entry
5b System is unable to save the entry then a message will be displayed and the dialog will not be removed unless cancel is selected
No Comments

Deliberate Practice: How-To

work safe

A long time ago I promised to talk about HOW to do deliberate practice. There, I DID cover what it meant to me, but just to sum it all up in one place, I’ll repeat myself some.

Deliberate practice is the repetition of specific actions to gain feedback for altering behavior.

I have an IDEER about making a good exercise. You can build one out with the following Parts.

  • Identify the skill set you wish to improve
  • Devise a task or action that will isolate and expose the skill set.
  • Execute the task. Preferably in a manner that will allow you to review your work.
  • Examine your work and review it. What do you want to do differently next time?
  • Repeat. Once you can do it perfectly on demand, make it harder.

Great. Now for what that looks like in the real word? Well, it kind of depends on you. Here’s my non-exhaustive list.

Kata

This is the obvious example. A code kata is a TDD exercise for an essentially toy problem. A great example is Roy Osherove’s String Calculator example.

Why are Kata interesting? First, if you’re learning TDD, they give you a place to learn the rhythm of Red, Green, Refactor. After that, they can give you a place to explore how test choices effect the implementation and how the implementation can effect the test choices. It’s also a scaffold for other skills such as Keyboard navigation, refactoring tools, autocomplete, and other techniques adjacent to development.

Archetypical Project

This is a project that is simple and well known. The purpose is not to be interesting in the domain, but in the implementation. It’s a blog just like every one has done before but this time in Node, or Rails, Clojure, or using DCI or DDD.

Pet Projects

This is a tool over which you have complete ownership. Also, you aren’t on a time table to ship. If you sell a product, that might not count. Here’s why they are important. With a pet project, you can radically rewrite parts of it to explore new concepts. How does immutable state work with this problem? How can I use Ractive programming in the View Model? Can I migrate some or all of the data storage to a NoSQL system? This would be a maintenance nightmare for production code, but for a pet project, it’s a branch and some spare time learning valuable lessons.

Critical Reading

Writer’s read one another’s work. They look at aspects of characterization, pacing, use of language, and much more. So, why do we want to read other’s source code? To understand all those aspects of design that we should be looking for in our own work. Do the abstraction leak? How effective are the names in quickly communicating understanding of architecture, concerns, and responsibilities? How well does it handle dependencies? How easy is it to change the code? What can you do to improve this?

This is not a code review. A code review should cover these, but also be much more aware of things like correctness and local dialect / idioms.

Reductio Ad Absurdum

This is my favorite! It’s not about the right way, it’s about an extreme way. If you did this in my production code, I would slap you silly. But if you’re doing it to understand linq, or the use of lambdas, or immutable state. How far can you push the SOLID principles, what if every METHOD had a single responsibility? How about writing a class with no references to a concrete type only Generic types.

Mindfulness

This isn’t about practice, but about getting feedback in everything you do. If you don’t pay attention to what you do every day, understanding the tiny subtle variations you have day after day and their effect on your work. This is the essence of deliberate practice. If you are mindful of what you are doing, then you will strive to do it better next time.

1 Comment

Dirty Secrets

work safe

There has been some buzz around the office recently about getting some TDD training. I figured I could drop my 2¢ in with an example of how it helps me. It’s not about bug-free code. Or even faster coding. To me, it’s about reducing rework.

I have a dirty secret. I’m not always awesome. On occasion, I’ve been known to write a bug. Not often! Most of the code I write mostly works, so I’ve got that going for me.

When I had to rewrite a subsystem of our application because of a drastic change in the requirements, I wasn’t worried. I had the parts that needed changing isolated and I had an interface that would work. I just needed to gut some classes and start over. And write some tests showing the behavior I wanted that section to have. For those playing the home game, this is related to the “London School” of TDD and BDD.

It worked flawlessly. Until our test lead thought of corner cases I had not considered. That’s his job, and he’s good at it. But here is where the awesome came in…

I added some test cases to some itty bitty logic classes deep in the code to handle those new behaviors. Then I made ’em pass. Easy.

The best part is I knew I did’t break the cases I had already covered. That means this bug won’t cause more bugs.

Success Kid!

Contrast this with a project I was working on a bit over a year ago. It was very hard to wrap test cases around it because of how I had written the interface to the UI. We played ‘whack-a-mole’ with the same few issues for a few iterations.

U Y NO FIX BUGS

And that’s what it’s about. I don’t want to fix code that was working. I want to write code for features and cases that aren’t already there.

No Comments

Apropos of Nothing – A Magical Podcast Playlist

work safe

Several years ago, I was listening to a podcast and they were making fun of a friend of theirs. The friend liked closing music on podcasts, because it gave him time to pick a new show before that one is done. My mind boggled because I had already solved this problem using iTunes smart playlists.

Fact: Each podcast has a ‘media kind’ of podcast when imported via iTunes.

Fact: Each podcast file has a play count that starts and zero and increases once the file has been played all the way through. If you stop, skip, and go back the play count is still zero until you finish the file. Listen on you iPod then sync and the count goes to 1.

Fact: It’s trivial to right-click a file in iTunes and reset plays

Combine those first two facts with a ‘smart playlist’ with live updating and I always have a list of fresh new podcasts.

Bonus Fact 1: If your car has an iPod interface, naming some playlists 01_* through 05_* will control which order the playlists happen to appear on your 6 disc changer interface.

Bonus Fact 2: If you use an iPad, iPod Touch, or iPhone this list will update as you play through them on that device. Millage varies on other iPods.

I have no idea why now is the time I have a bee in my bonnet to write this down.

No Comments

When things go wrong – UITableViewCell Edition

work safe

I’ve been leading a brown bag session at SEP where we gather as a group and write an iPhone application. The main reason isn’t to learn everything about the iPhone. I want to aclimate to the Cocoa development environment. There is enough about iPhone and Mac development that are very different from Java and .NET that I want to make sure we don’t have to learn from the ground up when we start coding with this stuff for real. When talking with Scott Hanselman, John Sonmez called it a parallel universe where everything is slightly different.

That said, We did a session this past Thursdays and I totally borked it. I ruined it from two sides; I didn’t discuss ANY of the concepts regarding either Storyboards (because I don’t know them, maybe?) or UITableView, and I hit a snag with the demo because I dove straight and hard at the code without thinking about my audience. Oops. I promised them a blog post once I figured out what went wrong.

First, the session I will be talking a bit more about the concepts behind the Storyboard. I’ll also be talking about TableView concepts. It might be the whole session, but it should be worth it.

Now, where did the code go wrong? Look at this portion of the Second iOS App tutorial. I missed a few things in it. The default table set up for a Master/Detail view is to use static cells. I needed to change this to a prototype cell, lay it out, and dequeue it using it’s name. The error was coming from a mismatch between telling the table to use a list of items and telling it to show a list of specific cells.

I’m looking forward to our next session, and hopefully it will run smoother now that it seems we’re getting closer to being on the same page.

2 Comments

Getting it done – across platforms

work safe

I’ve been trying for years to find the ‘one true way’ to capture all my todos and notes and stuff. I’ve tried a few systems that worked fairly well, but there were always some catches.

Using a Hipster PDA, I had to make sure I had it with me. I had to remember to pack it. It didn’t handle long notes, nor electronic notes.

I’ve used Things by cultured code. It’s great, because I always have my iPhone in my hand. It syncs with my Mac and my iPad. It has recurrence, long notes, and notifications. It is great. But it misses out because I can’t use it on my computer at work. Out of sight, out of mind.

I tried TaskPaper from HogBay software shortly after getting my first Mac. It was really cool, because it used a plain text file that is human readable and stupid easy to parse. I’ve even used it as an example in a DSL talk I once gave. I could use the same todo file both at work and at home. But I had to carry that file around on a thumb drive.

Until I came to a recent revelation. There is a TaskPaper for iOS that syncs to Dropbox. I use Dropbox. Taskpaper’s file format already has a Vim plugin at work. It works with task paper on my home Mac. It works on my phone and iPad. It is simple and easy to use. And flexible enough for just about anything.

Just for fun, here are some Taskpaper vim commands. And so I can find them again.

\td – Toggle Done – @done(2012-1-24)
\tx – Toggle Canceled – @cancelled(2012-1-24)
\tc – Show Context
\ta – Show All
\tp – Fold All Projects

What are the next steps?

  • It doesn’t give me reminder, so I need a helper app to find things due today and alert me. It’s easy to parse and just needs a command line app run by the OS scheduler that sends an email with today’s agenda.
  • It needs to quickly open my dropbox file and a work only file that doesn’t sync over Dropbox (google Export Controlled). This will most likely just be a shortcut on my desktop to vim and two files.
  • Vim isn’t the prettiest user interface, so I may get sucked back in to some side project WPF development.

I’ve only been doing this for, like, a day. Let’s see how it goes!

1 Comment

A Quick Checkup of your Corporate Health

work safe

Here are some questions to ask yourself about common organizational behavior.

  • Rules are there for you. Does everyone help others in the organization achieve through proper channels? Short-cuts lead to bad mistakes.
  • Passion is of utmost importance. Do people make time to share how the current task at hand effects them personally? Do they feel safe communicating their agreement even after a decision has been made?
  • Two heads are better than one. Are simple decisions still taken as an opportunity to get input and feedback from others? Ideally from five or more people?
  • It’s all interconnected Do we cross-check the impact on even the most seemingly unimportant and tangential issues? Complex systems have complex interactions.
  • The devil is in the details. Are words in minutes, resolutions, mission statements, requirements, etc chosen carefully? Are they discussed until no other possible meaning can be accidentally read from them?
  • The world is constantly changing Are old issues contantly being reviewed for their fitness in a rapidly changing world? Even matters decided in the last meeting can be cast in new light by the speed of modern change.
  • Failure is not an option. Mistakes can be costly and lose people their jobs. Are people constantly reminding each other to be cautious and reasonable? Success may fade, but bad PR lives forever.
  • There is no vacuum. Are people aware of the overarching goals of the organization? Is there discussion of whether your group is the appropriate source for this decision, or should it be elevated to those with a beter strategic understanding of the organization’s goals?

I’ve been thinking about this because I heard a song shuffle up on my iPod, but also because I’ve been discussing how organizations function with several folks in and around the Indy tech community. And some in other fields. And some discussing politics.

The list uses golf scoring, by the way. One or two isn’t bad. But If you’ve managed to score a perfect eight, your organization may be its own worst enemy. Wait, why am I saying that? Because those eight checkpoints are variants of an eight step list of how to sabotage an organization. Brought to you by the OSS (Office of Strategic Service), the precursor to the CIA, this list was developed to help occupied French and other nationalities slow the progress of the Axis war machine durring WWII. And no, I’m not the first to see this. See page 28 for the details.

There is a balance to be struck. But remember, the process that keeps you from making a decision and doing work is a process that is killing your organization.



No Comments

Overcoming Momentum – It’s how I’ve always done it.

work safe

This week’s blog battle has begun!

We, those of us who fancy ourselves serious developers, like to disparage the enterprise developer who specializes in a class of application called Forms Over Data. The Business needs to save some data, so they have the DBA lay out a table. The developer then points their IDE at the table and drags input element on to the form and bind columns to text boxes and BAM!, they are done. System.DraggyDroppy. It doesn’t scale to Real Development. Not when I have a rich set of domain objects.

When I started full-on professional development, the summer before my senior year, I wrote web pages. Each page was a thin veneer over the database. Until I had to add more logic and added a bunch of ifs and elses in to the page. The fact remains, the data I was manipulating was pretty anemic. I’ll call this Pages Over Data. The difference is I have an implicit Fat Controller in my CGI script that the forms over data didn’t.

As I’ve done more desktop and mobile development, I’m starting to see that I’ve just done the same damn thing. Over and Over. It’s how I’ve always done it.

Recently, I have heard several people talk about software architecture. James Coplein has been promoting DCI. At work a few of us have been thinking about rereading Eric Evan’s Domain Driven Design. Despite none of these texts exploring a new idea, despite none of these ideas being things I heartily agree with, despite having evangelized and touted these ideas; I’m not very good at it. I keep finding myself doing pages over data.

What am I seeing? In one case, we had to stand up a bunch of screens for a user study so we’ve stuck a bunch of logic in Android Activity classes. While we’ve been refactoring this out, the odds are good we will always have some of that sticking around. In another case, we had a “business layer” that another team managed and UI designed a screen at a time. Our ViewModels had a lot of logic that we decided didn’t belong in the BL as that was a representation of only the data to be saved in the file and enough logic to ensure consistency and validity and undoing edits.

I can’t put my finger on WHY I don’t like these things, but I don’t. I’m on a quest to overcome the architectural momentum I’ve developed. Here’s what I’m going to do about it. I’m reading a bunch of architecture stuff. Reading along is only so good, so I’m writing a pet project a few times to explore each architectural style I’m working with. Hopefully, this will give me a better understanding of what I’m feeling and how well these styles work for me. So the next time I’m done with a project I don’t look back and say, “it’s just Pages over Data.”

No Comments
« Older Posts
Newer Posts »