# test
test
is a central function which is used to create a testcase unit. Full info ➤
test("It should print 'hello world'", () => {
chunk(() => {
console.log("hello world");
});
});
➜ glace-core: ./bin/glace example.js
suite: Session 2018-11-15 09:27:15
test: It should print 'hello world'
hello world
✓ chunk
✓ 1 passed test
1 executed chunk
Summary tests time is 0.003 sec
-----------------------------------------------------------
Local report is /home/user/projects/glace/glace-core/report
test
should contain as minimum one chunk
, named or unnamed.
# chunk
chunk
is independently executed part of test
. Independently means even if
first chunk is failed, other chunks will be executed in any case. Full info ➤
test("It should include one unnamed chunk", () => {
chunk(() => {
console.log("do some stuff");
});
});
test("It should include one named chunk", () => {
chunk("first chunk", () => {
console.log("do some stuff");
});
});
test("It should include several chunks", () => {
chunk("first chunk", () => {
console.log("do some stuff");
});
chunk("second chunk", () => {
console.log("do some stuff");
});
});
test("It should include failed & passed chunks", () => {
chunk("which is failed", () => {
throw Error("BOOM!");
});
chunk("which is passed", () => {
console.log("do some stuff");
});
});
➜ glace-core: ./bin/glace example.js
suite: Session 2018-11-15 09:38:45
test: It should include one unnamed chunk
do some stuff
✓ chunk
test: It should include one named chunk
do some stuff
✓ chunk: first chunk
test: It should include several chunks
do some stuff
✓ chunk: first chunk
do some stuff
✓ chunk: second chunk
test: It should include failed & passed chunks
✖ chunk: which is failed
do some stuff
✓ chunk: which is passed
✓ 3 passed tests
✖ 1 failed test
6 executed chunks
Summary tests time is 0.005 sec
TEST FAILURES:
test: It should include failed & passed chunks
which is failed
message: BOOM!
stack: Error: BOOM!
at chunk (example.js:24:15)
at Context.<anonymous> (lib/globals/chunk.js:88:18)
at next (lib/hacking.js:45:20)
at Immediate.<anonymous> (lib/hacking.js:88:9)
-----------------------------------------------------------
Local report is /home/user/projects/glace/glace-core/report
# before
before
is a hook executed before all chunks inside a test or before all tests inside a suite / scope / session. Full info ➤
test("It should execute hook before all chunks", () => {
before(() => {
console.log("some stuff before chunks");
});
chunk("first chunk", () => {
console.log("do some stuff");
});
chunk("second chunk", () => {
console.log("do some stuff");
});
});
# after
after
is a hook executed after all chunks inside a test or after all tests inside a suite / scope / session. Full info ➤
test("It should execute hook after all chunks", () => {
chunk("first chunk", () => {
console.log("do some stuff");
});
chunk("second chunk", () => {
console.log("do some stuff");
});
after(() => {
console.log("some stuff after chunks");
});
});
# beforeChunk
beforeChunk
is a hook executed before each chunk inside a test. Full info ➤
test("It should execute hook before each chunk", () => {
beforeChunk(() => {
console.log("some stuff before each chunk");
});
chunk("first chunk", () => {
console.log("do some stuff");
});
chunk("second chunk", () => {
console.log("do some stuff");
});
});
# afterChunk
afterChunk
is a hook executed after each chunk inside a test. Full info ➤
test("It should execute hook after each chunk", () => {
chunk("first chunk", () => {
console.log("do some stuff");
});
chunk("second chunk", () => {
console.log("do some stuff");
});
afterChunk(() => {
console.log("some stuff after each chunk");
});
});
# $
$
is the steps namespace, central concept of glace
philosophy. Ideally and normally in glace
tests
to have only step calls inside test chunks. glace-core
provides only basic steps, other steps for specific actions are provided by
plugins or should be implemented together with tests development. There are more examples of steps usage in glace-js
. And here some basic:
suite("Timer steps", () => {
test("It should sleep 1 sec", () => {
chunk(async () => {
await $.pause(1, "sleep 1 sec");
});
});
test("It should pass timer check", () => {
chunk(async () => {
await $.startTimer();
await $.pause(1, "sleep");
await $.checkTimer({ "to be above": 1 });
});
});
test("It should fail timer check", () => {
chunk(async () => {
await $.startTimer();
await $.pause(1, "sleep");
await $.checkTimer({ "to be below": 1 });
});
});
test("It should fail because timer is not started", () => {
chunk(async () => {
await $.startTimer();
await $.pause(1, "sleep");
await $.stopTimer();
await $.checkTimer({ "to be equal": 1 });
});
});
});
➜ glace-core: ./bin/glace example.js
suite: Session 2018-11-16 08:29:39
suite: Timer steps
test: It should sleep 1 sec
✓ chunk
test: It should pass timer check
✓ chunk
test: It should fail timer check
✖ chunk
test: It should fail because timer is not started
✖ chunk
✓ 2 passed tests
✖ 2 failed tests
4 executed chunks
Summary tests time is 4.032 sec
TEST FAILURES:
test: It should fail timer check
message: Timing is failed: expected 1.005 to be below 1
stack: AssertionError: Timing is failed: expected 1.005 to be below 1
at Proxy.Assertion.correspond (lib/matcher.js:50:27)
at Proxy.checkTimer (lib/steps/timer.js:135:56)
at chunk (example.js:23:21)
at <anonymous>
test: It should fail because timer isn't started
message: Timer isn't started: expected null to exist
stack: AssertionError: Timer isn't started: expected null to exist
at Proxy.getTimer (lib/steps/timer.js:103:54)
at Proxy.checkTimer (lib/steps/timer.js:135:21)
at chunk (example.js:32:21)
at <anonymous>
-----------------------------------------------------------
Local report is /home/user/projects/glace/glace-core/report
# CONF
CONF
refers to glace
configuration and is mostly used inside steps, features or iterators, rather than inside tests directly.
For example, glace-core/lib/globals/forEachLanguage.js#L66:
scope(`${name} "${lang}"`, () => {
let oldLang;
before(() => {
if (CONF.test.curCase) {
oldLang = CONF.test.curCase.testParams.language;
CONF.test.curCase.testParams.language = lang;
}
});
U.wrap(fixtures, () => func(lang))();
after(() => {
if (CONF.test.curCase) {
CONF.test.curCase.testParams.language = oldLang;
}
});
});
CONF
is global object for all glace
components, which means that even if some glace
plugin imports own config module internally,
finally it works in the same global config namespace. Full info ➤
# fixtures
Fixtures
are reusable functions, which can add hooks before and after test or group of tests.
They were introduced to glace-core
under impression of pytest fixtures.
Simple fixture can be presented as:
const myFixture = testFunc => {
before(() => console.log("fixture before"));
testFunc();
after(() => console.log("fixture after"));
};
Now it can be reusable as many times as it needs. For example:
suite("My suite", [myFixture], () => {
test("first test", () => {
chunk(() => {});
});
test("second test", [myFixture], () => {
chunk(() => {});
});
});
Run result:
➜ glace-core: ./bin/glace example.js
suite: Session 2018-11-22 07:39:21
suite: My suite
fixture before
test: first test
✓ chunk
test: second test
fixture before
✓ chunk
fixture after
fixture after
✓ 2 passed tests
2 executed chunks
Summary tests time is 0.005 sec
-----------------------------------------------------------
Local report is /home/user/projects/glace/glace-core/report
Fixtures
can be used with test, scope, suite, session and forEachLanguage.
Many glace
plugins offer fixtures as wrappers on their steps. For example, glace-web/lib/fixtures.js#L18.
And glace-js
session is fully based on fixtures reusage.
# iterators
iterators
are used to make parametrization over tests or chunks. Underhood iterators
are cycles.
glace-core
provides iterator forEachLanguage to make easy localisation tests.
suite("Localisation tests", () => {
test("my test", () => {
forEachLanguage(lang => {
chunk(() => {
// someLangSpecificStuff(lang);
});
});
});
});
➜ glace-core: ./bin/glace example.js --languages en,ru,fr
suite: Session 2018-11-22 07:39:21
suite: Localisation tests
test: my test
scope: for language "en"
✓ chunk
scope: for language "ru"
✓ chunk
scope: for language "fr"
✓ chunk
✓ 1 passed test
3 executed chunks
Summary tests time is 0.004 sec
-----------------------------------------------------------
Local report is /home/user/projects/glace/glace-core/report
# suite
suite
is used to group tests. Full info ➤
suite("my tests", () => {
test("first test", () => {
chunk(() => {});
});
test("second test", () => {
chunk(() => {});
});
});
➜ glace-core: ./bin/glace example.js
suite: Session 2018-11-22 07:39:21
suite: my tests
test: first test
✓ chunk
test: second test
✓ chunk
✓ 2 passed tests
2 executed chunks
Summary tests time is 0.004 sec
-----------------------------------------------------------
Local report is /home/user/projects/glace/glace-core/report
# scope
scope
is used to group tests or chunks. Full info ➤
test("my test", () => {
scope("user chunks", () => {
chunk("login as user", () => {});
chunk("post a message", () => {});
});
scope("admin chunks", () => {
chunk("login as admin", () => {});
chunk("moderate messages", () => {});
});
});
➜ glace-core: ./bin/glace example.js
suite: Session 2018-11-22 07:39:21
test: my test
scope: user chunks
✓ chunk: login as user
✓ chunk: post a message
scope: admin chunks
✓ chunk: login as admin
✓ chunk: moderate messages
✓ 1 passed test
4 executed chunks
Summary tests time is 0.004 sec
-----------------------------------------------------------
Local report is /home/user/projects/glace/glace-core/report
# session
session
is root suite, which is created automatically (not need to use it explicitly). Full info ➤
But it can be overridden to extend its functionality, for example glace-js/lib/globals.js#L13:
const gSession = session;
global.session = (name, fixtures, func) => {
if (_.isFunction(fixtures)) [func, fixtures] = [fixtures];
if (_.isArray(name)) [fixtures, name] = [name];
if (_.isFunction(name)) [func, name] = [name];
fixtures = fixtures || [];
if (CONF.web.use && !CONF.cluster.slavesNum) fixtures.push(fxKillWebdriver);
if (CONF.xvfb.use) fixtures.push(fxXvfb);
if (CONF.proxy.global) fixtures.push(fxGlobalProxy);
if (CONF.proxy.http) fixtures.push(fxHttpProxy);
if (CONF.web.use && !CONF.webdriver.host) fixtures.push(fxSelenium);
if (CONF.web.use) fixtures.push(fxBrowser);
if (CONF.image.screenOnFail) fixtures.push(fxScreenOnFail);
gSession(name, fixtures, func);
};