SuiteCloud SDK And Testing SuiteApps with JEST

November 28, 2023 | 7 minute read
Federico Donner
SDN Solutions Engineer at Oracle NetSuite
Text Size 100%:

Introduction

Software testing and development tools play a crucial role in today's software development processes. These tools not only ensure more robust outcomes but also expedite the integration of new features. When it comes to coding SuiteApps, the complexity increases as the code operates solely on NetSuite servers. Therefore, a proficient development environment is vital. To assist developers in tackling these challenges, NetSuite provides the SuiteCloud SDK, with a special emphasis on the JEST testing tools, enhancing the efficiency and effectiveness of the development process.

SuiteCloud SDK

The SuiteCloud Software Development Kit (SuiteCloud SDK) encompasses a comprehensive suite of tools designed to facilitate the development of SuiteApps. This toolkit enables users to interact seamlessly with development accounts, streamlining processes such as object creation, importation, deployment, and testing. This integration not only enhances the development experience but also ensures a more efficient and effective workflow in building and managing SuiteApps.

The SDK includes three key tools, each serving a distinct purpose in the development process:

  • SuiteCloud CLI for Node.js
  • SuiteCloud Extension for Visual Studio Code
  • SuiteCloud Unit Testing

Each tool within the SDK presents a variety of features to enhance and streamline the development process. The Extension for Visual Studio Code integrates SuiteCloud commands directly into the Visual Studio Code interface. We will analyze some of the most practical commands available in the command line, followed by an draft look at the functionalities of JEST.

The SuiteCloud CLI for Node.js represents the fundamental layer of the SDK. It allows users to execute a range of commands via the command line. These commands facilitate interactions with a NetSuite account or assist in creating file structures essential for the development of SuiteApps and Account Customizations. To access all available commands, users simply begin by typing into the command line.

suitecloud

The full list of commands can be found here, we will go over a few useful ones for bootstrapping and overcharging SuiteApp development. 

suitecloud project:create -i

Note the flag -i that indicates interactive prompts. The same command can be entered specifying all the parameters directly. The user will be prompted to select between a SuiteApp or an Account Customization, enter the project details and when finished, a folder will be created with the correct structure.

suitecloud project:create

Apart from the folders, two important files are created: manifest.xml and deploy.xml. Those files will tell the SuiteApp Control Center important details on the SuiteApp configuration. 

suitecloud account:setup

This is one of the most powerful functionalities of the SDK. It allows the local project to connect to a NetSuite account in order to import objects, deploy code or check dependencies. When run, it allows the user to authenticate using two methods: browser-based (the command line delegates control to the browser and the user can select an account already logged there), or using TBA (entering authentication tokens corresponding to an Integration Record present in the account).

Once the authentication ID is crated, it’s stored and can be used in different projects without the need to authenticate again. Every time a command is run that needs to connect to an account, it will use the selected authentication ID. Feel free to create multiple authentication IDs corresponding to your partner TSTDRV accounts. They can be useful for testing your SuiteApps in the different environments.

suitecloud object:import -i

Once the project is linked to an account, objects created in NetSuite can be imported using this command. The interactive prompts will allow the user to specify the type of object they want to import and choose the SuiteApp of origin if applicable. Once the object is specified, an xml with the object’s definition is created in the project’s Objects folder.

suitecloud project:deploy

This is probably the most powerful of the SDK commands. It deploys the project to the connected account allowing the developer to run it on the target account. The deployment process is identical to the one used when installing from the SuiteApps Marketplace so the customer experience will be exactly the same. Install Scripts are triggered and all the included objects are deployed.

This command can be run alongside suitecloud project:validate and suitecloud project:adddependencies to verify that the account is configured correctly and that the project requires the necessary features before deployment. The manifest.xml file at the root of the project is automatically modified to reflect this.

suitecloud project:package

Finally, this command can be run when the SuiteApp is ready for deployment. It will create a zip file of the project according to the SuiteApp Control Center specifications.

Unit testing with JEST

The third tool included available via the SDK is a Unit Testing package. It implements JEST and exposes stubs for Modules of SuiteScript 2.x.

When running the suitecloud project:create command, the prompt allows to include the Unit Testing framework in the project. That creates a package.json file with JEST included as a devDependency, and a node_modules folder. Also, in the package.json file, a script is added automatically that runs the tests.

{
   “scripts”:{
        “test”: “jest”
    }
}

The command npm test runs the configured tests. The syntax is the standard for JEST, you can read more here.

To properly run your tests against the SuiteScript 2.x files of your SuiteCloud project, you will need to create a jest.config.js file on the root of your SuiteCloud project folder. It must follow a specific structure.

const SuiteCloudJestConfiguration = require("@oracle/suitecloud-unit-testing/jest-configuration/SuiteCloudJestConfiguration");
module.exports = SuiteCloudJestConfiguration.build({
  projectFolder: 'src', //or your SuiteCloud project folder
  projectType: SuiteCloudJestConfiguration.ProjectType.SUITEAPP,
});

The SDK comes with some pre-created stubs. These are basically class definitions of NetSuite modules that expose the same methods as their corresponding module. This way, the code will be able to run the functions without getting exceptions. Of course the functionality of the method won’t be there, but for the test, it can be run. 

Each test is described inside a file with the extension .test.js in the __tests__ folder in the roof of the directory. In that file, the SuiteScript that will be tested needs to be imported (in this case src/FileCabinet/SuiteScripts/Suitelet.js, note that the project folder was defined as “src” in the jest.config.js file), as well as the stubs for the modules that will be mocked (in this case “N/record”). The SDK also includes some stubs that mock the behavior of object instances or other types of objects typically used in NetSuite development.

import Suitelet from "SuiteScripts/Suitelet";
import record from "N/record";
import Record from "N/record/instance";

The function jest.mock(‘function’) tells JEST that the mocked function must be called instead of the real function. In this case it would be necessary to run add to the test file the following:

jest.mock("N/record");
jest.mock("N/record/instance");

Once the test is set up, the instances need to be defined using standard JEST syntax. For example:

describe("Suitelet Test", () => {
    it("Sales Order memo field has been updated", () => {
        // given
        const context = {
            request: {
                method: 'GET',
                parameters: {
                    salesOrderId: 1352
                }
            }
        };

        record.load.mockReturnValue(Record);
        Record.save.mockReturnValue(1352);

        // when
        Suitelet.onRequest(context);

        // then
        expect(record.load).toHaveBeenCalledWith({id: 1352});
        expect(Record.setValue).toHaveBeenCalledWith({fieldId: 'memo', value: 'foobar'});
        expect(Record.save).toHaveBeenCalledWith({enableSourcing: false});
    });
});

In that example, a test is configured that updates the memo field of order with id 1352. It’s easy to see that the context object is defined returning the salesOrderId with the same structure as NetSuite and when the load method is called on the record module, the record instance I returned. Also, the save returns a specific id that’s the same as the one defined in the context.

Finally, the expect API allows JEST to verify if the result of the function is the same as the one that should be.

Summary

Software testing, especially with tools like JEST, introduces an essential level of consistency vital for serious software development efforts. JEST enables testing of the code in its native form by simulating (mocking) various functions and objects that NetSuite provides to its SuiteApps. The library incorporated in the SDK features over 40 predefined stubs. These stubs permit the code to interact with SuiteScript modules during testing, ensuring coherent and predictable responses. Additionally, developers have the flexibility to create custom stubs to accommodate specific requirements that may not be covered by the default offerings. This adaptability ensures a comprehensive testing environment tailored to the unique needs of each development project.

 

Federico Donner

SDN Solutions Engineer at Oracle NetSuite

Federico is passionate about coding and technology in general. Has experience with full stack development and systems integrations, specializing in front end and scripting languages.


Previous Post

How to call a RESTlet from a script without the authorization header

Wilman Arambillete | 3 min read

Next Post


Managing SuiteApp API Secrets

Radek Felkl | 7 min read