FCF 2.0 development in progress...
> > >
[News] [Packages API] [Downloads] [Donate to the project] [Contacts]

Application testing example

The package provides unit testing functionality through an instance of the fcf.NUnitest.Unitest class, which is returned by the fcf-framework-unitest module.

Testing can be performed both on the server side and on the browser side. So, it is also possible to run tests in the browser from the NODEJS application.

Consider an example of testing an application.

First, let's create a project and install the fcf-framework-unitest package. After that, we will add the main index.js file, which will export a function that will always return the value 1.

$ mkdir application $ cd application $ npm init $ npm install --save fcf-framework-unitest

index.js file:

module.exports = function() { return 1; }

Test declaration

Now let's add a unit test to test our function. To do this, create a file tests/localTests.js and declare a test using the function fcf.test

tests/localTests.js file:

const someFunction = require("../index.js"); fcf.test("Local test", (a_unitest)=>{ a_unitest.equal(someFunction(), 1); });

To declare and connect a test, the fcf.test function is used, which, in addition to registering the test, also automatically loads the fcf-framework-test module on the browser side. The fcf-framework-unitest module is loaded only if the page is loaded by the fcf.NUnitest.Unitest.run() method from the NODEJS server or the URL argument ___fcf_unitest of the GET request is declared.

The function fcf.test() has the following signatures:

fcf.test(string a_part, string a_group, string a_name, function a_cbtest)

fcf.test(string a_group, string a_name, function a_cbtest)

fcf.test(string a_name, function a_cbtest)

string a_part = "default"
- Test part

string a_group = "default"
- Test group

string a_name
- Test name

function a_cbtest
- Test function

Function signature: [simple or async] void a_cbtest(fcf.NUnitest.Unitest a_unitest)

fcf.NUnitest.Unitest a_unitest - The test object created by the main object on which the run() method was called. It is on this object that the verification methods are called during script execution.

Running tests on the server side

Now you need to run the test, for this you need to execute the run method of the fcf.NUnitest.Unitest object. Let's add the run-tests.js script, in which we will execute the run method.

run-tests.js file:

let unitest = require("fcf-framework-unitest"); unitest.run({ include: [":tests/localTests.js"], }) .finally(()=>{ process.exit(0); });

And let's run the test

$ node run-tests.js

2023-05-13 03:26:51.018 [PID:228207] [LOG] [MOD:UniTest]: ==================================================== 2023-05-13 03:26:51.023 [PID:228207] [LOG] [MOD:UniTest]: Start testing on the server side... 2023-05-13 03:26:51.023 [PID:228207] [LOG] [MOD:UniTest]: Parts: * 2023-05-13 03:26:51.024 [PID:228207] [LOG] [MOD:UniTest]: Groups: * 2023-05-13 03:26:51.024 [PID:228207] [LOG] [MOD:UniTest]: Tests: * 2023-05-13 03:26:51.025 [PID:228207] [LOG] [MOD:UniTest]: 2023-05-13 03:26:51.025 [PID:228207] [LOG] [MOD:UniTest]: Start local tests... 2023-05-13 03:26:51.025 [PID:228207] [LOG] [MOD:UniTest]: -------------------- 2023-05-13 03:26:51.026 [PID:228207] [LOG] [MOD:UniTest]: Test [default][default][Local test] running ... 2023-05-13 03:26:51.027 [PID:228207] [LOG] [MOD:UniTest]: Test [default][default][Local test] is completed. 2023-05-13 03:26:51.028 [PID:228207] [LOG] [MOD:UniTest]: 2023-05-13 03:26:51.028 [PID:228207] [LOG] [MOD:UniTest]: ---------------------------------------------------- 2023-05-13 03:26:51.029 [PID:228207] [LOG] [MOD:UniTest]: 1 test have been completed. 2023-05-13 03:26:51.029 [PID:228207] [LOG] [MOD:UniTest]: Errors: 0; Successfully: 1; Total: 1

Running tests on the browser side

Unit testing of the framework can also be done on the browser side, with the ability to run from a NODEJS script.

First, let's create a simple one-page application. Create a NODEJS server to serve the index.html page to the browser on port 8080

server.js file:

let libExpress = require("express"); let libPath = require("path"); let server = libExpress(); server.use("/", libExpress.static(__dirname)); server.get("/", libExpress.static(libPath.join(__dirname, "index.html"))); const port = 8080; server.listen(port, () => { console.log(`Start listing on ${port} port`); });

And let's make a simple HTML page, which will contain an input field, when filled in, the data will be duplicated in a div with an index label

The fcf-framework-core:fcf.min.js framework file must be included in the page header in order to be able to use the unit testing functionality.

index.html file:

<html> <head> <script src="/node_modules/fcf-framework-core/fcf.min.js"></script> </head> <body> <fieldset> <p> <input id="input"> </p> <p> <div id="label" style="min-height: 1.2em;"></div> </p> </fieldset> <script> document.getElementById("input").addEventListener("input", (a_event)=>{ document.getElementById("label").innerHTML = a_event.target.value; }) </script> </body> </html>

Let's run our test application:

$ node server.js

Now let's create a test function for our page in the file tests/browserTests.js

tests/browserTests.js file:

fcf.test("Browser test", (a_unitest)=>{ const input = document.getElementById("input"); const label = document.getElementById("label"); input.value = "test"; input.dispatchEvent(new Event("input")); a_unitest.equal(label.innerHTML, input.value); });

It remains only to change the code for calling the run() method in the run-tests.js file

webProcesses option

The run() method will start the NODEJS server server.js by itself, for this you need to set the webProcesses option in the function argument. This parameter is an array containing objects with a description of the launch commands before testing.

Description of the elements of the webProcesses array:

  • string|[string] command - Run command, which can be given as a single string or an array of command line arguments.

  • integer startTimeout = 1000 - Time in milliseconds to wait for the application to start. The executable script transfers control to the following commands only after the specified delay has elapsed.

webTestingPages option

In addition, you need to tell the run() method that you want to test the page "http://localhost:8080" and when testing it, you need to include the file " :tests/browserTests.js", which contains the test. To set this, you need to use the webTestingPages parameter in the first argument of the run method.

[object] webTestingPages = [] - An array with information about the pages for which testing will be performed on the browser side

Object properties:

  • string url - URL of the page being tested

  • [string] include = [] - An array of additionally included URLs to JS files on the browser side, where tests can be located.

  • integer|string wait = 0 - Waiting time before testing, after page load. If the parameter is a string, then it must contain the path to a global asynchronous function that will return control after all page components have been loaded.

webBrowsers option

The choice of the browser to be launched is determined by the webBrowsers parameter. This must be an array, where the element specifies for which browser the test will be performed. If the parameter has the value ["chrome", "firefox"], then the test will be performed for the two specified browsers.

The value of the array element is the name of the command to be executed, so the path to the specified browser must be specified in the PATH environment variable. This is especially important on Windows!

If the array element is an array, then the test will run against the first browser in the nested array that runs successfully.

By default, the webBrowsers option is set to [["google-chrome", "chrome", "chromium", "firefox", "opera", "safari"]],

And so, the run-tests.js file should take the following form:

let unitest = require("fcf-framework-unitest"); unitest.run({ include: [":tests/localTests.js"], webProcesses: [{ command: "node ./server.js", }], webTestingPages: [ { url: "http://localhost:8080", include: ["tests/browserTests.js"] } ] }) .finally(()=>{ process.exit(0); });

Let's start testing

$ node run-tests.js

2023-05-13 05:15:42.144 [PID:230049] [LOG] [MOD:UniTest]: ==================================================== 2023-05-13 05:15:42.148 [PID:230049] [LOG] [MOD:UniTest]: Start testing on the server side... 2023-05-13 05:15:42.149 [PID:230049] [LOG] [MOD:UniTest]: Parts: * 2023-05-13 05:15:42.149 [PID:230049] [LOG] [MOD:UniTest]: Groups: * 2023-05-13 05:15:42.150 [PID:230049] [LOG] [MOD:UniTest]: Tests: * 2023-05-13 05:15:42.150 [PID:230049] [LOG] [MOD:UniTest]: 2023-05-13 05:15:42.151 [PID:230049] [LOG] [MOD:UniTest]: Start local tests... 2023-05-13 05:15:42.151 [PID:230049] [LOG] [MOD:UniTest]: -------------------- 2023-05-13 05:15:42.151 [PID:230049] [LOG] [MOD:UniTest]: Test [default][default][Local test] running ... 2023-05-13 05:15:42.153 [PID:230049] [LOG] [MOD:UniTest]: Test [default][default][Local test] is completed. 2023-05-13 05:15:42.231 [PID:230049] [LOG] [MOD:UniTest]: 2023-05-13 05:15:42.231 [PID:230049] [LOG] [MOD:UniTest]: Start web tests... 2023-05-13 05:15:42.232 [PID:230049] [LOG] [MOD:UniTest]: -------------------- 2023-05-13 05:15:42.232 [PID:230049] [LOG] [MOD:UniTest]: Start process: node ./server.js 2023-05-13 05:15:42.237 [PID:230049] [LOG] [MOD:UniTest]: Child process "node" started with pid 230056 2023-05-13 05:15:42.374 [PID:230049] [LOG] [MOD:UniTest]: Sub process "node" stdout: [node PID: 230056]> Start listing on 8080 port [node PID: 230056]> 2023-05-13 05:15:43.238 [PID:230049] [LOG] [MOD:UniTest]: Start back server on port 4589 2023-05-13 05:15:43.245 [PID:230049] [LOG] [MOD:UniTest]: Start browser 'google-chrome "http://localhost:8080?___fcf_unitest&___fcf_unitest_host=localhost&___fcf_unitest_port=4589&___fcf_unitest_tests=undefined&___fcf_unitest_groups=undefined&___fcf_unitest_parts=undefined&___fcf_unitest_id=d54c8793ad107a8ac4e2bd4c3fac5ac8&___fcf_unitest_include=%5B%22tests%2FbrowserTests.js%22%5D"' ... 2023-05-13 05:15:47.330 [PID:230049] [LOG] [MOD:UniTest; BROWSER:google-chrome]: Test [default][default][Browser test] running ... 2023-05-13 05:15:47.336 [PID:230049] [LOG] [MOD:UniTest; BROWSER:google-chrome]: Test [default][default][Browser test] is completed. 2023-05-13 05:15:47.360 [PID:230049] [LOG] [MOD:UniTest]: 2023-05-13 05:15:47.360 [PID:230049] [LOG] [MOD:UniTest]: ---------------------------------------------------- 2023-05-13 05:15:47.361 [PID:230049] [LOG] [MOD:UniTest]: 2 tests have been completed. 2023-05-13 05:15:47.361 [PID:230049] [LOG] [MOD:UniTest]: Errors: 0; Successfully: 2; Total: 2