• 20 hours
  • Medium

Free online content available in this course.

Videos available in this course

Certificate of achievement available at the end this course

Got it!

Discover tests

Log in or subscribe for free to enjoy all this course has to offer!

We've now reached the part where we’re going to expand our knowledge on tests in general and learn about Unit Tests in detail!

Testing, I must admit, is a big part of the development process. Knowing how to test and when to perform the right type of test will make this process so integrated into your daily routine that you won't even be consciously separating the code writing and testing processes. 💪

Discovering tests

So, what are tests? 🤔

Tests are supporting elements of the main application. They allow us to ensure that a tested application performs as expected.

Manual vs. Programmatic/Automated tests

What has been your development process so far? Perhaps you've completed writing some code to perform an exciting function - like popping up a unicorn on the screen after a user has been holding a phone up vertically for 30 seconds. Sounds fun, doesn't it?

And what do you typically do next? I bet you hit the Run button in Xcode and patiently wait for the app to load on your device, hold the phone up... and expect a marvelous unicorn to pop up! 🦄

Well, that's testing! Ensuring that functions performs as hoped for... and, maybe doing a little dance when it does. 💃

You've already performed actions to ensure your app functions as expected!

In terms of execution method, tests can be:

  • Manual - performed by humans,

  • or Programmatic - performed by computers. These are also called automated tests.

Manual tests are performed by developers, QA/QC teams, and, ultimately, users.  They are typically more time consuming and less reliable due to human error or, simply, due to unreasonable expectations of testing all possible variations in the app's performance. 

Manual tests are not scalable, in fact, the more code you add, the more you need to test and re-test.

Programmatic/Automated tests require whitening some test code by developers and then are performed by a computer - sort of like another application. They are incomparably more reliable as they guarantee consistent performance. The human factor plays an insignificant role in automated tests. They are also prone to human error; however, once spotted, they can be fixed and used an endless number of times without a fail.  

Programmatic tests are scalable - written once, run virtually an infinite number of times! 

Development classification of tests

In the context of the development process, I’d like to highlight 3 types of test:

  • Manual tests

  • Functional tests

  • Unit tests

We'll focus on the three types above as we encounter them the most as we start our development career.

To indicate the place each of the types takes in the development process, we can use a pyramid as an illustration:

Pyramid of test types
Pyramid of test types

At the top of the pyramid are Manual tests. This group of tests typically refers to a test ran without strategy; they are virtually random. You'll use them all the time; however, they aren't sufficient as they are:

  • ...slow and time consuming. It's necessary to compile the code, to launch the app in Simulator or on a device. On top of that, sometimes it takes several actions before accessing a test spot, i.e. reaching a specific view in the navigation that is not the first view of an application.

  • ...unreliable. With manual tests, we can check that an action works, but it's not enough. We should also verify that it hasn't broken other features of the application. And, finally, for the manual tests to be reliable, every time we change some code, it will be necessary to re-test the whole program. Regardless of your ambition, this will tire you pretty quickly! 

  • ...non-scalable. The more code you write, the more you'll need to test and even more to re-test. 

Does that mean you should resist pressing the Run button?

Of course not! It's fun to test on a device and simulator - go ahead, keep doing so. As longs as you are not using it as a reliable tool to ensure that you are creating a valid code. And, obviously, make sure you aren't wasting your time!

At the very bottom of the pyramid are Unit Tests. These are automated tests written by developers and performed by computers. They are very reliable and should be extensively used to benefit the quality and efficiency of code production.

And, finally, we have Functional Tests in the middle of the pyramid. They can be manual or automated. If performed manually, they are typically strategic and based on a test plan. Automated tests of this kind in context of iOS typically refer to UI Tests.

That's it in a nutshell. Let's expand a bit on the two bottom layers.

Unit Tests

Unit tests allow you to test very small units in your code. This is also the reason that there are typically many of them per application. A unit test will test a single method of a single class. If a method serves multiple purposes, it may need several tests to cover it.

Let's do an example, with the following class:

class Person
    var age = 0

    func celebrateBirthday() {
        age += 1
    }
}

If we want to test the celebrateBirthday  method, we need to create a unit test - a small piece of code that would do the following:

  • Create an instance of the Person  class with an age  property of 12 for example.

  • Call the celebrateBirthday method on this instance.

  • Check that the  age  property is now 13.

Let's repeat: a Unit Test is a small piece of code that will test a small unit of a program. Hence the name Unit Test! 😉

When creating a unit test, we feed it a predefined output. If the result produced by executing a method matches the predefined result, the test is considered successful.

The following diagram illustrates the process:

Unit testing process
Unit testing process

Functional Tests

So, we can poke around manually or we can be very meticulous and create a variety of necessary unit tests. Now, to cover the quality of the functional scope of an app, let's review functional tests!

Functional Tests allow to test a complete functional element of an application (and, ultimately, the whole application). An example of a functional element could be a login path (referring to a user path).

In iOS, functional tests are typically called UI Tests because they are tightly associated with the UI and rely heavily on user interactions and feedback.

The principle of UI testing is that we assign the simulator a number of actions to perform (press a particular button, return to the previous view, swipe down, etc.) and then we request to verify that a resulting screen matches what's expected.

Even though functional tests can be manual, automated implementation is more common and, of course, more efficient and faster.

When app tests are implemented as automated tests, the computer follows a scenario it was given on the UI of an application.

Making testing choices

Knowing what we know now, how do we apply this new knowledge to our project? Which tests should we perform to ensure the correct functionality of the app?

Manual tests are useful and inevitable for quick checks here and there. And automated tests will always have your back!

In this course, we'll settle for these options:

1. Using manual tests for quick checks and... for fun (we want to play we the app in the process!)

We can't avoid manual testing completely. It's a good way to see if the app works as a whole and especially because we can always trust what we see! (Well, at least if we spot a flaw, it needs fixing. If everything appears alright to our eye, this may or may not be the case. Sigh. 😅)

We'll continue doing manual tests, so don't hesitate to click that Run button, but don't rely exclusively on it - this approach is slow and unreliable in the long run!

2. Trust automated tests

Functional tests and unit tests have the advantage of being automated. So they will allow us to test our entire code.

OK, but should we use both? If not - which one to choose? 

Typically, if your app is relatively small and well-architected, and if you are a detail-oriented person with high standards for quality, unit testing should be enough. 😉

But why is that so?

If your program is well-architected with all the logic of your application well arranged in classes where each class has a clear role - it's easily testable using unit tests.

In addition, unit tests have two advantages over functional tests:

  • They are faster to execute. While functional tests require the launch of an app followed by an action scenario, unit tests boil down to evaluating a boolean - pass or fail.

  • Unit tests are easier to write and maintain because each of the tests corresponds to a small unit of the program.

Let's Recap!

  • There are two executional types of testing:

    • Manual

    • Programmatic, or, automated

  • There are generally 3 types of testing involved in the development process:

    • Unit Tests

    • Functional Tests

    • Manual Tests

  • Unit tests are programmatic tests that are used to validate a small piece of code, typically a method  or a function.

  • Functional tests can be programmatic or strategic manual, and they are used to test a complete feature of an application.

  • Manual tests are performed manually and are typically non-strategic. They are used to (somewhat randomly) test a specific function or an app as a whole. They are not scalable and are unreliable as the only testing approach for an app development. 

Example of certificate of achievement
Example of certificate of achievement