User Guide
  • Introduction
  • Overview
    • About 4WS.Platform
      • Architecture
      • Enterprise Edition
      • Tech specs and requirements
      • Warp SDK
    • Creating a web application
  • Core features
    • Tables
    • SqlTool
    • Definition of Data models and Relations
      • Relations
      • Reverse Engineering
      • Custom Fields
    • Defining business components
      • What are business components
      • Business components to fill-in panels
      • Creating business components
        • By a datastore entity
        • By a MongoDB collection
      • Defining Custom Java Business component
    • Defining the UI
      • App Designer
        • App Designer Menu
        • Definition of additional data sources
        • Panel containers and layouts
          • Tab panel
          • Alternative panel
          • Accordion panel
          • Vertical orientation panel
          • Horizontal orientation panel
          • Columns panel
          • Table panel
          • Generic panel
          • Responsive panel
        • Window content
          • Grid Panel
          • Form Panel
          • Filter Panel
          • Tree Panel
          • Google Map Panel
          • Preview Panel (old Image panel)
          • Tree + Grid Panel
          • Image Gallery
        • Windows list
        • Panel definition
          • Columns properties
          • Controls properties
          • Filter properties
          • Supported components
        • Variables
        • Code selectors
          • When not to use a dynamic combo-box
        • Smart Filter and Advanced Filter
        • Multi Value Combobox Filter
        • Multi Value Tree Filter
        • Buttons
        • Translations
          • Translations about GUI components and internationalization settings
          • Data coming from database
          • Custom code and translations
        • Application Menu
        • Bulk import binded to a grid
        • Range Date Filter
      • Web Interpreter
        • Grid components
        • Detail forms
        • Other components
        • Other features
          • Chat
        • Global variables
          • Client-side global variables
          • Server global variables
        • Forgot Password
    • Working with users and roles
      • Rule for roles
      • Permissions Administrator
    • Wizard
      • How to add a checkbox grid to select one or more rows
      • How to load a second grid when clicking on a row from the first grid
      • How to load a form when clicking on a row of the grid
      • How to open a window when double clicking on a row of the grid
      • How to open a window with right click on the popup menu
      • How to open a window when pressing a button on the grid toolbar
      • How to load a grid after loading a form
      • How to open a window when pressing a button on the form toolbar
      • How to load a grid when clicking on a tree node
      • How to load a form when clicking on a tree node
    • Defining events
      • Panel events
      • Column events
      • Control events
      • Filter events
      • Timer events
      • Start-End event
    • Server-side Javascript & Web Service
      • Server-side Javascript
      • Grid component filled by a server-side JS
      • Detail component filled by a server-side JS
      • How to define a server-side JavaScript action
      • Web service
  • Setting up the environment
    • How to install
    • Application parameters
    • Global parameters
  • Modules
    • Reports & Charts
      • Jasper Report + iReport
      • Online report
      • Docx templating
      • Charts
      • Pivot Grid
      • Multidimensional pivot grid
      • Data Export from SQL query
    • SSO
      • Identity management in Platform
        • Identity management on the internal Platform database
        • Identity management based on Google SSO
      • LDAP
        • LDAP support
        • Identity management based on LDAP and database
        • Identity management based on an embedded LDAP server used by Alfresco and or Activiti
        • Identity management based on a remote LDAP server to connect to Platform on the cloud
        • Connecting an LDAP server to Activiti BPM
        • Connecting an LDAP server to Alfresco ECM
      • Google SSO
        • Google SSO
        • Google OAuth2
        • Identity management based on Google SSO
      • Custom SSO
      • Firebase
    • Mobile
      • Mobile introduction
      • Offline vs Online
        • Server side features
        • Server side functionalities
        • Server side Platform features
        • Mobile app features
      • Mobile side specifics
        • Customizations
          • Custom theme editor
        • App Menu
        • Window content
          • Detail scrollable form
          • Scrollable paginated grid
          • Constraint layout
          • Constraint panel
          • Collection grid view
          • Preview panel (mobile)
        • Form Controls
      • Reference guide
      • Cleaning up data
      • How to
      • App deployment
        • App deployment for the iOS platform
        • App deployment for the Android platform
      • Style properties
      • Appendix : Synchronization flow
      • Translations
    • GSuite
      • Introduction
      • Client-side integration
      • GMail
      • Calendar
      • Drive
      • Contacts
    • Google Cloud Platform
      • Datastore
        • Google Datastore Introduction
        • How to create Datastore entities
      • Google Cloud Storage
    • Scheduler
      • Scheduler Introduction
      • Process settings
        • How to define a sequence of consecutive processes
        • How to define a Custom Java Business component
        • How to define a Grid Data Import
        • How to define a server-side Javascript action
      • Email notifications
      • Process executions
      • Manually start a scheduled process
      • Process input parameters
    • Queue Manager
    • Log & Analysis
      • Application Log
      • Log statistics
      • App analyzer
      • Table log
      • Threads
      • Sessions and heap memory
      • Heap memory analysis
      • Access Log
      • Datastore statistics
      • Total monthly costs with Google Datastore
      • Service Monitoring
        • Introduction
        • Defining a service to monitor
        • Notifications setup
        • Events automatically managed by Platform
        • Remote Platform servers
        • Knowledge base
        • Adding log programatically
        • Searching for logged data
        • Use cases
    • File Management
    • Export and Import of Metadata
      • Application Metadata Management
    • Trigger writing operations
    • Audit
    • BPM
      • BPMN Introduction
      • BPMN main parts
      • Activiti Setup
      • Platform integration
        • Processes
        • Models
        • Process instances
        • To-do list
        • Process history
      • Process Web Modeler
        • Model Creation
          • Start-End Event
          • Gateways
        • Supported objects
        • Start tasks and user tasks
        • Form properties
          • Important notes
          • Property types
        • Service tasks
          • Web service
          • SQL Query
          • SQL statement
        • Mail task
        • Script task
          • Example : how to get a value previously read from a SQL query
          • Example : how to get the current process instance id
        • Timer events
        • Subprocess and Call Activiti
      • Utility methods available in Platform
        • How to start a process from a JavaScript action
        • How to complete a user task from a JavaScript action
      • An example
        • Processes
        • Instances
        • Activities
        • History
    • Embedded CMS
    • ECM
      • Alfresco
        • Alfresco Introduction
        • Integration between 4WS.Platform and Alfresco
          • Integration at GUI level
          • Integration at model level
          • Integration at authentication and authorizations level
          • Additional features
        • How to use 4WS.Platform and Alfresco together
          • Set the same Identity Management system
          • Define document types and aspects in Alfresco
          • Import the document types and aspects definitions in 4WS.Platform
          • Define document types and aspects in 4WS.Platform
          • Reverse engineering of document types or aspects
          • Definition of business components to fill-in panels
          • Definition of the GUI
          • Additional server-side services
        • Requirements
        • Current limits in 4WS.Platform - Alfresco integration
      • Archiflow
        • Setup
        • Archiflow artifacts
        • How to
    • Lotus Notes Migration Tool
    • NoSQL databases
      • MongoDB
        • MongoDB Introduction
        • Setting up the environment
        • How to create collections
        • How to create business components
        • How to create windows filled with data coming from MongoDB collections
        • Design rules
      • Google Datastore
        • Google Datastore Introduction
        • Setting up the environment
        • How to create entities
        • How to create business components
        • How to create windows filled with data coming from Datastore entities
        • Design rules
    • TensorFlow
    • Web Page Development
      • Pure Web Page Development
      • Google Material Design development
      • Appendix A - a complete example without any lib
      • Appendix B - a complete example with Google MD
    • Jira Integration
    • Platform for GAE
    • SQL errors management
    • Multidimensional pivot grid
    • Quality
      • Automated Web Service Testing
      • Automated unit testing
      • Source code static analysis using ESlint
      • Source code static analysis using SonarQube
  • Troubleshootings
  • Best practises
    • Database design
    • Database maintenance
    • Creating a Web app : common use cases
    • Creating a mobile app : common use cases
Powered by GitBook
On this page
  • Executing a test case
  • Exporting results in JUnit format
  • Test Driven Development

Was this helpful?

  1. Modules
  2. Quality

Automated unit testing

Unit testing is a software testing method by which individual units of source code (e.g. server-side javascript/GAE actions) are tested to determine whether they are fit for use.

When a developer is creating a server-side javascript/GAE action, he is free to organize the content as he wish. A good way to organize the content is by splitting up code into functions declarations.

Look at these two examples:

1) all code is in-line:

var companyId = "00000";
var siteId = 100;
var userCodeId = "ADMIN";

// reading users
var json = utils.executeQuery(
  "SELECT * FROM PRM01_USERS where COMPANY_ID=? AND SITE_ID=? AND USER_CODE_ID=?",
  null,
  false,
  true,
  [companyId,siteId,userCodeId]
);
var list = JSON.parse(json);

var total = list.length;

utils.setReturnValue(JSON.stringify({
    num: total,
    success: true
}));

2) code is splitted up in declared functions; then these are invoked:


function listaUtenti(companyId,siteId,userCodeId) {
    var json = utils.executeQuery("SELECT * FROM PRM01_USERS where COMPANY_ID=? AND SITE_ID=? AND USER_CODE_ID=?",null,false,true,[companyId,siteId,userCodeId]);
    var list = JSON.parse(json);
    list.push(user);
    return list;
}

function totale() {
    return listaUtenti("00000",100,"ADMIN").length;
}

utils.setReturnValue(JSON.stringify({
    num: totale(),
    success: true
}));

The second one is easily testable, since the code has been organized in a TDD (test driven development) approach, i.e. first the developer thought about the portions of code to test before writing code within the declared functions (See the paragraph below for more details).

In this way, functions can be tested separately and in a specific order.

Platform provides a new folder to prepare unit tests:

The first time the folder is opened, Platform proposes 2 fixed methods:

  • setUpBeforeClass (as in JUnit), where the developer can include js code to initialize the test case: it will be invoked by Platform before executing the xxxMethodName functions

  • tearDownAfterClass (as in JUnit), where the developer can include js code to remove data or anything else at the end of the test case: it will be invoked by Platform after executing the xxxMethodName functions

In addition, there is a testxxx function, for each method found in the server-side js action.

Within each testxxx method, you are free to use all js functions available.

Moreover you can also set which user to use when executing the test case/action under test, through the following js function:

utils.setUserInfo(String companyId,Long siteId,String username,String languageId)

Finally, a test case method should always contain assertions. These are the available methods:

assertEquals(expected,actual)
assertNotEquals(expected,actual)
assertTrue(expected)
fail(msg)

Executing a test case

The last button in the toolbar allows to execute manually the unit test and a dialog is prompted at the end to report the results.

Moreover, the list of actions is updated with the outcome of the test execution (red vs green).

Note that an empty cell means that there is not a unit test defined.

The coverage column represents the coverage of the source code (number of functions under test).

When defining a unit test, it is a good practice to specify a collection, in order to group together unit tests related to similar functionalities.

Finally, you can schedule the execution of all unit tests belonging to the same collection: in this way, you can update the outcome on a daily basis.

If you define also a notification, it is possible to receive an email reporting all outcomes.

Example of notification:

In data :DATE sono stati eseguiti i test automatici per l'applicazione Platform Web 6.0.2 
<br/> 
<br/> 
<br/> 
Report dei test eseguiti: <br/>
 :EXIT_MESSAGE <br/> 
 <br/> 
 <br/> 
 <center><i>Questo è un messaggio automatico. Non rispondere a questa email. </i></center>

The predefined :EXIT_MESSAGE variable would generate HTML code containing the report of all unit test executions.

Exporting results in JUnit format

Finally, it is also possible to integrate the unit test outcomes with a continuous integration tool like Jenkins, through a Platform web service:

https://myhost/mywebapp/getActions/executeCollection?appId=...&collection=...&company...&siteId=..&username=..&password=...

This web service will provide an XML content in JUnit format, containing the outcomes for all unit tests belonging to the specified collection.

Test Driven Development

Test-driven development is a software development process relying on software requirements being converted to test cases before software is fully developed, and tracking all software development by repeatedly testing the software against all test cases.

The test-driven development cycle is composed of 3 main steps:

1. Writing the tests first: the tests should be written before the functionality that is to be tested. To say it in another way, decompose your functionality in functions, but declare functions, DO NOT define them and the function declaration should be carried out in terms of tests to perform: for each function declared, prepare a test for it, i.e. implement all the test but the corresponding function under test.

Since all functions composing the functionality are only declared but not implemented, all test case fails initially: this ensures that the test really works and can catch an error: this is the red state.

2. Implementing the functions under test: once the test cases have been implemented and "work", the underlying functionality can be implemented, let's say in the simplest naive way.

Test-driven development constantly repeats the steps of adding test cases that fail and then passing them (green state).

3. Refactoring: the "test-driven development mantra" is the "red/green/refactor" cycle, where red means fail and green means pass: the refactoring of the functions under test is needed for readability and maintainability. In particular, hard-coded test data should be removed. Running the test suite after each refactor helps ensure that no existing functionality is broken.

PreviousAutomated Web Service TestingNextSource code static analysis using ESlint

Last updated 2 years ago

Was this helpful?