Add unit tests to an Oracle JET MVVM web app

Introduction

Testing is a crucial part of the development lifecycle, ensuring the creation of robust and stable web apps. There are various types of testing, such as end-to-end testing and integration testing. Unit testing involves writing tests for individual units of code, including classes, functions, or methods. It is good practice to write unit tests early in the development process. Starting early not only demonstrates the importance of testing but also increases the likelihood of achieving full test coverage, rather than waiting until the web app is fully functional and complex.

Objectives

In this tutorial, you will learn how to install the testing tools that Oracle JET supports for Oracle JET apps developed using the MVVM architecture using the Oracle JET CLI add testing command, and how to write a unit test in the Oracle JET web app that you have developed over the course of this learning path series.

Prerequisites

Task 1: Add the Testing Libraries

  1. Navigate to the JET_Web_Application folder, and add the testing libraries.

    npx ojet add testing
    

    The Oracle JET tooling creates a test-config folder in the JET_Web_Application folder with the configuration files that the testing libraries require:

    ./JET_Web_Application/test-config
    karma.conf.js
    test-main.js
    tsconfig.json
    

    It also updates the package.json file with the testing tools that the add testing command installs. These updates include entries for Chai, Karma, and Mocha.

Task 2: Edit the Test Configuration Files

The add testing command is currently optimized to create unit tests for custom components that you create within the Oracle JET web app. You can read more about unit tests for custom components and download a sample unit test from the developer’s guide. However, to write a unit test for code in one of the modules of an Oracle JET web app, such as the Incidents module, you need to make some changes to the files in the test-config folder that the add testing command created. We describe these change here.

  1. Navigate to the JET_Web_Application/test-config directory and open the karma.conf.js file in an editor.

  2. Comment out or delete the entries for CCA files, and add entries for the viewModels files and their dependencies that need to be included to run the tests.

    . . .
    // // CCA libs
    // {
    //   pattern: 'web/*/jet-composites/**/*',
    //   included: false
    // },
    // viewModels and dependent files
    {
       pattern: "web/*/{viewModels/**,accUtils.js,store_data.json}",
       included: false
    },
    // JET/3rd party libs
    . . .
    
  3. Still in the test-config directory, open the test-main.js file in an editor, and revise the value of the TEST_REGEXP variable to reference test script files in a __tests__ directory of the MVVM app rather than the jet-composites directory.

    var allTestFiles = [];
    // var TEST_REGEXP = /jet-composites.*\w\.spec\.js$/i
    var TEST_REGEXP = /__tests__.*\w\.spec\.js$/i;
    
  4. Open the tsconfig.json file that is in the test-config directory, and make updates to reference test script files under the src/ts directory

    . . .
    "baseUrl": ".",
    "paths": {
       "*": [
       // add the "../src/ts/*" entry
       "../src/ts/*",
       . . .
       "../node_modules/*"],
       // add the "viewModels/*": ["../src/ts/viewModels/*"], entry
       "viewModels/*": ["../src/ts/viewModels/*"],
       "ojs/*": ["../node_modules/@oracle/oraclejet/dist/types/*"]
    },
    . . .
      },
    "include": [
       // add the "../src/ts/__tests__/*.ts" entry
       "../src/ts/__tests__/*.ts",
    . . .
    
  5. Save the ./test-config/tsconfig.json file.

    Your file should look similar to final-test-config-tsconfig-json-ts.txt.

Task 3: Write a Unit Test

Before we create our unit test, we update the Incidents module in our app to use a messageText variable. Later, the unit test that we write tests the value of this variable.

  1. Navigate to the JET_Web_Application/src/ts/viewModels folder, and open the incidents.ts file in an editor.

  2. Add code to the incidents.ts file to include a Knockout string observable for a messageText variable that is initialized to Hello World.

    import * as AccUtils from "../accUtils";
    import * as ko from 'knockout';
       
    class IncidentsViewModel {
       
       messageText: ko.Observable<string>;
       
       constructor() {
       
       this.messageText = ko.observable('Hello World');
       }
    . . .
    

    Your file should look similar to incidents-ts.txt.

  3. Navigate to the JET_Web_Application/src/ts/views folder, and open the incidents.html file in an editor.

  4. Add code to the incidents.html file to display the value of the messageText variable.

    <h1>Incidents Content Area</h1>
      <div>
    	<p><oj-bind-text value="[[messageText]]"></oj-bind-text></p>
      </div>
    . . .
    
  5. Navigate to the JET_Web_Application/src/ts folder, and create a new folder named __tests__.

    This folder is where we save the test script files. The test configuration files that we modified in the previous task reference this folder.

  6. In the newly-created JET_Web_Application/src/ts/__tests__ folder, create a test script file named incidents-value-viewmodel.spec.ts.

  7. In the incidents-value-viewmodel.spec.ts file, write entries that test the value of a messageText variable in the Incidents’ module viewModel file:

    import { expect } from 'chai';
    // @ts-ignore
    import IncidentsViewModel = require('viewModels/incidents');
       
    describe('Incidents unit test', () => {
      let viewModel: IncidentsViewModel;
      console.log('Incidents unit test');
       
      // beforeEach function creates a new instance of
      // ViewModel before each test to ensure that each test
      // is independent and starts with a fresh state.
       
      beforeEach(() => {
        viewModel = new IncidentsViewModel();
        console.log('Created new instance of viewModel for test run');
      });
       
      it('messageText should be "Hello World"', () => {
        expect(viewModel.messageText()).to.equal('Hello World');
      });
    });
    

    Your file should look similar to incidents-value-viewmodel.spec-ts.txt.

Task 4: Run the Unit Test

The unit test(s) that you write execute against the build output in the ./web directory. For this reason, ensure that you build your Oracle JET web app before you run the test scripts that you write.

  1. In the terminal window, navigate to the JET_Web_Application directory and build the app using the following command:

    npx ojet build
    
  2. Wait for a confirmation message similar to the following.

    runAllComponentHooks
    Running after_build hook.
    Success: Build finished.
    
  3. In the same terminal window, execute the unit test in the JET_Web_Application/src/ts/__tests__/ folder by running the following command.

    npm test
    

    The test executes and displays console output similar to the following.

    Chrome 130.0.0.0 (Windows 10) LOG: 'Incidents unit test'
    07 11 2024 10:44:38.195:DEBUG [Chrome 130.0.0.0 (Windows 10)]: CONFIGURING -> EXECUTING
    LOG: 'Created new instance of viewModel for test run'
    Incidents unit test
       ✔ messageText should be "Hello World"
    07 11 2024 10:44:38.198:DEBUG [Chrome 130.0.0.0 (Windows 10)]: EXECUTING -> CONNECTED
    . . .
       
    Finished in 0.003 secs / 0 secs @ 10:44:38 GMT+0100 (Central European Standard Time)
       
    SUMMARY:
    ✔ 1 test completed
    07 11 2024 10:44:38.202:DEBUG [karma-server]: Run complete, exiting.
    . . .
    

Next Step

To proceed to the first tutorial in the next learning path in this series, click here.

More Learning Resources

Explore other labs on docs.oracle.com/learn or access more free learning content on the Oracle Learning YouTube channel. Additionally, visit education.oracle.com/learning-explorer to become an Oracle Learning Explorer.

For product documentation, visit Oracle Help Center.