A tiny test framework for mjs on mongoose-os.
Add this library as a dependecy in your mos.yml
file:
libs:
- origin: https://github.com/johanwiren/mjs-test
Add a configuration toggle in mos.yml
enable testing mode:
config_schema:
- ["bank", "o", {hide: true}]
- ["bank.test_mode", "b", false, {title: "Run only tests"}]
Build and flash your firmware to pull dependencies.
$ mos build --local --platform <your platform>
$ mos flash
Write some tests in fs/bank_tests.js
:
load('mjs_test.js');
load('bank.js');
// Tests
let s = TestSuite.create("bank_tests");
s.tests = [
function() {
// Given
let account = Account.create();
// When
account.deposit(100);
// Then
assertTrue(account.hasMoney());
assertFalse(account.isBankrupt());
assertEqual(100, account.balance());
}];
Run your tests in init.js
:
load('mjs_test.js');
load('api_config.js');
if (Cfg.get("bank.test_mode")) {
print("Test mode only");
load('bank_tests.js');
print("Running test suites");
TestRunner.runSuites();
} else {
load('bank.js');
// Your application initialisation goes here
}
Enable test mode:
$ mos config-set bank.test_mode=true
Upload your code and watch the tests complete in the console:
$ mos put fs/bank.js && mos put fs/init.js && mos call Sys.Reboot && mos console
...
[Dec 1 22:48:57.606] mgos_init Init done, RAM: 295504 total, 222688 free, 222688 min free
[Dec 1 22:48:57.680] Test mode only
[Dec 1 22:48:57.702] Registered suite: bank_tests
[Dec 1 22:48:57.706] Running test suites
[Dec 1 22:48:57.713] Running test suite bank_tests
[Dec 1 22:48:57.731] {"result":"successful","tests":1,"suite":"bank_tests"}
If you encounter errors you will get a stack trace and no further tests will be run:
[Dec 1 22:50:22.710] Running test suites
[Dec 1 22:50:22.716] Running test suite bank_tests
[Dec 1 22:50:22.731] Expected: 99
[Dec 1 22:50:22.734] Actual: 100
[Dec 1 22:50:22.737] at mjs_test.js:57
[Dec 1 22:50:22.740] at mjs_test.js:74
[Dec 1 22:50:22.742] at bank_tests.js:25 <-- This is where the error was encountered
[Dec 1 22:50:22.744] at mjs_test.js:37
[Dec 1 22:50:22.745] at mjs_test.js:31
[Dec 1 22:50:22.747] at mjs_test.js:14
[Dec 1 22:50:22.749] at init.js:10
[Dec 1 22:50:22.752] MJS error: Assertion failed
There are no helper functions for mocking, but mocking in javascript can easily be accomplished:
// Mock FBI.Logger
let FBI = {
Logger: {
// Mocked method
log: function(arg) {
FBI.Logger.updateInvocations++;
return;
},
logInvocations: 0,
logWasInvoked: function() {
let wasInvoked = FBI.Logger.logInvocations > 0;
FBI.Logger.logInvocations = 0;
return wasInvoked;
},
_reset: function() {
FBI.Logger.logInvocations = 0;
}
}
};
// Tests
let s = TestSuite.create("fbi_tests");
s.setUp = FBI.Logger._reset;
s.tests = [
function() {
// Given
let account = Account.create();
// When
account.withdraw(100);
// Then
assertTrue(FBI.Logger.logWasInvoked());
},
function() {
// Given
let account = Account.create({"secret": true});
// When
account.withdraw(100);
// Then
assertFalse(FBI.Logger.logWasInvoked());
}];
There is currently no way to obtain a stack trace from within mjs. The only way to produce a stack trace is to call die
which results in that the test runner stops running when the first failed test occurs.