SlideShare a Scribd company logo
1 of 56
Testing Business Logic
Using DSLs in Clojure
Mayank Jain
Test Engineer
A TALK, IN 6 PARTS
1. What is the problem?
2. Real World Example.
3. Demo of the actual code.
4. Other features tested using same ideas.
5. Advantages/Disadvantages of writing DSLs for testing.
6. QA.
WHAT IS THE PROBLEM?
Testing real world stateful business logic is hard
Microwave Oven State Machine
Business logic is Stateful
Microwave Oven State Machine
Large number transition states
Difficult to enumerate all possible cases
Microwave Oven State Machine
Tests become unreadable
Microwave Oven State Machine
HELPSHIFT
• Embeddable support desk for native apps
• Main Features:
• Frequently Asked Questions which
customers can search
• File issues/tickets from within the app
Helpshift
Supercell
Clash of Clans
Gaana
General Billing
Domain
App
Section
FAQ 1 FAQ 2FAQs
Boom Beach Gaana App
Translations English Content Hindi Content
….
….
….
….
….
Top Down View of FAQs
Example of Gaana FAQ Page
Customers can search FAQs
Available FAQs FAQ Sections
Domain
App
FAQ Title
FAQ Body
FAQ is Visible?
PROBLEM
You cannot share FAQs across apps.
Big Customers have multiple apps which have same
FAQ translations content example “Privacy Policy”
FEATURE: LINKED FAQS
{:published? false
:id “faq-id-1”
:app_id “app-1”
:section_id “section-1”
:translations
{:en {:published? false
:stags []
:body “Privacy Body”
:title “Privacy Title”}}
:linked_faq_ids [“faq-id-2”]
:publish_id “1”}
App-1
{:published? false
:id “faq-id-2”
:app_id “app-2”
:section_id “section-2”
:translations
{:en {:published? false
:stags []
:body “Privacy Body"
:title “Privacy Title"}}
:linked_faq_ids [“faq-id-1”]
:publish_id “2”}
App-2
faq 1
(Sync faq-1 to App-2)General
faq 2
General
{:published? false
:id “faq-id-1”
:app_id “app-1”
:section_id “section-1”
:translations
{:en {:published? false
:stags []
:body “Update Body”
:title “Privacy Title”}}
:linked_faq_ids [“faq-id-2”]
:publish_id “1”}
{:published? false
:id “faq-id-2”
:app_id “app-2”
:section_id “section-2”
:translations
{:en {:published? false
:stags []
:body “Privacy Body"
:title “Privacy Title"}}
:linked_faq_ids [“faq-id-1”]
:publish_id “2”}
faq 1
Sync
faq 2
Update FAQ 1’s Body
{:published? false
:id “faq-id-1”
:app_id “app-1”
:section_id “section-1”
:translations
{:en {:published? false
:stags []
:body “Update Body”
:title “Privacy Title”}}
:linked_faq_ids [“faq-id-2”]
:publish_id “1”}
{:published? false
:id “faq-id-2”
:app_id “app-2”
:section_id “section-2”
:translations
{:en {:published? false
:stags []
:body “Update Body"
:title “Privacy Title"}}
:linked_faq_ids [“faq-id-1”]
:publish_id “2”}
faq 1
Sync
faq 2
Update FAQ 1’s Body
EXAMPLE TEST CASE
1. Add 1st App with only English languages.
2. Add 2nd App with only English languages
3. Add 1st FAQ under 1st App
4. Link 1st FAQ to 2nd App to create 2nd FAQ
5. Check -> translations of 2nd FAQ == 1st FAQ
6. Update English title of FAQ-1
7. Check -> translations of 2nd FAQ == 1st FAQ
8. Delete FAQ-1
9. Check if 1st FAQ is deleted in DB
10.Assert 2nd FAQ should remain as it is in database.
Simulation Verification
PARTS OF EACH ACTION
“Add APP-1 with only English language”
1. Type of Action Add an App
2. Names App-1
3. Arguments English Language
4. Expected Result As per Spec/Modal of the system
5. Actual Result Database
EXPRESS ACTIONS AS
CLOJURE DATA
“Add app APP-1 with English language”
:add-app :app-1 {:langs-config [:en]}
ONE UNIT OF ACTION
[:add-app :app-1 {:langs-config [:en]}]
SERIES OF ACTIONS
[[:add-app :app-1 {:langs-config [:en]]
[:add-app :app-2 {:langs-config nil}]
[:add-faq :faq-1 {:app-var :app-1 ...}]
[:link-faq :faq-2 {:faq-var :faq-1 :app-var :app-2 ...}]
[:update-faq nil {:app-var :app-1 :faq var :faq-1 ...}]
[:update-faq nil {:app-var :app-2 :faq-var :faq-2 ...}]
[:delete-faq nil {:faq-var :faq-1 ...}]]
REDUCE ON ACTIONS
Reduce
{}
[:add-app :app-1 {:langs-config nil}])
{:env {:apps {:app-1 {…}}}
:result [{result-1…}]}
…..}
Reduce
[:add-app :app-2 {:langs-config nil}])
{:env {:apps {:app-1 {…}
:app-2 {…}}}
:result [{result-1…}
{result-2…}]}
…..}
{:env {:apps {:app-1 {…}}}
:result [{result-1…}]}
…..}
And so on…
RESULT HASH-MAP COMPRISES OF
{:env {:apps {:app-1 {:app-id “970"}
:app-2 {:app-id “142”}}}
:faqs {:faq-1 {:faq-id “112”}}}}
:result [{:action-type :add-faq
:expected {….}
:actual {….}}
{…more}]
“112” {…state…}
…more}
Environment (:env) - Contains bindings of vars
RESULT HASH-MAP COMPRISES OF
{:env {:apps {:app-1 {:app-id “970"}
:app-2 {:app-id “142”}}}
:faqs {:faq-1 {:faq-id “112”}}}}
:result [{:action-type :add-faq
:expected {….}
:actual {….}}
{…more}]
“112” {…state…}
…more}
Result (:result) - Contains Actual And Expected Result
RESULT HASH-MAP COMPRISES OF
{:env {:apps {:app-1 {:app-id “970"}
:app-2 {:app-id “142”}}}
:faqs {:faq-1 {:faq-id “112”}}}}
:result [{:action-type :add-faq
:expected {….}
:actual {….}}
{…more}]
“112” {…state…}
…more}
Current Generated Expected State
Dispatch On Action Type
Update The Variables in
arguments to its bindings
Call args with relevant
function
Bind the result to the given
var in Global Data
Store Expected current
state
Store Actual current
database state
What
happens
inside
the
reducer?
Dispatch On Action Type
Update The Variables in
arguments to its bindings
Call args with relevant
function
Bind the result to the given
var in Global Data
Store Expected current
state
Store Actual current
database state
[:add-app :app-1 {:langs-config nil}])
[:add-app :app-1 {:langs-config nil}])
(add-app {:langs-config nil})
{:env {:apps {:app-1 {:app-id "970"}}}}
Dispatch On Action Type
Update The Variables in
arguments to its bindings
Call args with relevant
function
Bind the result to the given
var in Global Data
Store Expected current
state
Store Actual current
database state
[:add-app :app-2 {:langs-config nil}])
[:add-app :app-2 {:langs-config nil}])
(add-app {:langs-config nil})
{:env {:apps {:app-1 {:app-id “970"}
:app-2 {:app-id “142"}}}}
Dispatch On Action Type
Update The Variables in
arguments to its bindings
[:add-faq :faq-1 {:app-var :app-1 ….}])
{:env {:apps {:app-1 {:app-id “970"}
:app-2 {:app-id “142”}}}
Dispatch On Action Type
Update The Variables in
arguments to its bindings
[:add-faq :faq-1 {:app-var :app-1 ….}])
[:add-faq :faq-1 {:app-id “970” …}])
{:env {:apps {:app-1 {:app-id “970"}
:app-2 {:app-id “142”}}}
Dispatch On Action Type
Update The Variables in
arguments to its bindings
Call args with relevant
function
Bind the result to the given
var in Global Data
[:add-faq :faq-1 {:app-var :app-1 ….}])
[:add-faq :faq-1 {:app-id “970” …}])
(add-faq {:app-id “970” ….})
Dispatch On Action Type
Update The Variables in
arguments to its bindings
Call args with relevant
function
Bind the result to the given
var in Global Data
[:add-faq :faq-1 {:app-var :app-1 ….}])
[:add-faq :faq-1 {:app-id “970” …}])
(add-faq {:app-id “970” ….})
{:env {:apps {:app-1 {:app-id “970"}
:app-2 {:app-id “142”}}
:faqs {:faq-1 {:faq-id “112”}}}}
Dispatch On Action Type
Update The Variables in
arguments to its bindings
Call args with relevant
function
Bind the result to the given
var in Global Data
Store Expected current
state
[:add-faq :faq-1 {:app-var :app-1 ….}])
[:add-faq :faq-1 {:app-id “970” …}])
(add-faq {:app-id “970” ….})
{:env {:apps {:app-1 {:app-id “970"}
:app-2 {:app-id “142”}}
:faqs {:faq-1 {:faq-id “112”}}}}
{:env {:apps {:app-1 {:app-id “970"}
:app-2 {:app-id “142”}}}
:faqs {:faq-1 {:faq-id “112”}}}}
:result [{:action-type :add-faq
:expected {….}}
Dispatch On Action Type
Update The Variables in
arguments to its bindings
Call args with relevant
function
Bind the result to the given
var in Global Data
Store Expected current
state
Store Actual current
database state
[:add-faq :faq-1 {:app-var :app-1 ….}])
[:add-faq :faq-1 {:app-id “970” …}])
(add-faq {:app-id “970” ….})
{:env {:apps {:app-1 {:app-id “970"}
:app-2 {:app-id “142”}}
:faqs {:faq-1 {:faq-id “112”}}}}
{:env {:apps {:app-1 {:app-id “970"}
:app-2 {:app-id “142”}}}
:faqs {:faq-1 {:faq-id “112”}}}}
:result [{:action-type :add-faq
:expected {….}
:actual {….}}
VERIFICATION:
COMPARE EXPECTED VS ACTUAL FOR EACH STEP
COMPARE RESULT FOR
FIRST ACTION
{"112"
{:translations
{:en
{:published? false,
:stags [],
:body "Temp body",
:title “Title 1"}},
:linked-faq-ids #{}}}
Actual Data in DB
Expected Data
from my Generated result
{"112"
{:translations
{:en
{:published? false,
:stags [],
:body "Temp body",
:title “Title 1"}},
:linked-faq-ids #{}}}
==
PASS
:title "Title 1"
Actual Data in DB
Expected Data
from my Generated result
:title "Title 2"
==
FAIL
COMPARE RESULT FOR
SECOND ACTION
DEMO TIME
APPROACHES TO VERIFY
Actions : Hardcoded
Expected Output : Hardcoded
Actions : Simulated
Expected Output : Hardcoded
Actions : Simulated
Expected Output : Generated
Actions : Generated
Expected Output : Generated
Hardcoded Actions,
Hardcoded Expected Output
ADVANTAGES DISADVANTAGES
Requires no extra knowledge to
understand
Very cumbersome to
enumerate
Anyone can add/edit tests Modification is hard
False negatives are not possible
Simulate list of Actions,
Hardcoded Final Expected Output
ADVANTAGES DISADVANTAGES
Easy to enumerate
Requires knowledge of the
DSL
Very readable
Maintenance overhead of
DSL
Shareable with dev to simulate
bugs
Does not check intermediate
state
False negatives are not possible
Expected output may have
data which is available only
at runtime like faq-ids
Simulate list of actions,
Generate Expected Output
ADVANTAGES DISADVANTAGES
Easy to enumerate
Requires knowledge of the
DSL
Very readable
Maintenance overhead of
DSL
Shareable with dev to simulate
bugs
Maintenance overhead of
Expected Modal
Checks intermediate state False negatives are possible
Runtime data is available like
faq-ids
Generate Actions,
Generate Expected Output
ADVANTAGES DISADVANTAGES
Possible to generate large
number of tests
Requires knowledge of the
DSL
Possible to Shrink failed test
case using test.check library
Maintenance overhead of
DSL
Shareable with dev to simulate
bugs
Maintenance overhead of
Expected Modal
Checks intermediate state False negatives are possible
Maintenance overhead of
generative code for list of
actions.
Generate Actions,
Generate Expected Output
Feature - Issue Audit Trail
Issue Audit Trail
• Maintains a log of
• Who Took an action
• What Action they took
Who - Types of Users
App User Support User
Agents Admins
Helpshift
What - Types of Actions
App User
• Create Issue
• Reply Issue
• etc…
Admin User
• Create Issue
• Reply Issue
• Resolve Issue
• Edit Tags
• etc…
Agent User
• Create Issue
• Reply Issue
• Resolve Issue
• Edit Tags
• etc…
App User
Admin
“Mayank”
Agent
“Agent-2”
Example Issue
Example Issue
Issue
Audit
Logs
DEMO - ISSUE AUDIT TRAIL
Generate Actions,
Generate Expected Output
ADVANTAGES OF WRITING DSL
Discovering very hard to find bugs, for example we found:
Duplicate issue messages being rendered only if the
number of messages were "just right".
Finding ordering bugs.
Increase in developer/tester productivity
DISADVANTAGES OF WRITING DSL
Cost of maintaining DSLs is high.
If your DSL is just data being evaluated at run time,
changes in feature code will not throw any compile time
errors like function parameters being changed in DSL
code.
You have to educate your team members to learn your
specific DSL for that feature to be able to understand the
tests.
CONCLUSION
DSL can be used as a workflow for writing tests.
Separating simulation vs verification of tests.
A step towards ability to generate tests instead of writing
them.
Further Resources
• Clojure Made Simple - Rich Hickey
• Growing a DSL with Clojure
• Jeanine Adkisson - Design and Prototype a Language
In Clojure
• John Hughes - Testing the Hard Stuff and Staying Sane
• Reid Draper - Powerful Testing with test.check
• Clojure Tutorials on DSLs with Tim Baldridge (Paid)
Any Questions?
@firesofmay
facebook.com/firesofmay/
firesofmay@gmail.com

More Related Content

Similar to Testing business-logic-in-dsls

Me and my importers
Me and my importersMe and my importers
Me and my importersDonny Wals
 
React native meetup 2019
React native meetup 2019React native meetup 2019
React native meetup 2019Arjun Kava
 
Engineering Velocity @indeed eng presented on Sept 24 2014 at Beyond Agile
Engineering Velocity @indeed eng presented on Sept 24 2014 at Beyond AgileEngineering Velocity @indeed eng presented on Sept 24 2014 at Beyond Agile
Engineering Velocity @indeed eng presented on Sept 24 2014 at Beyond AgileKenAtIndeed
 
Breaking Limits on Mobile HTML5 - TopConf Tallinn
Breaking Limits on Mobile HTML5 - TopConf TallinnBreaking Limits on Mobile HTML5 - TopConf Tallinn
Breaking Limits on Mobile HTML5 - TopConf TallinnMaximiliano Firtman
 
Linked In Weekly Status Report (062011 062511)(1)
Linked In Weekly Status Report (062011 062511)(1)Linked In Weekly Status Report (062011 062511)(1)
Linked In Weekly Status Report (062011 062511)(1)RuxanaT
 
DSR Testing (Part 2)
DSR Testing (Part 2)DSR Testing (Part 2)
DSR Testing (Part 2)Steve Upton
 
Passenger 6 generic language support presentation
Passenger 6 generic language support presentationPassenger 6 generic language support presentation
Passenger 6 generic language support presentationHongli Lai
 
[QE 2018] Adam Stasiak – Nadchodzi React Native – czyli o testowaniu mobilnyc...
[QE 2018] Adam Stasiak – Nadchodzi React Native – czyli o testowaniu mobilnyc...[QE 2018] Adam Stasiak – Nadchodzi React Native – czyli o testowaniu mobilnyc...
[QE 2018] Adam Stasiak – Nadchodzi React Native – czyli o testowaniu mobilnyc...Future Processing
 
Reactive programming in clojure script using reactjs wrappers
Reactive programming in clojure script using reactjs wrappersReactive programming in clojure script using reactjs wrappers
Reactive programming in clojure script using reactjs wrappersKonrad Szydlo
 
QA Fest 2018. Adam Stasiak. React Native is Coming – the story of hybrid mobi...
QA Fest 2018. Adam Stasiak. React Native is Coming – the story of hybrid mobi...QA Fest 2018. Adam Stasiak. React Native is Coming – the story of hybrid mobi...
QA Fest 2018. Adam Stasiak. React Native is Coming – the story of hybrid mobi...QAFest
 
GraphQL Munich Meetup #1 - How We Use GraphQL At Commercetools
GraphQL Munich Meetup #1 - How We Use GraphQL At CommercetoolsGraphQL Munich Meetup #1 - How We Use GraphQL At Commercetools
GraphQL Munich Meetup #1 - How We Use GraphQL At CommercetoolsNicola Molinari
 
Open Social In The Enterprise
Open Social In The EnterpriseOpen Social In The Enterprise
Open Social In The EnterpriseTim Moore
 
Progressive Web Apps. What, why and how
Progressive Web Apps. What, why and howProgressive Web Apps. What, why and how
Progressive Web Apps. What, why and howRiza Fahmi
 
"Progressive Web Apps" by Riza Fahmi (Hacktiv8)
"Progressive Web Apps" by Riza Fahmi	(Hacktiv8)"Progressive Web Apps" by Riza Fahmi	(Hacktiv8)
"Progressive Web Apps" by Riza Fahmi (Hacktiv8)Tech in Asia ID
 
Heroku Introduction: Scaling customer facing apps & services
Heroku Introduction: Scaling customer facing apps & servicesHeroku Introduction: Scaling customer facing apps & services
Heroku Introduction: Scaling customer facing apps & servicesJohn Stevenson
 
Declaring Server App Components in Pure Java
Declaring Server App Components in Pure JavaDeclaring Server App Components in Pure Java
Declaring Server App Components in Pure JavaAtlassian
 
Netserv Software Testing
Netserv Software TestingNetserv Software Testing
Netserv Software Testingsthicks14
 
Test driven development with behat and silex
Test driven development with behat and silexTest driven development with behat and silex
Test driven development with behat and silexDionyshs Tsoumas
 

Similar to Testing business-logic-in-dsls (20)

Me and my importers
Me and my importersMe and my importers
Me and my importers
 
React native meetup 2019
React native meetup 2019React native meetup 2019
React native meetup 2019
 
Engineering Velocity @indeed eng presented on Sept 24 2014 at Beyond Agile
Engineering Velocity @indeed eng presented on Sept 24 2014 at Beyond AgileEngineering Velocity @indeed eng presented on Sept 24 2014 at Beyond Agile
Engineering Velocity @indeed eng presented on Sept 24 2014 at Beyond Agile
 
Breaking Limits on Mobile HTML5 - TopConf Tallinn
Breaking Limits on Mobile HTML5 - TopConf TallinnBreaking Limits on Mobile HTML5 - TopConf Tallinn
Breaking Limits on Mobile HTML5 - TopConf Tallinn
 
Linked In Weekly Status Report (062011 062511)(1)
Linked In Weekly Status Report (062011 062511)(1)Linked In Weekly Status Report (062011 062511)(1)
Linked In Weekly Status Report (062011 062511)(1)
 
DSR Testing (Part 2)
DSR Testing (Part 2)DSR Testing (Part 2)
DSR Testing (Part 2)
 
Passenger 6 generic language support presentation
Passenger 6 generic language support presentationPassenger 6 generic language support presentation
Passenger 6 generic language support presentation
 
[QE 2018] Adam Stasiak – Nadchodzi React Native – czyli o testowaniu mobilnyc...
[QE 2018] Adam Stasiak – Nadchodzi React Native – czyli o testowaniu mobilnyc...[QE 2018] Adam Stasiak – Nadchodzi React Native – czyli o testowaniu mobilnyc...
[QE 2018] Adam Stasiak – Nadchodzi React Native – czyli o testowaniu mobilnyc...
 
Reactive programming in clojure script using reactjs wrappers
Reactive programming in clojure script using reactjs wrappersReactive programming in clojure script using reactjs wrappers
Reactive programming in clojure script using reactjs wrappers
 
QA Fest 2018. Adam Stasiak. React Native is Coming – the story of hybrid mobi...
QA Fest 2018. Adam Stasiak. React Native is Coming – the story of hybrid mobi...QA Fest 2018. Adam Stasiak. React Native is Coming – the story of hybrid mobi...
QA Fest 2018. Adam Stasiak. React Native is Coming – the story of hybrid mobi...
 
GraphQL Munich Meetup #1 - How We Use GraphQL At Commercetools
GraphQL Munich Meetup #1 - How We Use GraphQL At CommercetoolsGraphQL Munich Meetup #1 - How We Use GraphQL At Commercetools
GraphQL Munich Meetup #1 - How We Use GraphQL At Commercetools
 
Open Social In The Enterprise
Open Social In The EnterpriseOpen Social In The Enterprise
Open Social In The Enterprise
 
Progressive Web Apps. What, why and how
Progressive Web Apps. What, why and howProgressive Web Apps. What, why and how
Progressive Web Apps. What, why and how
 
"Progressive Web Apps" by Riza Fahmi (Hacktiv8)
"Progressive Web Apps" by Riza Fahmi	(Hacktiv8)"Progressive Web Apps" by Riza Fahmi	(Hacktiv8)
"Progressive Web Apps" by Riza Fahmi (Hacktiv8)
 
Heroku Introduction: Scaling customer facing apps & services
Heroku Introduction: Scaling customer facing apps & servicesHeroku Introduction: Scaling customer facing apps & services
Heroku Introduction: Scaling customer facing apps & services
 
Gain more freedom when migrating from Camunda 7 to 8.pdf
Gain more freedom when migrating from Camunda 7 to 8.pdfGain more freedom when migrating from Camunda 7 to 8.pdf
Gain more freedom when migrating from Camunda 7 to 8.pdf
 
Declaring Server App Components in Pure Java
Declaring Server App Components in Pure JavaDeclaring Server App Components in Pure Java
Declaring Server App Components in Pure Java
 
Netserv Software Testing
Netserv Software TestingNetserv Software Testing
Netserv Software Testing
 
Test driven development with behat and silex
Test driven development with behat and silexTest driven development with behat and silex
Test driven development with behat and silex
 
behat
behatbehat
behat
 

More from Mayank Jain

Nasscom Demystifying Blockchain 101
Nasscom Demystifying Blockchain 101Nasscom Demystifying Blockchain 101
Nasscom Demystifying Blockchain 101Mayank Jain
 
Nasscom Ahmedabad Demystifying blockchain 101
Nasscom Ahmedabad Demystifying blockchain 101Nasscom Ahmedabad Demystifying blockchain 101
Nasscom Ahmedabad Demystifying blockchain 101Mayank Jain
 
Demystifying blockchain Dec'18
Demystifying blockchain Dec'18Demystifying blockchain Dec'18
Demystifying blockchain Dec'18Mayank Jain
 
Introduction to blockchain
Introduction to blockchainIntroduction to blockchain
Introduction to blockchainMayank Jain
 
Asset tokenisation
Asset tokenisationAsset tokenisation
Asset tokenisationMayank Jain
 
Asset tokenisation Old
Asset tokenisation OldAsset tokenisation Old
Asset tokenisation OldMayank Jain
 
Informal talk at pict
Informal talk at pictInformal talk at pict
Informal talk at pictMayank Jain
 

More from Mayank Jain (7)

Nasscom Demystifying Blockchain 101
Nasscom Demystifying Blockchain 101Nasscom Demystifying Blockchain 101
Nasscom Demystifying Blockchain 101
 
Nasscom Ahmedabad Demystifying blockchain 101
Nasscom Ahmedabad Demystifying blockchain 101Nasscom Ahmedabad Demystifying blockchain 101
Nasscom Ahmedabad Demystifying blockchain 101
 
Demystifying blockchain Dec'18
Demystifying blockchain Dec'18Demystifying blockchain Dec'18
Demystifying blockchain Dec'18
 
Introduction to blockchain
Introduction to blockchainIntroduction to blockchain
Introduction to blockchain
 
Asset tokenisation
Asset tokenisationAsset tokenisation
Asset tokenisation
 
Asset tokenisation Old
Asset tokenisation OldAsset tokenisation Old
Asset tokenisation Old
 
Informal talk at pict
Informal talk at pictInformal talk at pict
Informal talk at pict
 

Recently uploaded

Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Andreas Granig
 
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Matt Ray
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based projectAnoyGreter
 
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...OnePlan Solutions
 
Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Velvetech LLC
 
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...OnePlan Solutions
 
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Cizo Technology Services
 
What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...Technogeeks
 
How To Manage Restaurant Staff -BTRESTRO
How To Manage Restaurant Staff -BTRESTROHow To Manage Restaurant Staff -BTRESTRO
How To Manage Restaurant Staff -BTRESTROmotivationalword821
 
VK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web DevelopmentVK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web Developmentvyaparkranti
 
SpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at RuntimeSpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at Runtimeandrehoraa
 
英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作qr0udbr0
 
Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)Ahmed Mater
 
Innovate and Collaborate- Harnessing the Power of Open Source Software.pdf
Innovate and Collaborate- Harnessing the Power of Open Source Software.pdfInnovate and Collaborate- Harnessing the Power of Open Source Software.pdf
Innovate and Collaborate- Harnessing the Power of Open Source Software.pdfYashikaSharma391629
 
Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...Rob Geurden
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024StefanoLambiase
 
Introduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfIntroduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfFerryKemperman
 
Implementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureImplementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureDinusha Kumarasiri
 
Unveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesUnveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesŁukasz Chruściel
 
Xen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdfXen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdfStefano Stabellini
 

Recently uploaded (20)

Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024
 
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based project
 
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
 
Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...
 
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
 
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
 
What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...
 
How To Manage Restaurant Staff -BTRESTRO
How To Manage Restaurant Staff -BTRESTROHow To Manage Restaurant Staff -BTRESTRO
How To Manage Restaurant Staff -BTRESTRO
 
VK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web DevelopmentVK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web Development
 
SpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at RuntimeSpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at Runtime
 
英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作
 
Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)
 
Innovate and Collaborate- Harnessing the Power of Open Source Software.pdf
Innovate and Collaborate- Harnessing the Power of Open Source Software.pdfInnovate and Collaborate- Harnessing the Power of Open Source Software.pdf
Innovate and Collaborate- Harnessing the Power of Open Source Software.pdf
 
Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
 
Introduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfIntroduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdf
 
Implementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureImplementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with Azure
 
Unveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesUnveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New Features
 
Xen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdfXen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdf
 

Testing business-logic-in-dsls

  • 1. Testing Business Logic Using DSLs in Clojure Mayank Jain Test Engineer
  • 2. A TALK, IN 6 PARTS 1. What is the problem? 2. Real World Example. 3. Demo of the actual code. 4. Other features tested using same ideas. 5. Advantages/Disadvantages of writing DSLs for testing. 6. QA.
  • 3. WHAT IS THE PROBLEM? Testing real world stateful business logic is hard
  • 4. Microwave Oven State Machine Business logic is Stateful
  • 5. Microwave Oven State Machine Large number transition states
  • 6. Difficult to enumerate all possible cases Microwave Oven State Machine
  • 8. HELPSHIFT • Embeddable support desk for native apps • Main Features: • Frequently Asked Questions which customers can search • File issues/tickets from within the app
  • 9. Helpshift Supercell Clash of Clans Gaana General Billing Domain App Section FAQ 1 FAQ 2FAQs Boom Beach Gaana App Translations English Content Hindi Content …. …. …. …. …. Top Down View of FAQs
  • 10. Example of Gaana FAQ Page Customers can search FAQs Available FAQs FAQ Sections Domain App
  • 11. FAQ Title FAQ Body FAQ is Visible?
  • 12. PROBLEM You cannot share FAQs across apps. Big Customers have multiple apps which have same FAQ translations content example “Privacy Policy”
  • 14. {:published? false :id “faq-id-1” :app_id “app-1” :section_id “section-1” :translations {:en {:published? false :stags [] :body “Privacy Body” :title “Privacy Title”}} :linked_faq_ids [“faq-id-2”] :publish_id “1”} App-1 {:published? false :id “faq-id-2” :app_id “app-2” :section_id “section-2” :translations {:en {:published? false :stags [] :body “Privacy Body" :title “Privacy Title"}} :linked_faq_ids [“faq-id-1”] :publish_id “2”} App-2 faq 1 (Sync faq-1 to App-2)General faq 2 General
  • 15. {:published? false :id “faq-id-1” :app_id “app-1” :section_id “section-1” :translations {:en {:published? false :stags [] :body “Update Body” :title “Privacy Title”}} :linked_faq_ids [“faq-id-2”] :publish_id “1”} {:published? false :id “faq-id-2” :app_id “app-2” :section_id “section-2” :translations {:en {:published? false :stags [] :body “Privacy Body" :title “Privacy Title"}} :linked_faq_ids [“faq-id-1”] :publish_id “2”} faq 1 Sync faq 2 Update FAQ 1’s Body
  • 16. {:published? false :id “faq-id-1” :app_id “app-1” :section_id “section-1” :translations {:en {:published? false :stags [] :body “Update Body” :title “Privacy Title”}} :linked_faq_ids [“faq-id-2”] :publish_id “1”} {:published? false :id “faq-id-2” :app_id “app-2” :section_id “section-2” :translations {:en {:published? false :stags [] :body “Update Body" :title “Privacy Title"}} :linked_faq_ids [“faq-id-1”] :publish_id “2”} faq 1 Sync faq 2 Update FAQ 1’s Body
  • 18. 1. Add 1st App with only English languages. 2. Add 2nd App with only English languages 3. Add 1st FAQ under 1st App 4. Link 1st FAQ to 2nd App to create 2nd FAQ 5. Check -> translations of 2nd FAQ == 1st FAQ 6. Update English title of FAQ-1 7. Check -> translations of 2nd FAQ == 1st FAQ 8. Delete FAQ-1 9. Check if 1st FAQ is deleted in DB 10.Assert 2nd FAQ should remain as it is in database. Simulation Verification
  • 19. PARTS OF EACH ACTION “Add APP-1 with only English language” 1. Type of Action Add an App 2. Names App-1 3. Arguments English Language 4. Expected Result As per Spec/Modal of the system 5. Actual Result Database
  • 20. EXPRESS ACTIONS AS CLOJURE DATA “Add app APP-1 with English language” :add-app :app-1 {:langs-config [:en]}
  • 21. ONE UNIT OF ACTION [:add-app :app-1 {:langs-config [:en]}]
  • 22. SERIES OF ACTIONS [[:add-app :app-1 {:langs-config [:en]] [:add-app :app-2 {:langs-config nil}] [:add-faq :faq-1 {:app-var :app-1 ...}] [:link-faq :faq-2 {:faq-var :faq-1 :app-var :app-2 ...}] [:update-faq nil {:app-var :app-1 :faq var :faq-1 ...}] [:update-faq nil {:app-var :app-2 :faq-var :faq-2 ...}] [:delete-faq nil {:faq-var :faq-1 ...}]]
  • 23. REDUCE ON ACTIONS Reduce {} [:add-app :app-1 {:langs-config nil}]) {:env {:apps {:app-1 {…}}} :result [{result-1…}]} …..} Reduce [:add-app :app-2 {:langs-config nil}]) {:env {:apps {:app-1 {…} :app-2 {…}}} :result [{result-1…} {result-2…}]} …..} {:env {:apps {:app-1 {…}}} :result [{result-1…}]} …..} And so on…
  • 24. RESULT HASH-MAP COMPRISES OF {:env {:apps {:app-1 {:app-id “970"} :app-2 {:app-id “142”}}} :faqs {:faq-1 {:faq-id “112”}}}} :result [{:action-type :add-faq :expected {….} :actual {….}} {…more}] “112” {…state…} …more} Environment (:env) - Contains bindings of vars
  • 25. RESULT HASH-MAP COMPRISES OF {:env {:apps {:app-1 {:app-id “970"} :app-2 {:app-id “142”}}} :faqs {:faq-1 {:faq-id “112”}}}} :result [{:action-type :add-faq :expected {….} :actual {….}} {…more}] “112” {…state…} …more} Result (:result) - Contains Actual And Expected Result
  • 26. RESULT HASH-MAP COMPRISES OF {:env {:apps {:app-1 {:app-id “970"} :app-2 {:app-id “142”}}} :faqs {:faq-1 {:faq-id “112”}}}} :result [{:action-type :add-faq :expected {….} :actual {….}} {…more}] “112” {…state…} …more} Current Generated Expected State
  • 27. Dispatch On Action Type Update The Variables in arguments to its bindings Call args with relevant function Bind the result to the given var in Global Data Store Expected current state Store Actual current database state What happens inside the reducer?
  • 28. Dispatch On Action Type Update The Variables in arguments to its bindings Call args with relevant function Bind the result to the given var in Global Data Store Expected current state Store Actual current database state [:add-app :app-1 {:langs-config nil}]) [:add-app :app-1 {:langs-config nil}]) (add-app {:langs-config nil}) {:env {:apps {:app-1 {:app-id "970"}}}}
  • 29. Dispatch On Action Type Update The Variables in arguments to its bindings Call args with relevant function Bind the result to the given var in Global Data Store Expected current state Store Actual current database state [:add-app :app-2 {:langs-config nil}]) [:add-app :app-2 {:langs-config nil}]) (add-app {:langs-config nil}) {:env {:apps {:app-1 {:app-id “970"} :app-2 {:app-id “142"}}}}
  • 30. Dispatch On Action Type Update The Variables in arguments to its bindings [:add-faq :faq-1 {:app-var :app-1 ….}]) {:env {:apps {:app-1 {:app-id “970"} :app-2 {:app-id “142”}}}
  • 31. Dispatch On Action Type Update The Variables in arguments to its bindings [:add-faq :faq-1 {:app-var :app-1 ….}]) [:add-faq :faq-1 {:app-id “970” …}]) {:env {:apps {:app-1 {:app-id “970"} :app-2 {:app-id “142”}}}
  • 32. Dispatch On Action Type Update The Variables in arguments to its bindings Call args with relevant function Bind the result to the given var in Global Data [:add-faq :faq-1 {:app-var :app-1 ….}]) [:add-faq :faq-1 {:app-id “970” …}]) (add-faq {:app-id “970” ….})
  • 33. Dispatch On Action Type Update The Variables in arguments to its bindings Call args with relevant function Bind the result to the given var in Global Data [:add-faq :faq-1 {:app-var :app-1 ….}]) [:add-faq :faq-1 {:app-id “970” …}]) (add-faq {:app-id “970” ….}) {:env {:apps {:app-1 {:app-id “970"} :app-2 {:app-id “142”}} :faqs {:faq-1 {:faq-id “112”}}}}
  • 34. Dispatch On Action Type Update The Variables in arguments to its bindings Call args with relevant function Bind the result to the given var in Global Data Store Expected current state [:add-faq :faq-1 {:app-var :app-1 ….}]) [:add-faq :faq-1 {:app-id “970” …}]) (add-faq {:app-id “970” ….}) {:env {:apps {:app-1 {:app-id “970"} :app-2 {:app-id “142”}} :faqs {:faq-1 {:faq-id “112”}}}} {:env {:apps {:app-1 {:app-id “970"} :app-2 {:app-id “142”}}} :faqs {:faq-1 {:faq-id “112”}}}} :result [{:action-type :add-faq :expected {….}}
  • 35. Dispatch On Action Type Update The Variables in arguments to its bindings Call args with relevant function Bind the result to the given var in Global Data Store Expected current state Store Actual current database state [:add-faq :faq-1 {:app-var :app-1 ….}]) [:add-faq :faq-1 {:app-id “970” …}]) (add-faq {:app-id “970” ….}) {:env {:apps {:app-1 {:app-id “970"} :app-2 {:app-id “142”}} :faqs {:faq-1 {:faq-id “112”}}}} {:env {:apps {:app-1 {:app-id “970"} :app-2 {:app-id “142”}}} :faqs {:faq-1 {:faq-id “112”}}}} :result [{:action-type :add-faq :expected {….} :actual {….}}
  • 36. VERIFICATION: COMPARE EXPECTED VS ACTUAL FOR EACH STEP
  • 37. COMPARE RESULT FOR FIRST ACTION {"112" {:translations {:en {:published? false, :stags [], :body "Temp body", :title “Title 1"}}, :linked-faq-ids #{}}} Actual Data in DB Expected Data from my Generated result {"112" {:translations {:en {:published? false, :stags [], :body "Temp body", :title “Title 1"}}, :linked-faq-ids #{}}} == PASS
  • 38. :title "Title 1" Actual Data in DB Expected Data from my Generated result :title "Title 2" == FAIL COMPARE RESULT FOR SECOND ACTION
  • 40. APPROACHES TO VERIFY Actions : Hardcoded Expected Output : Hardcoded Actions : Simulated Expected Output : Hardcoded Actions : Simulated Expected Output : Generated Actions : Generated Expected Output : Generated
  • 41. Hardcoded Actions, Hardcoded Expected Output ADVANTAGES DISADVANTAGES Requires no extra knowledge to understand Very cumbersome to enumerate Anyone can add/edit tests Modification is hard False negatives are not possible
  • 42. Simulate list of Actions, Hardcoded Final Expected Output ADVANTAGES DISADVANTAGES Easy to enumerate Requires knowledge of the DSL Very readable Maintenance overhead of DSL Shareable with dev to simulate bugs Does not check intermediate state False negatives are not possible Expected output may have data which is available only at runtime like faq-ids
  • 43. Simulate list of actions, Generate Expected Output ADVANTAGES DISADVANTAGES Easy to enumerate Requires knowledge of the DSL Very readable Maintenance overhead of DSL Shareable with dev to simulate bugs Maintenance overhead of Expected Modal Checks intermediate state False negatives are possible Runtime data is available like faq-ids
  • 44. Generate Actions, Generate Expected Output ADVANTAGES DISADVANTAGES Possible to generate large number of tests Requires knowledge of the DSL Possible to Shrink failed test case using test.check library Maintenance overhead of DSL Shareable with dev to simulate bugs Maintenance overhead of Expected Modal Checks intermediate state False negatives are possible Maintenance overhead of generative code for list of actions.
  • 45. Generate Actions, Generate Expected Output Feature - Issue Audit Trail
  • 46. Issue Audit Trail • Maintains a log of • Who Took an action • What Action they took
  • 47. Who - Types of Users App User Support User Agents Admins Helpshift
  • 48. What - Types of Actions App User • Create Issue • Reply Issue • etc… Admin User • Create Issue • Reply Issue • Resolve Issue • Edit Tags • etc… Agent User • Create Issue • Reply Issue • Resolve Issue • Edit Tags • etc…
  • 51. DEMO - ISSUE AUDIT TRAIL Generate Actions, Generate Expected Output
  • 52. ADVANTAGES OF WRITING DSL Discovering very hard to find bugs, for example we found: Duplicate issue messages being rendered only if the number of messages were "just right". Finding ordering bugs. Increase in developer/tester productivity
  • 53. DISADVANTAGES OF WRITING DSL Cost of maintaining DSLs is high. If your DSL is just data being evaluated at run time, changes in feature code will not throw any compile time errors like function parameters being changed in DSL code. You have to educate your team members to learn your specific DSL for that feature to be able to understand the tests.
  • 54. CONCLUSION DSL can be used as a workflow for writing tests. Separating simulation vs verification of tests. A step towards ability to generate tests instead of writing them.
  • 55. Further Resources • Clojure Made Simple - Rich Hickey • Growing a DSL with Clojure • Jeanine Adkisson - Design and Prototype a Language In Clojure • John Hughes - Testing the Hard Stuff and Staying Sane • Reid Draper - Powerful Testing with test.check • Clojure Tutorials on DSLs with Tim Baldridge (Paid)