VIDEO: Building Tests

Chapter 4 of “Refactoring, Improving the Design of Existing Code by Martin Fowler, titled “Building Tests” provides an introduction to automated testing.

Here’s my perspective on the chapter:

Video Transcription:

Hey, what’s up everybody, it’s Andy from cleanswifter.com and I’m here to talk about the next chapter in Martin Fowler’s book, “Refactoring, Improving the Design of Existing Code.” You can buy that book in the Amazon Affiliate link in the description for this video. Last week we talked about chapter 3, Bad Smells in Code. In that chapter, Fowler presents some ideas of what to look for in your code to know it’s time to actually refactor it. This week, chapter 4, titled “Building Tests” Fowler actually talks about some techniques for introducing automated tests within your code. If you’ve been following any of my posts on cleanswifter.com, you’ll know I have a huge passion for automated testing of software. I was kind of excited for this chapter. When I finally got around to actually reading it, it fell short of what I was looking for. Fowler clarifies that this book is not about testing. And the reason I interpret he chose to include this chapter is to recognize the value of automated testing, especially in the time of refactoring. He doesn’t even mention test driven development in this chapter. Now, if you remember test driven development, one of the key steps to test driven development, is that final third step, to refactor everything you’ve done. Test driven development. You start off writing a failing test. Then you write the production code to make that test pass. And then you refactor. Now just bringing it back to Fowler’s book, he doesn’t actually talk about anything in detail with regard to test driven development. In fact I think he kind of just puts this chapter in here to recognize that when you go out to use this as a recipe book of refactoring, that you should keep in mind the value that can be adding tests throughout the process.

If you’re not familiar with automated testing, or haven’t been following any of my posts on <cleanswifter.com> is that remember, automated tests’ value is that it is code testing code. You can execute an entire test bed at the click of a button. Where your entire code base is tested in a matter of seconds. You do actually have to go through the effort of writing these tests, and that’s no small effort. Then you can make changes to the rest of your code base without risk of introducing new bugs. Additionally, when you find a bug, whether that’s reported through QA or an end user, you can first write a test to verify that bug, and then go fix the code to make sure the test passes, you can now have the confidence that that bug will never surface again in your code. For me, that’s really the value of adding tests, knowing that when I find a bug, I can write a test that verifies the bug does actually exist, then I can go fix that code, make the bug go away, make sure the test passes, then never again will that bug surface. This is especially relevant to the iOS development community because at a recent presentation I gave to the local CocoaHeads group here in Philly, there continues to be the majority of iOS development community that doesn’t write automated tests for their code. In that meeting we talked about some of the reasons this may be. For an independent or contract developer, that they don’t feel it is worth their time. Or hard to justify to their client, whether that is them for their own product, or someone else paying them for their time), that it is worth the time to write tests. It’s a 1:1 ratio, for every hour you spend writing production code, you’ll need to spend an hour writing test code. I think until you learn the lesson the hard way, and then see the value of automated tests correcting that, you’ll never be able to justify the cost. It’s like a catch-22, because if you never try it you’ll never be able to justify it to yourself. On the otherhand, if you’re going to wait to see the value before you try it, you’re never going to try it. I think one takeaway from this chapter, that even Fowler calls out, is that specifically, go try to write a couple tests. Don’t spend a lot of time writing an entire big test suite for your entire application, worrying about every edge case, and instead focus on just 1 or 2 tests that are going to add value, and I guarantee you that sometime down the road, you will have your butt saved by the fact that you had automated tests. You will write automated tests, and sometime down the road they will fail because some code change you made introduced an unexpected, but tested for bug. You’ll be happy since you caught the bug and not an end user.

Fowler clarifies the difference between unit and functional tests. Again, I have a ton of documentation on <cleanswifter.com> that helps differentiate and define each of these for iOS development. For unit testing, you’ll be using XCTest as provided by Apple. It’s code that tests other code at the smallest level. You’ll write a test method for each path of conditional code in another class. It requires intimate knowledge of the code you’re testing. Consider it white box testing. You can see the code, to know the conditional paths, and know how to test it. This is in contrast to functional testing. Functional testing is where you would call it black box testing. You don’t have intimate knowledge of the code. Instead, all you’re doing is testing the code from the outside in. This means that you are simulating an end user swiping, tapping, and navigating your app. There are a bunch of tools out there to do this. Apple’s provided tool is called Xcode UI Tests and I personally use a different tool, called KIF. It stands for Keep-It-Functional. It’s open source. Some of the benefits I like of KIF are that it is mature, been in the community for years, you can write your tests in either Objective-C or Swift. I haven’t spent enough time with Xcode UI Tests to know it’s pros and cons, but I did use its predecessor, UI Automation which was Javascript driven and a poorly documented API. It’s soured me on Apple’s provided functional testing tools, so that’s why I haven’t gone back yet. I’ll do that soon and write about it on <cleanswifter.com>.

Another important thing to keep in mind when you write your first test, regardless of whether you are doing TDD or not, and in fact if you are just starting out I don’t recommend jumping right into TDD. But one thing to keep in mind when writing your tests is that you want to see that test fail when you expect it to fail. For example, say you are writing a test for a method that adds numbers. You want to first verify that adding 1 and 2, never returns anything other than 3. Otherwise, you won’t have the confidence that when someting actually goes wrong, that test will actually fail. That gives you a baseline assurance that that test is actually providing that quality check you’re looking for. And trust me, I’ve seen plenty of cases where I’ve written a test and not done this, only to find out that it wasn’t actually verifying, what I thought it was verifying.

It was a pretty short chapter, chapter 4 in Martin Fowler’s book, “Refactoring” where he just introduces the concept of tests. If you’re watching this video and haven’t checked out anything I’ve posted on <cleanswifter.com> around automated tests. And if you’re not writing automated tests for your iOS apps, you should definitely go try that out.

Looking ahead, I’m really excited for the rest of this book. Chapter 4 is the end of the preamble before the actual list of refactoring recipes. Going forward, week by week, I’m going to make a screencast of that refactoring, showing it in action with Swift code, and post it on <cleanswifter.com>. It will demonstrate the transformation from smelly code to nice clean code. That will be done in a screencast where you can go back and watch. The first refactoring we’ll try in the book is Extract Method. It’s a really easy one, but also a really effective one. I’m looking forward to showing you that. Check back next week for that. In the meantime, be sure to checkout <cleanswifter.com>.

Happy cleaning.

VIDEO: Bad Smells in Code

Chapter 3 of “Refactoring, Improving the Design of Existing Code” by Martin Fowler, titled “Bad Smells in Code” puts definition on when you know to refactor your code.

Here’s my perspective on the chapter:

Video Transcription:

Hey what’s up everybody, I’m Andy, the Clean Swifter. Welcome to the third video episode from my blog cleanswifter.com, where I share tips, tricks, articles, and commentary on how to write cleaner Swift code. In this video, I’ll be providing some commentary on chapter three of Martin Fowler’s book, “Refactoring, Improving the design of existing code.” The third chapter is titled “Bad smells in code.” You can buy the book through my Amazon affiliate link in the description for this video. In this chapter, Fowler covers a list of specific things, called smells, that should catch your eye and tell you that it’s time to perform a refactoring. I think “Smell” is such an effective word. Often, you won’t know in black and white terms that it’s time to refactor. Instead, your intuition that something isn’t quite right will start to poke at you. Leveraging some semi-formal definition for these “smells” will help you be able to identify them in your code. Throughout the chapter, Fowler actually goes as far to actually suggest specific refactorings in response to various smells. Since we haven’t actually read about what those refactorings are, I’m not going to mention them in any detail yet myself. I was also happy to find that in the back of the book, literally inside on the back cover, is a table reference that lists these specific refactorings that can be performed to correct a bad smell. Here’s a quick tour through some of the code smells that jumped out at me.

The first smell, duplicated code. I bet you’ve seen this one yourself, especially if you’re a liberal copy and paster. It’s name is straight forward. Seeing the same pieces of code sprinkled in more than one place is a clear indication that a refactoring is possible and should happen. One common example might be styling a UILabel. Say some group of UILabels on a page all need a certain look. It’s very easy to copy and paste the common lines of code that set the font, color, and abbreviation style. Unfortunately, when you need to change one attribute of the style, you need to do it in many places, and are likely to miss at least one, thus leaving some labels without the change. Duplicate code is easy to spot. If you see it, you need to address it.

The second smell I wanted to call out is actually three in one: Long methods, long parameter lists, and long classes. Fowler actually lists these are three separate smells, but I’m going to summarize them as one. While there are some slight nuances in how they can be treated, they ultimately represent a piece of code that is trying to do too much. The more lines of code any one “unit” is, whether it’s a method or a class, the harder to understand it will be. Later in the book, we’ll learn refactorings that will help extract common behavior, and break these long pieces of code into separate parts.

The third smells I wanted to mention are shotgun surgery and divergent change. Again, these are granular variation of a common theme: where the need to make one change, results in needing to make many other changes. Divergent change refers to this happening within a single class, where shotgun surgery refers to this happening across many classes. When this smell starts to stink, it’s usually a sign that the single responsibility principle has been violated, or that there is weak encapsulation of behavior. We’ve all gone through this, where we get a request to add a tiny feature, only to find out that there is this cascading amount of changes that are required to implement it.

Feature envy is another common smell. This happens when one class or method, heavily leverages another class, repeatedly, for a wide variety of help in completing a task. See where the name comes from? The class is envious of the features in the other class. This creates an unnecessarily strong coupling between the two classes, which should be avoided when detected. We’ll eventually look at refactorings that help prevent this.

Refused bequest is an interesting smell, one that I’ve come across a bunch with UI code. Refused bequest is when a subclass wants all of the behavior of its parent class, except a certain piece. This happens a lot when subclassing UIKit classes, especially when you start to introduce multiple levels of hierarchy in your own code. Eventually, you’ll create a subclass, where you don’t want the subclass to have all of the behavior of its parent. This is a smell, and rather than code empty methods to override the parental behavior with essentially no ops, you should look to refactor this in a better way.

The last smell Fowler identifies is simply called, comments. And it’s just that, comments in code. I can totally relate to this one. I love how Fowler says that “comments are just deodorant on code smell.” If you find yourself needing to write an extraordinary amount of comments for a piece of code, take that as a sign that there’s probably a refactoring to be done that will help add clarity to the code. That being said, don’t let this stop you from writing comments in your code, just be aware when you all of a sudden write way more than usual for a piece of code.

There were actually a couple more subtle code smells I omitted, and I encourage you to go grab a copy of the book and check them out for yourself.

Looking ahead to chapter 4, it’s title is “building tests.” Fowler puts some clarification around how to build your tests to best support your refactoring. I hope you enjoyed this video from cleanswifter.com. until next time, happy cleaning.

Chris Eidhof on Table View Controllers

Are you following Chris Eidhof? If you’re not, you should be. He first came across my radar a couple years ago when was part of the founding team behind objc.io. I loved the monthly issues of objc.io, and I definitely recommend going to check out their back catalog if you haven’t already (despite some of it being written in Objective-C). I also really like Deckset, an app Chris made for easily creating beautiful presentations. And finally, I also read his book Functional Swift which honestly might have been my first formal introduction to real world functional programming outside of some academic exercises during my education.

Recently, Chris gave a talk at try! Swift in Japan titled Table View Controllers in Swift. I wanted to bring the talk to your attention because I think it’s a good example of refactorings and improvements you can make while implementing a table view controller in Swift. Go take a look.

My Highlights

Custom Initializers For View Controllers

It’s so easy to get sucked into the world of Interface Builder. Don’t forget that there is life outside it. Chris provides some solid examples of how you can leverage custom initializers for UITableViewControllers to provide the initial set of data, and even closures for populating table view cells. Nothing revolutionary here, but again, something easy to forget if you are always living in a world of Interface Builder.

Fix All In Scope

Do you know about this magical Xcode tool? I didn’t until I watched this talk. In a lot of ways, this is why watching talks are worth their time in gold. Even if the talk itself isn’t on a topic you’re totally into, just watching someone else code can yield so many little tips and tricks that will help you improve your own development. During this presentation, I learned from Chris of the option in Xcode to “Fix All In Scope.” I’ve only tried this in a couple cases, and it is magical. As you are coding, you’ll forget to force unwrap an optional, or something that was originally declared a constant with let now needs to be a variable with var. Xcode can automatically fix a lot of these issues for you, and there’s actually a menu option with an accompanying keyboard shortcut- Command-Option-Control-F. Give it a try.

Screen Shot 2016-05-26 at 8.58.48 PM

Refactoring View Controllers Crosses a Line

Watching this video with a co-worker, he said something that I agreed with. A lot of videos you watch, and blog posts you read, about refactoring view controllers, eventually cross a line from being useful to academic. I feel like this happened in the later part of this talk. Eventually the generalizing and refactoring led to a point where no two screens in an app are going to be so similar that you can use a single view controller implementation and be able to entirely reuse it. Despite that, there are plenty of things to be learned from “academic” implementations.

Refactor Out State

One pattern I really love in Swift that comes from functional programming is being able to use computed properties to help define the “truth.” Here’s an example:

var history:[String]? = nil
var canUndo: Bool {
  get {
    return (history == nil)
  }
}

This is similar to what Chris shows in his presentation for managing a history of changes to an editable table view. What I like about this, is that pre-functional programming, and back in Objective-C, I would create a instance boolean variable canUndo that gets set to true or false throughout the flow of code based on changes to the table view’s contents. That code is super prone to bugs, particularly because ensuring that canUndo is the correct value in all cases. By using a computed property like this to consolidate the truth in one place helps remove that uncertainty and proneness to bugs.

Refactoring A Complicated Initializer

As Chris moves through his refactoring of a table view controller, at one point he arrives at a custom initializer for the table view controller that has many parameters. Besides being hard to read, it also doesn’t really lend itself to testing that well. Chris’s refactoring creates a struct that represents each parameter in the custom initializer. Now, just one thing to pass as a value to the initializer whether from calling code, or the tests. Easy, and concise.

Try It Yourself

I’d love to hear what you think after watching the video, what were your takeaways?

Happy cleaning.

“Real World Mocking in Swift” talk by Veronica Ray

Today I watched a talk “Real World Mocking in Swift” by Veronica Ray hosted on realm.io. Mocks are something that I have found a TON of use for while striving to reach that elusive 100% code coverage from my unit tests. I have conflict on my mind on what the “right” amount of mock usage is, and I think Veronica hit a lot of important points in her talk.

A Tradeoff of Using Mock Objects

When using mock objects in your unit tests, there’s certainly a point at which readability and maintainability of your tests suffers in exchange for reaching 100% coverage. The tradeoff in my mind though, which is where I end up okay with these sacrifices, is that I rarely find the need to go back and change the code under test in such a minor way that the resulting changes to the tests are either minor tweaks, or major surgery to rewrite the tests. To say that another way, I feel better about the higher code coverage, despite less maintainable tests.

I Miss You OCMock

I used the hell out of OCMock during my days as an Objective-C developer. I loved how easy its API enabled me to quickly mock out 3rd party classes in order to test edge cases in my own code. I was bummed when I learned that the runtime hackery that enables OCMock simply isn’t possible in Swift. Since then though, I’ve come around to making my own mocks. It really isn’t that hard, it does take a little but more time, but I think it forces me to make some more protocol oriented choices in your code than I would otherwise have thought about.

Benefits of Mock Objects

Veronica specifically calls out three benefits of using mock objects that I totally agree with:

  1. It will make your tests faster.
  2. It will increase the coverage of your test suite.
  3. It will make your tests more robust.

Regarding #1, imagine you have a complicated method that runs a time consuming algorithm to tell you if some model object matches some criteria. When writing a unit test for a class that uses this algorithm, you don’t want to have to rely on this slow processing each time your tests run. By using mocks, you can simply force a response of true or false depending on what you’re trying to test, BOOM, FASTER!

As #2 states, mocks will increase the coverage of your test suite. I find this to be true especially with testing error handling. Often, some third party code I’m using will provide hooks for custom error handling in the event that things go wrong (imagine a failed object initialization). Without needing to reverse engineer the third party code, and intentionally code up a scenario in which the error handling will be triggered, you can simply code up a mock that forces the specific error scenario to trigger so you can write tests for your error handling code, BOOM, MORE TEST COVERAGE!

Along the same lines as writing a mock to simulate an error case for a failed web service connection, simply using a mock to provide a static API response is a great way that the #3 benefit is realized. You can then write tests that don’t depend on making a slow network connection and instead use the 100% reliable mock to always simulate expected response.

I don’t think anyone would dispute the value of mocks. I think it’s more of a cost/benefit tradeoff in one’s mind to buy in that the additional amount of coding is worth it.

Going Deeper on Mocking in Swift

There are a couple other topics that jumped out at me in this video that I’m going to save for dedicated posts throughout the rest of the week. Here’s a teaser:

  1. My reaction to Veronica’s claim that partial mocks are an antipattern.
  2. Veronica gives some guidelines as to “what makes a good mock.” I agree, and I’ll give you an anecdote of a time that I learned this lesson the hard way.
  3. Veronica talks about dependency injection. I learned of a cool way to do this with protocols when needing a different implementation per target.
  4. My opinion of using the term “mocking” to mean anything that is a “test double.”
  5. Veronica references some Swift mocking frameworks. I’ll provide getting started examples.

WWDC 2013 – Testing in Xcode 5

Ya’ll have it so easy with the tools that come with Xcode 7 to enable high quality code. Back in the day, Apple didn’t even recognize automated testing during WWDC (though tools were available in Xcode). It wasn’t until 2013 that a dedicated session to automated testing made the WWDC agenda. For posterity, go take a look:

WWDC 2013 – Testing in Xcode 5

or if you prefer, you can read it here.