The Unit in Unit Testing

The Unit in Unit Testing

The Unity Test Framework (UTF) enables Unity users to test their code in both Edit Mode and Play Mode, and also on target platforms such as Standalone, Android, iOS, etc.

Key Takeaways

  • Unit tests should increase confidence that our code works correctly, allow us to document how our code should function, and aid in designing loosely coupled, highly cohesive software.
  • Unit tests are isolated from the rest of the codebase, which helps them to be fast to run, simple to write, and easy to understand and maintain.
  • Test doubles, or objects that take the place of collaborators, can help to facilitate the isolation of unit tests.
  • The heavy use of mock objects in unit tests provides a lesser degree of confidence that the behaviour under test functions correctly.
  • A fake object can keep a unit test isolated while increasing confidence that it tests the desired behaviour.

No alt text provided for this image


Background

Developers often use test doubles as a way to facilitate this isolation. A test double is any object used in a test that takes the place of a collaborator. In his book xUnit Test Patterns, Gerard Meszaros defines several categories of test doubles: dummies, spies, stubs, fakes, and mocks. For our purposes, we’ll focus on the last two:

  • Mock objects are pre-programmed with specifications of the calls they expect to receive and their response to these calls. They have a mechanism to verify that they receive the correct calls during a test and will fail the tests if the calls don’t match their expectation. People often use frameworks like Mockito, Mockk, or GoMock to create mock objects.
  • Fake objects are functioning implementations of collaborators that take some kind of shortcut to make them more suitable to run in a test environment. For example, a developer might create an in-memory datastore to take the place of an object that saves data to S3 to run the tests locally.

Isolation

  • There’s general agreement that the word unit in unit testing refers to units of isolation,. That is, unit tests are isolated, at some level, from the rest of the codebase. However, opinions differ when defining what the unit is that is being isolated.

Test isolation

Kent Beck, representing the classical approach to testing, argues that

“Unit tests are completely isolated from each other, creating their test fixtures from scratch each time.”

In this approach, the word unit in unit testing refers to the test itself: unit tests are isolated from other tests. Beck argues that “tests should be coupled to the behavior of code and decoupled from the structure of code.” 

Tests written using this approach tend to have few mocks. They instead use instances of collaborating objects and even real supporting infrastructure (such as databases) to support each test run.

 Subject isolation

Steve Freeman and Nat Pryce, representing the mockist approach to testing, argue that

“[unit tests] exercise objects, or small clusters of objects, in isolation.”

Freeman argues that unit tests are “important to help us design classes and give us confidence that they work, but they don’t say anything about whether they work together with the rest of the system.” In this approach, the word unit in unit testing refers to the subject being tested.

Tests written using this approach must use test doubles to stand in for collaborators and tend to have many mocks.

In practice

To determine the approach to use in practice, we must first enumerate the goals we are trying to achieve by writing tests. We want to:

  • Increase confidence that our code works correctly.
  • Document how our code should function.
  • Aid in designing loosely coupled, highly cohesive software.

With these goals in mind, I’d argue to start with the test isolation approach to unit tests. If each test runs reliably in isolation while using as many real collaborators as possible.

Conclusion

When determining your testing approach, think carefully about your approach to unit isolation, so you’re aware of the benefits and tradeoffs of starting with a classical or a mockist approach. Always be willing to adapt your approach depending on the nature of your collaborators. Ultimately we all want a fast, reliable test suite that gives us the confidence to ship, documents our intentions clearly, and helps us to design an extensible system.

To view or add a comment, sign in

More articles by Amber Sharma

  • Manual Testing

    How does manual testing work? When a new programme is put through manual software testing, human testers examine it for…

    4 Comments
  • Software Tester - Roles, Responsibilities & Skills

    Software testing is the process of evaluating and verifying that a software product or application does what it is…

    3 Comments

Others also viewed

Explore content categories