jstestcontext v1.0.1
jstestcontext
jstestcontext is an extension package for jstestadapter as a means to provide MSTest style TestContext
to javascript test methods. Currently the main feature that TestContext exposes is uploading test case level result attachments. This is especially helpful when associating screenshots with failed UI tests running in CI scenario.
Install
npm install jstestcontext
Usage
NOTE: TestContext does not work with strict mode since it relies on Function.caller property.
// TypeScript
import { TestContext } from 'jstestcontext';
// JavaScript
const TestContext = require('jstestcontext').TestContext;
TestContext.Attachment methods
describe('Suite', () => {
it('Test', () => {.
// Returns the directory in which attachments for this test case should be placed.
const testResultsDirectory = TestContext.Attachments.getAttachmentDirectory();
// User's responsibility to copy the attachment to the directory.
copyAttachment('/path/to/some/file', testResultsDirectory);
});
})
describe('Suite', () => {
it('Test', () => {.
// Copies the given file to the appropriate test attachment directory.
TestContext.Attachments.recordAttachment('/path/to/some/file').
});
})
TestContext methods
describe('Suite', () => {
it('Test', () => {
// Returns the test name for the current test method, result: `Test`.
const testName = TestContext.getCurrentTestName();
// Returns a GUID style identifier for the current test method.
const testId = TestContext.getCurrentTestIdentifier();
});
})
Special Usage
Since the methods getCurrentTestName()
, getCurrentTestIdentifier()
, Attachments.getAttachmentDirectory()
, Attachments.recordAttachment()
rely on Function.caller
property, there are some unique situations that arise.
Through nested functions
If any one of these functions are called in a nested method, for example, testSpec -> someMethod -> TestContext.getCurrentTestName
, the call stack needs to be sequentially walked up till the test method is found. The limitation on this walk is determined by callerMatchDepth
value of the TestContext options with default value 2.
Call depth follows the pattern:
Call | Depth |
---|---|
testSpec -> method1 -> TestContext.getCurrentTestName | 1 |
testSpec -> method1 -> method2 -> TestContext.getCurrentTestName | 2 |
Updating callerMatchDepth
option
// TypeScript
import { TestContext, ITestContextOptions } from 'jstestcontext';
TestContext.updateOptions(<ITestContextOptions> {
callerMatchDepth: 4
});
// JavaScript
const TestContext = require('jstestcontext').TestContext;
TestContext.updateOptions({
callerMatchDepth: 4
});
Through Promise executors
Since promises executors don't have caller context the following does not work:
new Promise(() => {
// Following will throw
const dir = TestContext.Attachments.getAttachmentDirectory();
doSomething(dir);
});
To use any one of these methods from inside promises the following is the only option
const dir = TestContext.Attachments.getAttachmentDirectory();
new Promise(() => {
// Following will throw
doSomething(dir);
});
:x: Nopes and Gotchas
Calling in recursive methods
Calling in recurisve method does not work since Function.caller
is a static property. The moment a method
calls itself, it loses the caller as the test method.
describe('Dont make such mistakes', () => {
it('Im a smart guy using recursive functions', () => {
const dir = method();
});
})
let i = 0;
function method() {
if (i++ >= 3) {
return TestContext.Attachments.getAttachmentDirectory();
} else {
return method();
}
}
Building from source
# Build binaries and javascript to `./artifacts/Debug/out/` along with the package tarball in `./artifacts/Debug`
.\scripts\build.ps1
Running Unit Tests
npm run test