Concurrency and Test Data in TestCafe

My thoughts on how to successfully setup and teardown data that will be used in your testcafe suite.

Fri, 21 Jun 2019

concurrency

unsplash-logoArdian Lumi

TestCafe is great. It makes it super simple to add e2e testing to your repertoire, making you not only the front-end engineer but the QA engineer too. In my time using TestCafe I have run into situations that I think are common to most test suites. Doing something like creating/deleting user data before and after tests while using concurrency can give you some trouble. I’ll show you how I’ve setup a project to handle this situation.

Setup/teardown data while trying to use concurrency.

Running your tests in parallel is important to make sure your test runs are fast. I always have at least 4 running at the same time by using the concurrency option.

$ testcafe -c 4 chrome:headless tests/test.ts

I’d also like to create users before my test is run. My first thought was to use the fixture.before hook to create those users, then use the fixture.after hook to delete them. This would only work however if I used different users for each fixture since if I was running tests in parallel, users could possibly be deleted before another test is finished executing, throwing errors and failing tests.

// test-one.ts
import { addUsers, removeUsers } from './some-custom-module';
...
fixture('Fixture 1').page(...)
 .before(async () => await addUsers();)
 .after(async () => await removeUsers();)

// test-two.ts
import { addOtherUsers, removeOtherUsers } from './some-custom-module';
fixture('Fixture 2').page(...)
 .before(async () => await addOtherUsers();)
 .after(async () => await removeOtherUsers();)

As you can see, each fixture is independent from each other. Running these parallel shouldn’t give you an issue and most likely solves the more common use cases for setting up and tearing down data.

But what if you have multiple fixtures that will all use the same users? You would not be able to do what is shown above. Something you could do instead is create and delete users when you create the test cafe runner:

//testcafe-config.js
const userService = require('some-module');

createTestCafe('localhost')
  .then(tc => {
    testcafe = tc;
    // Run code to add users
    userService.addUsers();

    const runner = testcafe.createRunner();
    return runner
      .src('...')
      .browsers('...')
      .run();
  })
  .then(failedCount => {
    console.log('Done: ', failedCount);
    //Tests are done, cleanup those users
    userService.removeUsers();
    testcafe.close();
  })
  .catch(error => {
    //Just in case there's an error
    userService.removeUsers();
  });

Now all fixtures in your suite will have access to the same test data. Remember this means that if you were to do something like modify the user’s name in one fixture, but test for that same user’s name in another fixture, you could get a failure. If you want to create data in this way, I’d say to only create read-only data that will not change from within a fixture.

If you’ve come up with other ways to setup and teardown test data, let me know in the comments.

Also if you want to learn more about TestCafe, take a look at my course End-to-end Web Testing with TestCafe: Getting Started on Pluralsight

Thanks and Happy Testing :)

Get $100 Off Pluralsight Premium and Personal Annual Subscriptions

Loading...
marques woodson

Marques approves this article.