Sithh writing testable code
- 1. Karol Kalisz, Digital Supply Chain & Internet of Things
Writing Testable Code Inspired by Functional
Programming and Microservice Rules
INSPIRE
- 2. © 2017 SAP SE or an SAP affiliate company. All rights reserved. 2Internal
What you will learn today?
You will learn how to create better code with
concepts from functional programing and
microservices.
You will be inspired to be a better developer.
- 3. © 2017 SAP SE or an SAP affiliate company. All rights reserved. 3Internal
Concepts of functional programing that are valuable for testing
Pure functions
Purely functional functions (or expressions) have no side effects.
– Pure functions have several useful properties, many of which can be used to optimize the code.
First-class and higher-order functions
Higher-order functions can take other functions as arguments or return them as results – first-class
functions.
Strict and non-strict evaluation
Use of strict (eager) or non-strict (lazy) evaluation – concepts that refer to how function arguments
are processed when an expression is being evaluated.
Strong recursion
Iteration (looping) in functional languages is usually accomplished through recursion.
– Recursive functions invoke themselves, allowing an operation to be performed over and over until
the base case is reached.
https://en.wikipedia.org/wiki/Functional_programming
- 4. © 2017 SAP SE or an SAP affiliate company. All rights reserved. 4Internal
Concepts of functional programing that are valuable for testing
Pure functions
Purely functional functions (or expressions) have no side effects.
– Pure functions have several useful properties, many of which can be used to optimize the code.
First-class and higher-order functions
Higher-order functions can take other functions as arguments or return them as results – first-class
functions.
Strict and non-strict evaluation
Use of strict (eager) or non-strict (lazy) evaluation – concepts that refer to how function arguments
are processed when an expression is being evaluated.
Strong recursion
Iteration (looping) in functional languages is usually accomplished through recursion.
– Recursive functions invoke themselves, allowing an operation to be performed over and over until
the base case is reached.
https://en.wikipedia.org/wiki/Functional_programming
No side effects
Function
as argument
Better
performance
Less code
- 5. © 2017 SAP SE or an SAP affiliate company. All rights reserved. 5Internal
Concepts of microservices that are important for testing
Properties
The services are easy to replace:
– Services are organized around capabilities, such as the user-interface front-end,
recommendation, logistics, and billing.
– [Services can be implemented using different programming languages, databases,
hardware, and software environment, depending on what fits best.]
Architecture
Services should be small and the protocols should lightweight. This approach:
– Makes it easier to change and add functions and qualities to the system at any time
– Allows the architecture of an individual service to emerge through continuous refactoring
and therefore reduces the need for a large up-front design
https://en.wikipedia.org/wiki/Microservices
- 6. © 2017 SAP SE or an SAP affiliate company. All rights reserved. 6Internal
Concepts of microservices that are important for testing
Properties
The services are easy to replace:
– Services are organized around capabilities, such as the user-interface front-end,
recommendation, logistics, and billing.
– [Services can be implemented using different programming languages, databases,
hardware, and software environment, depending on what fits best.]
Architecture
Services should be small and the protocols should lightweight. This approach:
– Makes it easier to change and add functions and qualities to the system at any time
– Allows the architecture of an individual service to emerge through continuous refactoring
and therefore reduces the need for a large up-front design
https://en.wikipedia.org/wiki/Microservices
Structure
Flexibility
Testability
Maintainability
- 7. © 2017 SAP SE or an SAP affiliate company. All rights reserved. 7Internal
Using language specialties you can improve the way you code
Example based on JavaScript
What is challenging in JavaScript?
Parameters are untyped.
JavaScript Object Notation (JSON) is great as a data model:
– Good application programming interface (API) for accessing JSON objects,
serialization, deserialization, and cloning
– Easy programmatic access to any JSON object properties
– Easy binding to UI elements (such as SAPUI5)
A lot of Open Source is available for use:
– No compilation step is present; you cannot control any APIs from other modules.
Check your own programming language – you will find similar values.
- 8. © 2017 SAP SE or an SAP affiliate company. All rights reserved. 8Internal
Using language specialties you can improve the way you code
Example based on JavaScript
What is challenging in JavaScript?
Parameters are untyped.
JavaScript Object Notation (JSON) is great as a data model:
– Good application programming interface (API) for accessing JSON objects,
serialization, deserialization, and cloning
– Easy programmatic access to any JSON object properties
– Easy binding to UI elements (such as SAPUI5)
A lot of Open Source is available for use:
– No compilation step is present; you cannot control any APIs from other modules.
Check your own programming language – you will find similar values.
First-class
functions
Clear,
serializable
data model
Need for
better
tests
- 9. Let’s bring it together
Functional programming
Microservices
JavaScript
- 10. © 2017 SAP SE or an SAP affiliate company. All rights reserved. 10Internal
Five modelling rules to create better code
5
modelling
rules
- you can consider -
1Writeallfunctionslikemicroservices
Inputparametersareeitherprimitiveor
assuredtobeserializable.
Functionscanbeexecutedstateless.
Outputcanbeserializedaswell.
- 11. © 2017 SAP SE or an SAP affiliate company. All rights reserved. 11Internal
Five modelling rules to create better code
Write all functions like microservices
Input parameters are either primitive or
assured to be serializable
Functions can be executed stateless
Output can be serialized as well
2Writeallfunctionslikepurefunctions
Nocallstootherfunctionsinside
Allrequiredparametersandmethodspassedasinput
parameters
1
- 12. © 2017 SAP SE or an SAP affiliate company. All rights reserved. 12Internal
Five modelling rules to create better code
Write all functions like pure functions
No calls to other functions inside
All required parameters and methods passed
as input parameters
1Writeallfunctionslikemicroservices
Inputparametersareeitherprimitiveor
assuredtobeserializable.
Functionscanbeexecutedstateless.
Outputcanbeserializedaswell.
3Abstractrealobjectsassoonaspossible
Inuserinterface(UI)events,createanindependentdata
modelthatwillbeusedforthefunctionalprocessing.
Allparameterspassedtofunctionsmustbeserializable
intostring.
2
- 13. © 2017 SAP SE or an SAP affiliate company. All rights reserved. 13Internal
Five modelling rules to create better code
Abstract real objects as soon as possible
In user interface (UI) events, create an
independent data model that will be used
for the functional processing.
All parameters passed to functions must be
serializable
into string.
2Writeallfunctionslikepurefunctions
Nocallstootherfunctionsinside
Allrequiredparametersandmethodspassedasinput
parameters
4UseJSONasdatamodel
Canbeserializedanytime
CanbeusedforbindingtoSAPUI5elements
IseasytoaccessnativelyinJavaScriptcode
3
- 14. © 2017 SAP SE or an SAP affiliate company. All rights reserved. 14Internal
Five modelling rules to create better code
Use JSON as data model
Can be serialized any time
Can be used for binding to SAPUI5 elements
Is easy to access natively in JavaScript code
3Abstractrealobjectsassoonaspossible
Inuserinterface(UI)events,createanindependentdata
modelthatwillbeusedforthefunctionalprocessing.
Allparameterspassedtofunctionsmustbeserializable
intostring.
5Createlibrarieswithstatelesslogic
Ensuresnoaccesstoobjectsandotherfunctions
Meanseasiertestingoffunctions
Noneedtomockcomplexobjects
4
- 15. © 2017 SAP SE or an SAP affiliate company. All rights reserved. 15Internal
Five modelling rules to create better code
Create libraries with stateless logic
Ensures no access to objects and other
functions
Means easier testing of functions
No need to mock complex objects
4UseJSONasdatamodel
Canbeserializedanytime
CanbeusedforbindingtoSAPUI5elements
IseasytoaccessnativelyinJavaScriptcode
Usingtherulesallfunctionswillbereproducible
(idempotent)
Sameinputparametersalwaysthesameoutput.
Betterandstabletestsareeasiertocreate.
5
- 16. © 2017 SAP SE or an SAP affiliate company. All rights reserved. 16Internal
Five modelling rules to create better code
Using the rules all functions will be
reproducible (idempotent)
Same input parameters
always the same output.
Better and stable tests are easier to create
Caching for better performance is easier
5Createlibrarieswithstatelesslogic
Ensuresnoaccesstoobjectsandotherfunctions
Meanseasiertestingoffunctions
Noneedtomockcomplexobjects
1.2.3.4.5…
- 17. Let’s see the code
One function
applied rules
additional test code
JavaScript
- 18. © 2017 SAP SE or an SAP affiliate company. All rights reserved. 19Internal
Let’s be technical – if you follow the rules, you can serialize your
tests with automation
/* find a free id for an array using given prefix */
sap.scn.nextFreeArrayId = function (arrayToCheck, prefix, idProperty, f) {
if(sap.scn.tlog) {
sap.scn.tlog.fentry("nextFreeArrayId", arrayToCheck, prefix, idProperty);
}
var natNumber = 1; // start with ID 1
var newId = prefix + natNumber;
newId = f.createId(prefix, natNumber); // create new ID if f given
var indexN = 0; // loop on given array
for (indexN; indexN < arrayToCheck.length; indexN++) {
var colO = arrayToCheck[indexN]; // read object on actual index
if (colO[idProperty] == (prefix + newId)) { // compare ID property
indexN = -1; // reset loop
natNumber++; // try next ID
newId = prefix + natNumber;
newId = f.createId(prefix, natNumber); // create new ID if f given
}
}
if(sap.scn.tlog) {
sap.scn.tlog.fret("nextFreeArrayId", newId);
sap.scn.tlog.fexit("nextFreeArrayId", arrayToCheck, prefix, idProperty);
}
return newId;
};
Input parameters
Record function entry
Record function exit
Function code
How it works?
Input:
arrayToCheck
[0].id = ELEMENT_1
[1].id = ELEMENT_2
[2].id = ELEMENT_4
prefix
“ELEMENT_”
idProperty
“id”
Output:
“ELEMENT_3”
Input functions (modifiers)
If (f & f.createId)
If (f & f.createId)
- 20. © 2017 SAP SE or an SAP affiliate company. All rights reserved.
Thank you
Contact information:
Karol Kalisz
Project Expert - Development
Digital Supply Chain & IoT
Your Take Aways
Upgrade your Knowledge on Functional
Programming
Google “Functional Programming”
Check other self-learning options
Upgrade your Knowledge on Microservices
Google “Microservices”
Try it out
Start (or Continue) improving your code with
corresponding tests
Better code -> less troubles
Less troubles -> better cloud solutions!
Check SAP community events and learning
Google “SAP Inside Track”
Try out any Open SAP courses