Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,12 @@ Blog post about `qunit-retry` available [here](https://blog.mrloop.com/javascrip

### Set Max Runs

The default maximum number of retries is 2 (one attempt and one retry). To change it globally, pass an additional argument to the `setup` function:
The default maximum number of retries is 2 (one attempt and one retry). To change it globally, pass the `maxRuns` option to the `setup` function:

```js
const setup = require('qunit-retry');

const retry = setup(QUnit.test, 3); // sets maxRuns to 3
const retry = setup(QUnit.test, { maxRuns: 3 });
```

To change it for a single test, pass the number of retries as the third argument:
Expand All @@ -54,6 +54,16 @@ retry("a test relying on 3rd party service that occasionally fails", async funct

**Note:** It is generally advised to use the retry sparingly and this advice extends to setting a large number of retries.

### Resetting environment between retries

If you need to reset the environment between retries, you can pass a `beforeRetry` function to the `setup` function:

```js
const setup = require('qunit-retry');

const retry = setup(QUnit.test, { beforeRetry: () => resetEnvironment() });
```

Install
------------------------------------------------------------------------------

Expand Down
22 changes: 11 additions & 11 deletions main.js
Original file line number Diff line number Diff line change
@@ -1,36 +1,36 @@
import Retry from './src/retry.js'

export default function setup (testFn, defaultMaxRuns = 2) {
export default function setup (testFn, { maxRuns: defaultMaxRuns = 2, beforeRetry } = {}) {
const retry = function (name, callback, maxRuns = defaultMaxRuns) {
return new Retry([name], callback, maxRuns, testFn)
return new Retry([name], callback, maxRuns, testFn, beforeRetry)
}
retry.todo = function (name, callback, maxRuns = defaultMaxRuns) {
return new Retry([name], callback, maxRuns, testFn.todo)
return new Retry([name], callback, maxRuns, testFn.todo, beforeRetry)
}
retry.skip = function (name, callback, maxRuns = defaultMaxRuns) {
return new Retry([name], callback, maxRuns, testFn.skip)
return new Retry([name], callback, maxRuns, testFn.skip, beforeRetry)
}
retry.if = function (name, condition, callback, maxRuns = defaultMaxRuns) {
return new Retry([name, condition], callback, maxRuns, testFn.if)
return new Retry([name, condition], callback, maxRuns, testFn.if, beforeRetry)
}
retry.only = function (name, callback, maxRuns = defaultMaxRuns) {
return new Retry([name], callback, maxRuns, testFn.only)
return new Retry([name], callback, maxRuns, testFn.only, beforeRetry)
}

retry.each = function (name, dataset, callback, maxRuns = defaultMaxRuns) {
return new Retry([name, dataset], callback, maxRuns, testFn.each)
return new Retry([name, dataset], callback, maxRuns, testFn.each, beforeRetry)
}
retry.todo.each = function (name, dataset, callback, maxRuns = defaultMaxRuns) {
return new Retry([name, dataset], callback, maxRuns, testFn.todo.each)
return new Retry([name, dataset], callback, maxRuns, testFn.todo.each, beforeRetry)
}
retry.skip.each = function (name, dataset, callback, maxRuns = defaultMaxRuns) {
return new Retry([name, dataset], callback, maxRuns, testFn.skip.each)
return new Retry([name, dataset], callback, maxRuns, testFn.skip.each, beforeRetry)
}
retry.if.each = function (name, condition, dataset, callback, maxRuns = defaultMaxRuns) {
return new Retry([name, condition, dataset], callback, maxRuns, testFn.if.each)
return new Retry([name, condition, dataset], callback, maxRuns, testFn.if.each, beforeRetry)
}
retry.only.each = function (name, dataset, callback, maxRuns = defaultMaxRuns) {
return new Retry([name, dataset], callback, maxRuns, testFn.only.each)
return new Retry([name, dataset], callback, maxRuns, testFn.only.each, beforeRetry)
}
return retry
}
6 changes: 5 additions & 1 deletion src/retry.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ import AssertResultHandler from './assert-result-handler.js'
import extend from './extend.js'

export default class Retry {
constructor (args, callback, maxRuns = 2, testFn) {
constructor (args, callback, maxRuns = 2, testFn, beforeRetry) {
this.callback = callback
this.maxRuns = maxRuns
this.beforeRetry = beforeRetry
this.assertResultHandler = new AssertResultHandler(this)
this.isSuccess = true

Expand Down Expand Up @@ -60,6 +61,9 @@ export default class Retry {

async runTest () {
if (this.notFirstRun) {
if (this.beforeRetry) {
await this.beforeRetry.call(this.testEnvironment, this.assertProxy, this.currentRun)
}
this.isSuccess = true
this.test.testEnvironment = extend({}, this.test.module.testEnvironment, false, true)
await this.runHooks(this.beforeEachHooks)
Expand Down
21 changes: 20 additions & 1 deletion test/retry.js
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ QUnit.module('hooks count', function () {

QUnit.module('default max runs', function () {
const calls = []
const retryThrice = setup(QUnit.test, 3)
const retryThrice = setup(QUnit.test, { maxRuns: 3 })

retryThrice('count retries', function (assert, currentRun) {
calls.push(currentRun)
Expand All @@ -167,6 +167,25 @@ QUnit.module('default max runs', function () {
})
})

QUnit.module('beforeRetry hook', function () {
const calls = []
const retryWithHook = setup(QUnit.test, {
beforeRetry: function (assert, currentRun) {
calls.push(['hook', currentRun])
}
})

retryWithHook('count retries', function (assert, currentRun) {
calls.push(['test', currentRun])

assert.equal(currentRun, 2)
}, 2)

QUnit.test('verify calls', function (assert) {
assert.deepEqual(calls, [['test', 1], ['hook', 2], ['test', 2]])
})
})

QUnit.module('assert.expect', function () {
const calls = []

Expand Down