16

I have never used Unit Testing and I understand the uses of it but I don't really know when and how to use it.

I would like to know when it's worth it to use Unit Testing, maybe with some examples.

shim
  • 9,289
  • 12
  • 69
  • 108
k20
  • 2,008
  • 1
  • 17
  • 23
  • 2
    "when it's worth it to use Unit Testing" - some argue that it's always inevitable; I'd say it's only necessary for larger projects **and** libraries. –  Dec 14 '12 at 18:40
  • 1
    Search [here](http://stackoverflow.com/questions/33207/what-is-the-best-way-to-unit-test-objective-c-code). Complete information on unit testing options and tutorials. – rsswtmr Dec 14 '12 at 18:45
  • 1
    A good use is when you have a app that makes url connections to a server. You can set those up separately in the unit test, to test them without having to run the app. – Yuliani Noriega Dec 14 '12 at 18:48
  • I think you'll learn as you program more, that the slightest changes you make to some seemingly insignificant piece of code can have detrimental consequences that you could not have possibly foreseen. Unit testing, amongst other things and when done properly, can help protect against bugs that may arise from slight code changes. – Snowman Dec 14 '12 at 19:56

4 Answers4

19

The other answers tell when but not really how, so let me add an answer also.

When

Any time you are writing production code that you are going to keep, you should have Unit Testing for it. The most helpful training that I saw on this was the following 2-part video series:

The first five minutes or so are just intro so you can skip to the end of that.

How

I am using Xcode 7 with Swift.

Start a new project and add a Unit Test.

I am calling mine MyProject. If you open the MyProjectTests group in the Project Navigator, you will see that Xcode has already created a Unit Test file for you called MyProjectTest.swift.

enter image description here

You can delete all the example methods for now and add a new func to test your own class method. Be sure to add the line @testable import MyProject at the top. If your project name has spaces in it then replace the spaces with underscores. (For example, "My Example Project" would use @testable import My_Example_Project.)

I am following the naming pattern of testMethodNameBeingTested_Senario_ExpectedBehavior. Unit Test names must begin with "test".

I will do something like this:

import XCTest
@testable import MyProject

class MyProjectTests: XCTestCase {
    
    func testSum_TwoNumbers_ReturnsSum() {
        // Arrange (set up the needed objects)
        let myClass = MyClass()
        
        // Act (run the method you want to test)
        let sum = myClass.sum(1, 2)
        
        // Assert (test that the behavior is as expected)
        XCTAssertEqual(sum, 3)
        
    }
}

Of course, the build fails because we haven't added the MyClass class yet.

Add your class.

I am adding a Swift file to MyProject called MyClass.

class MyClass {
    
    func sum(a: Int, _ b: Int) -> Int {
        return a + b
    }
}

Press the test button next to the Test Unit Class or method to run the test again and it should pass.

To see it fail (an important part of Unit Testing) you could do something like return 0 in the sum method of MyClass. Then you would see the following when you run test:

enter image description here

You can go back and fix this and then add more Unit Tests. You can also make other Unit Test files for different classes if you like. Just right click the MyProjectTest group in the Project Navigator and choose "New File" Then choose Test Case Class.

enter image description here

Related

Xcode UI Test example

Community
  • 1
  • 1
Suragch
  • 484,302
  • 314
  • 1,365
  • 1,393
  • What do you mean `If I were really following TDD principles I would only add the function name, not return the correct value yet. `? The only place that is returning the correct value is in the test (3). You mean you would write only the function name in the test? Please explain. Thank you. – Edison Mar 05 '19 at 03:12
  • @tymac, I think I meant that I would write the class method, have it return `0`, run the test and watch it fail, fix the method, and then run the test again and watch it pass. My sentence was confusing, though, so I just removed it since TDD wasn't the topic of this answer anyway. – Suragch Mar 05 '19 at 16:59
  • Thanks. Good to know though, – Edison Mar 05 '19 at 18:33
13

You should almost always unit test and you should write code with unit tests in mind. The extremists write tests even before writing the code (it's called TDD - Test Driven Development).

I'll give you a real life example: I recently had to code a sorted NSArray that supports "intervals". Meaning, the array should know how to insert an interval and keep it sorted.

For example, the array would look like this: [1-3, 5-9, 12-50]. In this example there are 3 intervals in the array, and as you can see they are sorted. After I wrote my class (I called it IntervalsArray), I HAD to write tests to make sure that it works correctly and that I will not "break" it if I or someone else make changes to the code in the future.

Here are some example tests (pseudo-code):

Test 1:

- Create a new IntervalsArray
- Insert a new interval to the array
- (TEST) make sure the array has 1 object in it

Test 2:

- Create a new IntervalsArray
- Insert 2 intervals into the array: [1-3] and [5-9]
- (TEST) make sure there are 2 items in the array
- (TEST) make sure interval [1-3] comes before interval [5-9]

At the end I had something like 15 tests to cover every aspect of my new array.

Here's a good unit-testing with Xcode tutorial.

You can also write logic tests (which are more complicated than unit tests) to test your UI. Read a little about UIAutomation, which is Apple's way of testing UI. It's not perfect, but it's pretty good. Here's an excellent tutorial about this.

If you consider yourself a good programmer, you should write unit-tests for your code.

Eli Ganem
  • 1,479
  • 1
  • 13
  • 26
3

Write unit tests any time you write code that you'll have to maintain. That is, if you ever want to refactor anything — changing the code but keeping the behavior. Which is pretty much every bit of production code.

The counterexample of "Hello, World" is not to bother with code you plan to throw away. A "spike solution" is just to figure out how you might approach a problem. Once you've figured it out, throw it away and start again. Only this time, you start with tests.

Calling TDD "extremist" makes it sound irrational and impractical. In fact, once you learn TDD, it saves time/money.

See Unit Testing Example with OCUnit for an example of how TDD works.

Community
  • 1
  • 1
Jon Reid
  • 20,545
  • 2
  • 64
  • 95
1

Any time your writing an application that has classes, that are not your own. That is a good time to add unit tests, to test those classes.

All but the most basic apps will have their own classes, so its almost always a good idea to unit test.

If you are creating libraries that other programmers will use, or that you will use in multiple projects, those should always have unit tests.

Unit tests save you a lot of time when things change, for instance, a new version of the OS comes out, it is much better to test with the unit tests then to just test the app.

nycynik
  • 7,371
  • 8
  • 62
  • 87