Unit Tests Equal Awesome

I’m working on a hobby project iOS app that lets me track my comic book collection. I’m interested in comic books because all these super heroes from my misspent youth rule the world of popular culture. While the cool kids were playing sports and going to parties I stayed at home reading comic books. In college I stopped and found other things to do (computer programming, talking to humans, MTV). But now in the September of my life comic books are back and grip our imaginations tightly with their mutant powers.

I wanted to get back to the source. Where did all this cultural power come from? As I started buying physical comics again I realized I needed to track these objects of my affection on my phone. And I bet there are already dozens of apps that do this but I like to create my own tools.

Book Binder is the app and you’l find the code on GitHub.

Book Binder is an iOS app with a web backend. It’s an enormously long way from finished. I have lots of parts of it to figure out. The two current big problems are that comic book publishers can’t count and the number of comic books published is huge.

Comic book publishers can’t count!

Let’s take the case of Daredevil. One of my favorites as a teen and now a big show on Netflix. For reasons that are beyond comprehension (probably marketing) Marvel has restarted the numbering of the “man without fear” 6 times! Daredevil #1 was published in 1964, 1998, 2011, 2014, 2015, and 2017–and I don’t mean republished (that happens too). Daredevil #1 from 1964 is a completely different comic book from all the other Daredevil #1s in the five succeeding years! At one point Marvel tried to fix the problem with “legacy numbering” and that’s why the current series of DD started with #598 in 2017 instead of #29. I have no doubt in my mind that Marvel will start over with Daredevil issue #1 soon.

The other counting problem created by comic book marketing is variant issues with different covers. The most recent issues of Doctor Strange may or may not be published with different covers for the same issue. Collectors apply letters to each variant but Marvel doesn’t seem to have official variant designations. I have Doctor Strange #2 variant edition, legacy #392, second printing. I’m not sure how many variant editions were published or what the variant letter for each edition should be.

This counting (really identifying) problem makes it hard to come up with a good data structure for storing a comic book collection. I’m using a combination of a URI (unique resource identifier) and JSON (JavaScript Object Notation. This way I can easily share data between the iOS app and web server and with other comic book collectors, sellers, and buyers.

The number of comic books published is huge!

How many issues of Daredevil or Doctor Strange have been published since the 1960s? It’s hard to say. I estimate between 400 and 500 for Doctor Strange but I’m probably not including annuals, specials, team ups, side series, and all the variants. So let’s double that to 800 to 1000. And that’s the “master of the mystical arts” alone. If Marvel has around 200 books and DC has the same then we’re looking at a lower bound of 320K and an upper bound of 400K just for the two majors. Some of DC and Marvels comic books started in the 1930s and 1940s. If we include those and all the indy publishers (like Dark Horse) and all the publishers who have disappeared (like EC) then I’m going to estimate 1.6 million to 2 million unique comic books published in the USA. It’s really hard to say because it’s hard to know where to draw the line with publishers and if certain reprints should be included.

In any case I’m not going to be able to store more than a fraction of the millions of published comic book metadata representation in a phone. At best I can store a slice of this data locally and using any one of the big clouds to keep a shared catalog. I just want all this info to be quick to access, cheap to store, and easy to reconcile.

Testing an app for that

Let me tell you, creating an app, on my own, as a hobby project, is fun but hard. Like climbing a rock wall (which I would never personally do) you make a lot of false starts and have to retrace your steps trying to find a path forward.

This is where my unit test have helped. No, not helped. Made everything possible!

I started with three or four data structures. I’m testing out ideas and changing my mind as the idea do or don’t pan out. I’m not afraid to make large scale changes to my code because every function of every class has unit tests to make sure that if I break anything I can fix it.

Today I realized I had to take a big step back. I could not instantiate a comic book collection from a list of comic book URIs. I also realized I was storing state info in the comic book URIs which would not scale with millions of books to track. I finally realized that I had to enforce consistency in the formation of my comic book URIs (they all have to have four slashes). This way I could tell if a URI was mangled or incomplete.

I had to touch every one of my six major object that support my app… And I did! With Confidence. Once I removed state from my URIs and got all by unit tests to pass I fired up the app–and it worked fined. I had not added any bugs or broke any functionality. Whew!

If I didn’t have unit tests I’d be afraid to touch the code. I would be much more respectful of the code and I once I got some part of it to work I’d leave that part alone. As this is a lonely hobby project, I’d get stuck, give up, and move on to something easier.

Even with commercial software, with large teams of expert programmers, lack of tests and fear of changing the code, results in most software projects falling behind, abandoned, or just buggy.

I was sold on unit tests and Test Driven Development before and I’m resold every day I write code. I don’t care if you write the tests before or after the code that makes them pass (I do a bit of both). Just write the tests–especially if you are writing code for self-driving cars or robot military machines.

iPhone to the Max

I’m on that Apple program that where you pay for an iPhone over time and you get the opportunity to update immediately when a new model comes along, as it does every year.

While this is a very good deal for Apple, almost like a subscription service, it’s a good deal for me too. I hate the feeling of FOMO that comes along when a new computer, phone, or device is released. But with iPhones (and Android phones) it’s more than just a feeling. Missing out on the latest phone means missing out on important new features, security protections, and performance improvements.

FOMO used to be a big problem for personal computers as there were big performance jumps between PC models back when Moore’s Law was still in full effect. These days you can still get great results from a 5 year old PC or MacBook. Maybe you can’t play VR games but you email and browse the web like a champ.

Smart Phones are in a different place on the product evolution curve than PCs. They still have a long way to go before they settle down. Innovation in smart phones is driven by advances in displays, cameras, custom chips, and machine learning. Even incremental improvements in these technologies means far better user experiences, security, and even more epic cat photos.

I’m super happy with the jump between the iPhone 8+ and the XS Max. It responds faster, is easier on the eyes with its 6.5″ screen, and yet is basically the same size as the 8+. The name is kinda of silly. But I don’t care what Apple names their phones.

At some point phone hardware will cease to evolve and some new device will become our “primary interface” to the Internet. My guess is that it will be a watch of some sort with accessory glasses or screens. But these things are hard to predict.

I’m on the train as I type this post into my phone and one guy is still reading a paper news paper. I guess that iPhone XS Max just didn’t excite him.