Skip to main content

First Tests for iOS and Objective-C

Now that I have some basic UI elements working and some Data Objects defined and those Data Objects are persisted to a Database. Its time to start working on some logic, and before we do any logic, we want to have Tests in place. Red of the Red, Green, Refactor mantra. I want to keep track of every entry made throughout a day, and then when the day changes over, consolidate all of the previous day's records into 1 history record so that the user will be able to see how they have progressed over time. Date logic is always fun, so I am really glad to be starting out with a Test rather than assuming that my date comparisons will work as I expect them.

In .NET you denote a Test Method by giving it an Attribute, and then treating it like any other method. Here in Xcode, you denote a Test Method, but having the method's name start with lowercase test, and then you add the test name after it. I've grown accustomed to naming my Test Methods very verbosely and descriptively to make sure that their intent is clear. needing to start the name with test probably won't affect me much, but I think I will probably name my methods with that in mind. For instance, where I would have normally called a method, IfValueIsZero_ReturnZero, here I think I would name it, testForValueZero_ReturnsZero. Taking that leading test into account and trying to make the the name read using test with the rest of the name.

First thing I work on is to make sure my object is initialized. Interestingly I find out that you can't really create an object that is derived from NSManagedObject without giving it a context. It must be using that context to create the object, even given that I have generated subclass files that contain the properties associated to that subclass, the object can't be initialized.

Given that I don't want my tests to be tied to the Data side of the Data Objects, I want to put my logic in a location that can be accessed without knowledge of the Model or Data Context. In VB I would create a Shared, or Static, function to do the work and give it the parameters it needed to perform the logic needed. Looking into how to create a Static method led me to another interesting discovery. To mark a method as Static you use the + symbol before the return type, and to make is not Static, you use the - symbol. I had seen those and had assumed to this point that + was for a public and - for a private method. Instead I find out that + can be used without an instance of an object and - need to have an instance before it can be called. Does that mean there is no notion of public and private function, or have I just not discovered how to mark methods for that yet?

After talking with my coworker, David, he explained to me how to make a method/property/variable public or private. If you add the declaration in the header, .H, file then it is public. You can define them in the implementation, .M, file and then they will be private. This starts to make sense as you are only importing the header file into other files, so they would only know about what they can see in the header file.

David also expanded upon using a Category for a class. It turns out to be very much like a partial class in .NET. The Category, adding to a class by defining the Category name after the interface name in a separate file. Then using the ClassName+CategoryName as a means of asking for that new interface. When you are using Categories, you only need to import the Category header file as it will bring along with it the base class information. Once you have imported that header file you get access to all public methods of the base class and the Category. Then at compile time, just like a partial class, the base class and Category get compiled together and are treated as 1 Class.

Getting back to the Tests. For my first test I want to compare 2 dates. I start out with the simplest thing I can think of, Is one Date object equal to the same Date object? There is a method for comparing Dates in objective c, named compare. So I create a new Date object and pass it into my method in both parameter places. I assert that the result returned in True. In my method I use that compare function and return the results. It works, as you would expect it would. Next I choose to test a Date from January to a Date in May. Assert that my function returns false, and of course it fails. Wait What? How on earth can something this simple fail? I assume that it is likely due to my knowledge of Obj-C, but at least I created a test and made sure that the logic I am using does what I want it to do before just blindly writing my app. If I had done that, I would be stuck trying to debug the app, wondering why things were not working as expected. Now I know before I get to that point, that there is a flaw in my logic that I need to address before moving on.

I have been reading, Test Driven Development: By Example , by Kent Beck. It is a fantastic book if you are interested in TDD. It has been very inspirational in that I always want to strive to improve how I am Testing when I read it. It is also very educational. One trick that I learned from reading it, something that I was not previously doing, is to leave a programming session with a failing test. This may seem counterintuitive at first, but his reasoning makes a ton of sense. If you leave your project with all passing tests, then when you come back to it, you will likely have to spend time remembering what you were doing and get your mind back to where you were when you left. If however, you leave a failing test behind, then when you return to your project you can run your tests, find the failing test, and know exactly where you were at. You will be able to jump right back in to your code and continue on from there.

Given this advice, I am going to leave my project with this failing test, and come back to it next time. I will know that my expectation of Date compare was wrong, and will be able to set about finding out where my logic is failing and what to do about fixing it.

Comments

Popular posts from this blog

Converting a Large AngularJS Application to TypeScript Part 1

I work on a project that uses AngularJS heavily. Recently we wondered if using a preprocesser like CoffeeScript or TypeScript for our JavaScript would be beneficial. If our team is going to switch languages, we would need to be able to convert existing code over without much pain and we would have to find enough value in switching that it would be worth the conversion. I had read an article that stated that because TypeScript is a SuperSet of JavaScript, you could convert a plain JavaScript file to TypeScript by changing the extension to .ts and not much else would need to change. I wanted to test out this claim, so I took a file that I was familiar with, an Angular Controller, and tried to convert it to TypeScript to see how much effort it would take and then try to figure out where we would benefit from using TypeScript. This is what the controller JavaScript file looked like to start out with: ( function () { 'use strict' ; angular .module( 'app'

Interns: Taking off the training wheels

My intern team has been working for several weeks now on our new website. We have already completed one deployment to production and are finalizing our second one. We started with a plan to release often adding small bits of functionality as we go and so far that plan has been working really well. We already feel like we have accomplished a lot because we have completed many of our project's requirements and should easily be able to complete the rest giving us time to do even more than just the original requirements. One of the things I have had some difficulty balancing has been how much to lead the interns and how much to let them figure out on their own. In deciding what our team process should be and how we should allocate our time, I think it was important for me to do more leading. I saw some deficiencies in how we were currently working and brought up some ideas for how we could address them. We had moved into spending all our time just working through stories and did not

My idea for Hearthstone to add more deck slots

Recently someone asked the Blizzard developers for more slots for decks in the game Hearthstone. The response was that they are talking about it and looking into it, but no decision has been made yet. One of the concerns over adding deck slots is that it could complicate the UI for Hearthstone and make it more difficult for new players to understand. I have what I think would be a good solution to add more deck slots without increasing the learning curve for the game much if at all. First I would take a look at the current selection screen for starting to play a game. It defaults to showing the decks that are custom built by the player if they have any custom decks, and there is an option to page over to the basic decks. This basic deck screen is perfect for how I would change this process. Instead of having 2 pages of decks, 1 for basic and 1 for custom, you would just see the select a Hero screen. Then once you selected the Hero you wanted, you would see all of the decks that