By Developers, For Developers

Historical errata for iOS Unit Testing by Example

PDF PgPaper PgTypeDescriptionFixed onComments
9OK

I’d recommend images that span the width of the PDF…ish. Obviously it needs to be OK on mobile devices (I’m on a Mac, following along with the walkthrough). It took me a second to orient myself to the error image in the PDF because `XCTFail()` is so close to the “red bar” in the image, but it’s way across the screen on Xcode. I’ve seen that before, so it’s no big deal. But then the error image lower on the page is a different width.

So possibly use a “screenshot” (lineshot?) that shows the source code line number in it (though irrelevant) and have all of these images have the same width (in pixels)? Maybe it would break Kindle or PDF on iPhone, but a tiny bit more consistency wouldn’t hurt.

All that said…it’s not a big deal.

2019-06-10I think it would be hard to optimize images across all devices.
15OK

The font makes \\ very hard to distinguish from |. And the erratum reporting text box makes it wonky to use ` to surround my code like I do in Slack…

2019-06-10I agree that the italicization of string literals makes this hard to see. But I don't think there's anything I can do.
24SUGGEST

“Instead of Test Zero, which is a personal trick, this is standard practice for Swift test code.”

I think you sell yourself short by calling Test Zero a personal trick instead of putting it on par with the next step of writing a test of your app code. I think what you’ve shown is a microcosm of refactoring tests: the first step is to get a test that runs and fails, then you refactor the test name and wire it to actual code.

Perhaps something like this would give your idea the credit it deserves?

“Let’s refactor test_zero into a test of our first method by changing its signature to test_methodOne and creating an instance of MyClass to test.”

The thing I’ve seen is that too many people get so overwhelmed at the idea of what it takes to start testing their code, that I think that if they could see test_zero run then they feel some kind of progress and move on to the step of actually pulling in their code. I think you’ve proposed an important step for introducing testing to iOS devs (who often push back on testing), and I wouldn’t shortchange it or underestimate the simple power of seeing progress quickly.

2019-05-31
9TYPO

There appears to be a hanging blue box rendered on the next page from the previous page’s “Isn’t the Class a Test Case?” section.

2019-07-03
58ERROR

It appears when following along with the code, the real and testing app delegates are chosen correctly, however the book states that when running the tests, you should see:

<< Launching with testing app delegate
Window: nil
Root VC: nil

However, this is not the case. Downloading and running your code in XCode Version 10.2.1 (10E1001) results in the following output in the console:

<< Launching with testing app delegate
Window: Optional(<UIWindow: 0x7fc606419fc0; frame = (0 0; 414 896); hidden = YES; gestureRecognizers = <NSArray: 0x600003064fc0>; layer = <UIWindowLayer: 0x600003e57ac0>>)
Root VC: Optional(<UIViewController: 0x7fc60641a990>)
Test Suite ‘All tests’ started at 2019-06-20 09:41:58.671
Test Suite ‘AppLaunchTests.xctest’ started at 2019-06-20 09:41:58.671
Test Suite ‘AppLaunchTests’ started at 2019-06-20 09:41:58.672
Test Case ‘-[AppLaunchTests.AppLaunchTests test_emptyJustSoWeHaveAPassingTest]’ started.
Test Case ‘-[AppLaunchTests.AppLaunchTests test_emptyJustSoWeHaveAPassingTest]’ passed (0.001 seconds).
Test Suite ‘AppLaunchTests’ passed at 2019-06-20 09:41:58.674.
\t Executed 1 test, with 0 failures (0 unexpected) in 0.001 (0.002) seconds
Test Suite ‘AppLaunchTests.xctest’ passed at 2019-06-20 09:41:58.674.
\t Executed 1 test, with 0 failures (0 unexpected) in 0.001 (0.003) seconds
Test Suite ‘All tests’ passed at 2019-06-20 09:41:58.675.
\t Executed 1 test, with 0 failures (0 unexpected) in 0.001 (0.005) seconds

2019-07-03
32ERROR

The link “Design Patterns: Elements of Reusable Object-Oriented Software [GHJV95]” does not work. I’ve experienced this in my own book projects, and I believe the issue is that long links get broken in PDFs. You may want to use shortlinks throughout the book to avoid this issue.

2020-03-18
83SUGGEST

1. You switch from MySingletonViewController to MySingletonAnalytics. It would be helpful to mention that in text, e.g., "
Add a new static instance with a different name to MySingletonAnalytics."
2. It would be helpful if you clarified that you want to append to the existing code in track(event:), e.g., “Add the following code…” instead of “Also update the…”

2020-03-18
83SUGGEST

1. You switch from MySingletonViewController to MySingletonAnalytics. It would be helpful to mention that in text, e.g., "
Add a new static instance with a different name to MySingletonAnalytics."

CORRECTION: Disregard this suggestion. I just realized that you actually did want to change, not append:
2. It would be helpful if you clarified that you want to append to the existing code in track(event:), e.g., “Add the following code…” instead of “Also update the…”

2020-03-18
84ERROR

Attempting to run tests results in build error, “Build input file cannot be found.” This is due to the instruction, “Also delete that initial test file, HardDependenciesTests.swift.,” on page 79.

2020-03-18
86ERROR

Should include @testable import HardDependencies with defining TestableOverrideViewController.

2020-03-18
89SUGGEST

Regarding the text: “By declaring it lazy, the property won’t have an initial value. Once it’s accessed, it will receive the value—but only if it doesn’t already have one.”

One caveat here is that two Analytics instances will be created.

In other words, by simply accessing the value in order to set it, the lazy setter is executed. This can be verified by changing Analytics as follows:

1. Change shared to static let shared = Analytics(caller: “lazy setter”)
2. Add this initializer:
init(caller: String = #file, line: Int = #line) {
print(Self.self, #function, caller, line)
}

Then run the test and observe the console output:

…
Analytics init(caller:line:) …/InstancePropertyViewControllerTests.swift 18
…
Analytics init(caller:line:) …/Analytics.swift 12

Here’s what’s happening:
1. The first one (line 18) is the initialization of Analytics within the test, before it is assigned to sut.analytics.
2. The second one (line 12) is the lazy setter initialization of Analytics in Analytics, triggered by sut.analytics = … in the test
3. The first one is assigned to sut.analytics

One way to prevent this would be by declaring a pair of properties and an explicit setter…

private static var _shared: Analytics!
static let shared = _shared ?? Analytics(caller: “get setter”)

static func setShared(_ analytics: Analytics) {
_shared = analytics
}

…and then calling setShared(_:) in the test.

Fairly unpleasant, but it works. \\/

2020-03-18
5441SUGGEST

I had to select Editor > Code Coverage to see the red gutter for code coverage. You might want to mention this as well.

Book v. beta 8.

2020-03-18
38ERROR

The book says to go to Xcode -> Preferences, select Text Editing category with the Editing tab. In Xcode 11.3.1 ‘Show iteration counts’ doesn’t appear to be here.

2020-04-15
222TYPO

In “Add Tests for Existing Code” section, there’s the following sentence that contains an excess “be”.

“This means we need to reason about how the code is supposed to be behave.”

587TYPO

In chapter 13, in “Parse the Response” section, there’s a sentence that goes “Define SearchResult so that in conforms to the Equatable protocol”

typo - so that in … it should be - so that it

Categories: