mokacoding

unit and acceptance testing, automation, productivity

Quick beforeSuite and afterSuite behaviour

After I shared this little post about Quick beforeEach and afterEach with the team at iflix, Gerald popped a question in our chat:

Gerald's question: how does beforeSuite fits in the calls hierarchy?

Here's the documentation these two functionalities:

beforeSuite

Defines a closure to be run prior to any examples in the test suite. You may define an unlimited number of these closures, but there is no guarantee as to the order in which they're run.

afterSuite

Defines a closure to be run after all of the examples in the test suite. You may define an unlimited number of these closures, but there is no guarantee as to the order in which they're run.

The example code from the previous example has been updated adding calls to beforeSuite and afterSuite.

import Quick

class Spec: QuickSpec {
  override func spec() {
    beforeSuite {
      print("☕️ before suite")
    }

    describe("beforeEach and afterEach behaviour") {
      beforeEach {
        print("⭐️ top before each")
      }

      context("some context") {
        beforeEach {
          print("👉 context before each")
        }

        // ...
      }

      afterEach {
        print("⭐️ top after each")
      }
    }

    afterSuite {
      print("🗑 after suite")
    }
  }
}

In the code above beforeSuite and afterSuite are positioned at the very top and very bottom of the test, but you can put them anywhere inside a describe or context.

Can you guess how the console log will look like?

☕️ before suite
😈 an after suite call you weren't aware of

behaviour - some context - example 1
⭐️ top before each
👉 context before each
😊 example 1
👉 context after each
⭐️ top after each

...

behaviour - other context - example 2
⭐️ top before each
🍎 context before each
😜 example 2
🍎 context after each
⭐️ top after each

🗑 after suite
😈 an after suite call you weren't aware of

Hang on a second, where do those 😈 logs come from?!

The danger of using beforeSuite and afterSuite

Quick will look for all the beforeSuite and afterSuite calls in all your test suite, and run them respectively all at the start and all at the end.

Those unexpected 😈 console logs are simply defined in another spec in the project.

This is one of the danger of beforeSuite and afterSuite, there is no way other that by doing a text search to know how many such calls there are and where.

As time passes one might even forget having added those calls. That's a recipe for issues that are hard do debug.

The other danger is that being able to fiddle with state in the unit tests can lead us to write tests that are not as isolated and robust as they should be. If unit tests are isolated and simple to setup then the code they test will be simple and easy to setup as well.

Yes, beforeSuite and afterSuite can be life savers when you need to get started writing test on legacy code and you really cannot take out certain assupmtions baked in it. They allow you to work around them, and get the job done.

In such cases though, I would encourage you to leave a big FIXME note there:

// FIXME: Doing this now because the app makes assumptions that impact each
// unit test.
//
// Need to allocate proper time to refactor for isolation.
//
// If you are reading this comment after <date> get in touch with <person>.

Until next time:

👋 Leave the codebase bettern than you found it

Vote on Hacker News