{"id":11275,"date":"2024-03-15T07:58:20","date_gmt":"2024-03-15T07:58:20","guid":{"rendered":"https:\/\/www.anamata.nl\/?p=11275"},"modified":"2024-05-29T09:53:42","modified_gmt":"2024-05-29T09:53:42","slug":"exploring-the-mendix-client-api-for-testing","status":"publish","type":"post","link":"https:\/\/www.anamata.eu\/nl\/11275\/","title":{"rendered":"Exploring the Mendix Client API for Testing"},"content":{"rendered":"<div class=\"wp-block-qubely-row qubely-section qubely-block-7c8abd\"><div class=\"qubely-row-overlay\"><\/div><div class=\"qubely-container\"><div class=\"qubely-row\">\n<div class=\"wp-block-qubely-column qubely-column qubely-column-front qubely-block-d873e1\"><div class=\"qubely-column-inner\"><\/div><\/div>\n<\/div><\/div><\/div>\n\n\n\n<div class=\"wp-block-qubely-heading qubely-block-c3facb\"><div class=\"qubely-block-heading\"><div class=\"qubely-heading-container\"><h5 class=\"qubely-heading-selector\"><strong>Introductie<\/strong><\/h5><\/div><\/div><\/div>\n\n\n\n<p>When testing applications, I always want to know more about the technology used in the application stack. I strongly believe that having knowledge of the technology used &#8216;under the hood&#8217; can greatly contribute to more efficient testing.  <\/p>\n\n\n\n<p>When it comes to low-code applications like Mendix, knowing what happens below the surface is at least as interesting for testers. The created applications may look different and have different functionalities, they do share common interfaces and functionalities under that hood. Knowing these interfaces and functionalities as a tester, can help in increasing the test efficiency and team collaboration.<\/p>\n\n\n\n<div class=\"wp-block-qubely-divider qubely-block-d2fc22\"><div class=\"qubely-block-divider\"><div class=\"qubely-block-divider-style-fill\"><\/div><\/div><\/div>\n\n\n\n<div class=\"wp-block-qubely-heading qubely-block-8941af\"><div class=\"qubely-block-heading\"><div class=\"qubely-heading-container\"><h5 class=\"qubely-heading-selector\"><strong>The Client API<\/strong><\/h5><\/div><\/div><\/div>\n\n\n\n<p id=\"ember631\">In October last year, I was part of a team of Anamateers during the Mendix hackathon, aka P0wn Party. Besides the great experience and challenging puzzles, it also triggered my curiosity around the <a href=\"https:\/\/docs.mendix.com\/apidocs-mxsdk\/apidocs\/client-api\/\">Client API<\/a>. This JavaScript API forms the basis for communications between frontend (browser) and backend (microflows, database objects). During the hackathon, I learned how this API could be used to create objects and trigger microflows from the browser console. This got me thinking: if triggering microflows through the console is so easy, how easy is it to incorporate this functionality into a test automation framework and use it for testing purposes?<\/p>\n\n\n\n<p id=\"ember632\">In this article, I will not go into the exact operation of the APIs &#8211; there is a lot of information on this on the Mendix (community) websites -. Instead, I will share my learning process for incorporating Client API calls into an automation framework for the purpose of testing.<\/p>\n\n\n\n<div class=\"wp-block-qubely-heading qubely-block-ca3b52\"><div class=\"qubely-block-heading\"><div class=\"qubely-heading-container\"><h5 class=\"qubely-heading-selector\"><strong>Playwright<\/strong><\/h5><\/div><\/div><\/div>\n\n\n\n<p id=\"ember634\">At first, I had to decide which tool I would use for my framework. I wanted to use a tool that supported the JavaScript language, was open-source and can be used to create extensive test automation frameworks.<\/p>\n\n\n\n<p id=\"ember635\">Based on these requirements, I chose to go for <a href=\"https:\/\/playwright.dev\/\">Playwright<\/a>. I had never used Playwright before and my knowledge of Javascript was also limited. So, this was an opportunity for me to learn a lot of new things!<\/p>\n\n\n\n<div class=\"wp-block-qubely-heading qubely-block-95c1b6\"><div class=\"qubely-block-heading\"><div class=\"qubely-heading-container\"><h5 class=\"qubely-heading-selector\"><strong>The Demo app<\/strong><\/h5><\/div><\/div><\/div>\n\n\n\n<p>To check whether I was able to add the Client API calls to the framework, I first needed to create an app. Wanting to control the ability to create objects and associations and execute microflows, I created a simple app in Mendix with only these functionalities.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" width=\"1024\" height=\"383\" data-src=\"https:\/\/www.anamata.nl\/wp-content\/uploads\/2024\/03\/image-1024x383.png\" alt=\"\" class=\"wp-image-11276 lazyload\" data-srcset=\"https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/image-1024x383.png 1024w, https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/image-300x112.png 300w, https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/image-768x287.png 768w, https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/image-1536x575.png 1536w, https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/image-2048x766.png 2048w, https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/image-500x187.png 500w, https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/image-800x299.png 800w, https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/image-1280x479.png 1280w, https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/image-1920x718.png 1920w\" data-sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 1024px; --smush-placeholder-aspect-ratio: 1024\/383;\" \/><figcaption class=\"wp-element-caption\">My App and the corresponding data model<\/figcaption><\/figure>\n\n\n\n<div class=\"wp-block-qubely-heading qubely-block-f344d1\"><div class=\"qubely-block-heading\"><div class=\"qubely-heading-container\"><h5 class=\"qubely-heading-selector\"><strong>Creating an Object<\/strong><\/h5><\/div><\/div><\/div>\n\n\n\n<p id=\"ember640\">To create an object via the Client API, a couple of things need to be considered.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>The caller needs to have write access to the object<\/li>\n\n\n\n<li>To be able to call the API, you need to have an active -logged in &#8211; browser session.<\/li>\n<\/ol>\n\n\n\n<p id=\"ember642\">So to use this functionality, you must first be logged into the application with an appropriate user. With an active user session, you can trigger the <a href=\"https:\/\/apidocs.rnd.mendix.com\/10\/client\/mx.data.html#.create\">mx.data.create<\/a> functionality to create an object.<\/p>\n\n\n\n<p id=\"ember643\">As a first step, I logged in as an Admin user and ran the following JavaScript snippet manually in my JavaScript console:<\/p>\n\n\n\n<pre class=\"wp-block-code has-border-color has-palette-color-1-border-color has-background has-small-font-size\" style=\"border-width:1px;background-color:#2b32450f\"><code>mx.data.create({\n    entity: \"MyFirstModule.Person\",\n    callback: function(mxObject) {\n        mxObject.set(\"FirstName\", 'test');\n        mx.data.commit({\n            mxobj: mxObject,\n            callback: () => {}\n        })\n    }\n})<\/code><\/pre>\n\n\n\n<p>As a result, a new person with <em>FirstName = test<\/em> was created in the app. The next step was to add the same functionality in the Playwright framework.<\/p>\n\n\n\n<div class=\"wp-block-qubely-heading qubely-block-e7f5e5\"><div class=\"qubely-block-heading\"><div class=\"qubely-heading-container\"><h5 class=\"qubely-heading-selector\"><strong>Integrating object creation in the automation framework<\/strong><\/h5><\/div><\/div><\/div>\n\n\n\n<p id=\"ember646\">When running a Playwright test, the scripts run in its own &#8216;Playwright environment&#8217; and triggers actions on a page of the target application. The Client API runs in the target application. These environments remain distinct; they operate in separate virtual machines, processes, and potentially even on different computers. So, to run a JavaScript command in the context of a target application, we need to trigger an action in Playright which executes JavaScript on the target page.<\/p>\n\n\n\n<p id=\"ember647\">PlayWright has the function <strong><a href=\"https:\/\/playwright.dev\/docs\/evaluating\">page.evaluate<\/a> <\/strong>to do exactly that: run JavaScript in the context of the web page.<\/p>\n\n\n\n<p id=\"ember648\">So, to be able to create a person object via Playwright, I created the following code in Playwright (note that the login steps are not included in the test; these steps are placed in the <a href=\"https:\/\/playwright.dev\/docs\/api\/class-test#test-before-each\"><em>Before hook<\/em><\/a>).<\/p>\n\n\n\n<pre class=\"wp-block-code has-border-color has-palette-color-1-border-color has-background has-small-font-size\" style=\"border-width:1px;background-color:#2b32450f\"><code>await page.evaluate(() => {\n  mx.data.create(\n  {\n    entity: \"MyFirstModule.Person\",\n    callback: function(mxObject)\n    {\n      mxObject.set(\"FirstName\", '1');\n      mx.data.commit(\n      {\n        mxobj: mxObject,\n        callback: () => {}\n      })\n    }\n  })\n})<\/code><\/pre>\n\n\n\n<p id=\"ember649\">This created a person object in the database.<\/p>\n\n\n\n<p id=\"ember650\">The next step for me, was to check if it would be possible to create a generic funcion for the creation of a database object. So, instead of defining the entity and attributes inside the evaluate function, add them as input variables.<\/p>\n\n\n\n<p id=\"ember651\">First, I created a JavaScript Object for person (note that the naming of the keys is identical to the attribute names in the domain model):<\/p>\n\n\n\n<pre class=\"wp-block-code has-border-color has-palette-color-1-border-color has-background\" style=\"border-width:1px;background-color:#2b32450f\"><code>const person = { FirstName: 'test1', LastName: 'testbas1', BirthDate: new Date('2000-01-01'), Gender: 'Male' };<\/code><\/pre>\n\n\n\n<p>In the end, I added theModule name (<strong>moduleName<\/strong>), Entity name (<strong>objectName<\/strong>) and the <strong>content<\/strong> above as input parameter for the evaluate-function. This way, I was able to create a generic function for creating an object, where the input parameter content represents the JavaScript object as above:<\/p>\n\n\n\n<pre class=\"wp-block-code has-border-color has-palette-color-1-border-color has-background has-small-font-size\" style=\"border-width:1px;background-color:#2b32450f\"><code>await page.evaluate(({ moduleName, objectName, content }) => {\n   var entityName = moduleName + \".\" + objectName;\n   mx.data.create(\n     {\n         entity: entityName,\n         callback: function (mxObject) {\n             for (let i = 0; i &lt; Object.keys(content).length; i++) {\n                 const key = (Object.keys(content)&#91;i]);\n                 const value = (Object.values(content)&#91;i]);\n                 mxObject.set(key, value);\n             }\n             const guid = mx.session.sessionData.user.guid;\n             mx.data.commit(\n                 {\n                     mxobj: mxObject, guids: &#91;guid],\n                     callback: () => { }\n                 })\n         }\n     })\n}, ({ moduleName, objectName, content }))<\/code><\/pre>\n\n\n\n<p>Since the keys in the content object are equal to the attribute names, I was able to update all values with a simple loop.<\/p>\n\n\n\n<div class=\"wp-block-qubely-heading qubely-block-8757e5\"><div class=\"qubely-block-heading\"><div class=\"qubely-heading-container\"><h5 class=\"qubely-heading-selector\"><strong>Adding an association<\/strong><\/h5><\/div><\/div><\/div>\n\n\n\n<p id=\"ember655\">My next step was to figure out how to add an association in a generic way. As shown in the domain model above, the goal was to create an association from person to address.<\/p>\n\n\n\n<p id=\"ember656\">As the association points from person to address, the attribute should be stored on the person object. When the association is created via a microflow, we can see the following:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" width=\"1024\" height=\"508\" data-src=\"https:\/\/www.anamata.nl\/wp-content\/uploads\/2024\/03\/image-1-1024x508.png\" alt=\"\" class=\"wp-image-11277 lazyload\" data-srcset=\"https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/image-1-1024x508.png 1024w, https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/image-1-300x149.png 300w, https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/image-1-768x381.png 768w, https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/image-1-500x248.png 500w, https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/image-1-800x397.png 800w, https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/image-1.png 1206w\" data-sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 1024px; --smush-placeholder-aspect-ratio: 1024\/508;\" \/><figcaption class=\"wp-element-caption\">Change Person object: add association to address<\/figcaption><\/figure>\n\n\n\n<p id=\"ember658\">My strategy for the steps in framework was the following:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Create Person object<\/li>\n\n\n\n<li>Create Address object<\/li>\n\n\n\n<li>Change Person object: add association<\/li>\n<\/ol>\n\n\n\n<p id=\"ember660\">This way, I was able to re-use the previously described <em>Create Object<\/em> functionality for the first two steps and create only one new function for the association.<\/p>\n\n\n\n<p id=\"ember661\">This association function consisted out of 3 steps itself:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Find ID of address object<\/li>\n\n\n\n<li>Find Person object<\/li>\n\n\n\n<li>Change person object with addressID<\/li>\n<\/ol>\n\n\n\n<p id=\"ember663\">It took me a while to figure this out, mainly because I was struggling with the asynchronous behavior of the mx.data functionalities. The only way I was able to solve it, was to add the subsequent function in the callback of the previous one. Eventually, I was able to create the following:<\/p>\n\n\n\n<pre class=\"wp-block-code has-border-color has-palette-color-1-border-color has-background has-small-font-size\" style=\"border-width:1px;background-color:#2b32450f\"><code>await page.evaluate((\n{\n  associationKey,\n  xpathExpressionOriginalObject,\n  xpathExpressionAssociatedObject\n}) =>\n{\n  mx.data.get(\n  {\n    xpath: xpathExpressionOriginalObject,\n    callback: function(OriginalObjects)\n    {\n      if (OriginalObjects.length > 0)\n      {\n        var OriginalObject = OriginalObjects&#91;0];\n      }\n      mx.data.get(\n      {\n        xpath: xpathExpressionAssociatedObject,\n        callback: function(associationObjects)\n        {\n          if (associationObjects.length > 0)\n          {\n            OriginalObject.set(associationKey,  \n               associationObjects&#91;0]._guid);\n          }\n          const guid = mx.session.sessionData.user.guid;\n          mx.data.commit(\n          {\n            mxobj: OriginalObject,\n            guids: &#91;guid],\n            callback: () => { }\n          })\n\n        }\n      })\n    }\n  })\n}, (\n{\n  associationKey,\n  xpathExpressionOriginalObject,\n  xpathExpressionAssociatedObject\n}))<\/code><\/pre>\n\n\n\n<p id=\"ember664\">Where the input parameters are defined as follows:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>associationKey: the Name of the association (MyFirstModule.Person_Address)<\/li>\n\n\n\n<li>xpathExpressionOriginalObject: the Xpath needed to retrieve the person object<\/li>\n\n\n\n<li>xpathExpressionAssociatedObject: the Xpath needed to retrieve the address object<\/li>\n<\/ul>\n\n\n\n<p id=\"ember666\">These values are also determined by a function, using the same inputs as for the objects: module name, entity name and content.<\/p>\n\n\n\n<div class=\"wp-block-qubely-heading qubely-block-f4971f\"><div class=\"qubely-block-heading\"><div class=\"qubely-heading-container\"><h5 class=\"qubely-heading-selector\"><strong>Microflows<\/strong><\/h5><\/div><\/div><\/div>\n\n\n\n<p id=\"ember668\">Lastly, I wanted to trigger a microflow. I created two microflows: 1 to delete all addresses and 1 to delete all persons. To keep it simple, both microflows did not have an input and an output. I just wanted to be able to see if I could create a simple function to trigger these. To trigger a microflow, the <a href=\"https:\/\/apidocs.rnd.mendix.com\/10\/client\/mx.data.html#.action\">mx.data.action<\/a> call is provided.<\/p>\n\n\n\n<p id=\"ember669\">I was able to trigger the microflow through the browser console using the following command:<\/p>\n\n\n\n<pre class=\"wp-block-code has-border-color has-palette-color-1-border-color has-background has-small-font-size\" style=\"border-width:1px;background-color:#2b32450f\"><code>mx.data.action({\n\tparams: {\n\t\tactionname: \"MyFirstModule.deleteAllPersons\",\n\t\tapplyto: \"selection\",\n\t\tguids: &#91;mx.session.sessionData.user.guid]\n\t},\n\tcallback: () => {},\n})<\/code><\/pre>\n\n\n\n<p>To include this in the automation framework, I simply created to input parameter for a runMicroflow function, moduleName and microflowName:<\/p>\n\n\n\n<pre class=\"wp-block-code has-border-color has-palette-color-1-border-color has-background has-small-font-size\" style=\"border-width:1px;background-color:#2b32450f\"><code>await this.page.evaluate(({ moduleName, microflowName }) => \n{\n  var guid = mx.session.sessionData.user.guid;\n  mx.data.action({\n    params: {\n      actionname: (moduleName + \".\" + microflowName),\n      applyto: \"selection\",\n      guids: &#91;guid]\n    },\n    callback: () => {},\n  })\n}, { moduleName, microflowName });<\/code><\/pre>\n\n\n\n<div class=\"wp-block-qubely-heading qubely-block-b51ab9\"><div class=\"qubely-block-heading\"><div class=\"qubely-heading-container\"><h5 class=\"qubely-heading-selector\"><strong>Results<\/strong><\/h5><\/div><\/div><\/div>\n\n\n\n<p id=\"ember672\">Now I that was able to create objects via API calls, I was wondering what the time difference between creating an object via the UI and via the API would be. So, I created two functions: object creation via the Client API and object creation via the UI. For both functions, I first log in via the UI and then I subsequently:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Delete all address objects<\/li>\n\n\n\n<li>Delete all person objects<\/li>\n\n\n\n<li>Create Person with Address<\/li>\n<\/ol>\n\n\n\n<p id=\"ember674\">Obviously, for the UI I used the frontend actions and for the API I used the created JavaScript API calls.<\/p>\n\n\n\n<p id=\"ember675\">When I ran both functions &#8211; headless -, the results were as follows:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" width=\"1024\" height=\"183\" data-src=\"https:\/\/www.anamata.nl\/wp-content\/uploads\/2024\/03\/image-2-1024x183.png\" alt=\"\" class=\"wp-image-11278 lazyload\" data-srcset=\"https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/image-2-1024x183.png 1024w, https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/image-2-300x53.png 300w, https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/image-2-768x137.png 768w, https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/image-2-1536x274.png 1536w, https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/image-2-500x89.png 500w, https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/image-2-800x143.png 800w, https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/image-2-1280x228.png 1280w, https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/image-2-1920x342.png 1920w, https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/image-2.png 1974w\" data-sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 1024px; --smush-placeholder-aspect-ratio: 1024\/183;\" \/><figcaption class=\"wp-element-caption\">Execution times for creating 1 person with new address<\/figcaption><\/figure>\n\n\n\n<p>So, a time difference of 0.3 seconds for creating 1 object. Then I wondered what it would be if I created 10:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img decoding=\"async\" width=\"1024\" height=\"181\" data-src=\"https:\/\/www.anamata.nl\/wp-content\/uploads\/2024\/03\/image-3-1024x181.png\" alt=\"\" class=\"wp-image-11279 lazyload\" style=\"--smush-placeholder-width: 1024px; --smush-placeholder-aspect-ratio: 1024\/181;width:728px;height:auto\" data-srcset=\"https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/image-3-1024x181.png 1024w, https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/image-3-300x53.png 300w, https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/image-3-768x135.png 768w, https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/image-3-1536x271.png 1536w, https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/image-3-500x88.png 500w, https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/image-3-800x141.png 800w, https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/image-3-1280x226.png 1280w, https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/image-3-1920x338.png 1920w, https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/image-3.png 1974w\" data-sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" \/><figcaption class=\"wp-element-caption\">Execution times for creating 10 persons with new addresses<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" width=\"1024\" height=\"179\" data-src=\"https:\/\/www.anamata.nl\/wp-content\/uploads\/2024\/03\/image-4-1024x179.png\" alt=\"\" class=\"wp-image-11280 lazyload\" data-srcset=\"https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/image-4-1024x179.png 1024w, https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/image-4-300x53.png 300w, https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/image-4-768x134.png 768w, https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/image-4-1536x269.png 1536w, https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/image-4-500x88.png 500w, https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/image-4-800x140.png 800w, https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/image-4-1280x224.png 1280w, https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/image-4-1920x336.png 1920w, https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/image-4.png 1976w\" data-sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" style=\"--smush-placeholder-width: 1024px; --smush-placeholder-aspect-ratio: 1024\/179;\" \/><figcaption class=\"wp-element-caption\">Execution times for creating 100 persons with new addresses<\/figcaption><\/figure>\n\n\n\n<p>So yes, of course, the more objects you create, the greater the difference in processing time will become.<\/p>\n\n\n\n<div class=\"wp-block-qubely-heading qubely-block-ae7334\"><div class=\"qubely-block-heading\"><div class=\"qubely-heading-container\"><h5 class=\"qubely-heading-selector\"><strong>Conclusion &amp; next steps<\/strong><\/h5><\/div><\/div><\/div>\n\n\n\n<p id=\"ember683\">First of all, I learned some basics of JavaScript programming and explored some possibilities of Playwright. Still scratching the surface, but definitely worth exploring further.<\/p>\n\n\n\n<p id=\"ember684\">When it comes to using the Mendix Client API for testing purposes, I believe that integrating these functionalities in an automation framework will contribute to a faster, more robust and more feature-focused tests. By using these API calls, it will be easier to create automated tests focused on one functionality, which will also run faster. You can set up your objects, retrieve and verify objects and even trigger microflows to check logic or create preconditions. Additionally, it can help testers with their exploratory tests. Who wants to create 100 persons with 100 different addresses manually? Why not just create it via some api calls?<\/p>\n\n\n\n<p id=\"ember685\">There is still a lot to explore and I do have more ideas I would like to put to practice, like:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Execute microflows with input parameters<\/li>\n\n\n\n<li>Assert microflow outputs<\/li>\n\n\n\n<li>Assert Objects<\/li>\n\n\n\n<li>Add error handling<\/li>\n\n\n\n<li>Execute nanoflows<\/li>\n<\/ul>\n\n\n\n<p id=\"ember687\">And of course, put it into practice in a real Mendix project!<\/p>\n\n\n\n<p id=\"ember688\">If you would like to know more about my learnings, the functionality or have any other ideas that might be worth exploring, don&#8217;t hesitate to reach out to me or my colleagues.<\/p>","protected":false},"excerpt":{"rendered":"<p>In this article, I will share my learning process for incorporating Client API calls into an automation framework for the purpose of testing.<\/p>","protected":false},"author":4,"featured_media":11281,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"qubely_global_settings":"","qubely_interactions":"","tpgb_global_settings":"","_gspb_post_css":"","content-type":"","_vp_format_video_url":"","_vp_image_focal_point":[],"footnotes":""},"categories":[12,24,58],"tags":[71,70,74],"class_list":["post-11275","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-anamata","category-mendix","category-qa","tag-m-shaped","tag-mendix","tag-qa"],"blocksy_meta":{"styles_descriptor":{"styles":{"desktop":"","tablet":"","mobile":""},"google_fonts":[],"version":6}},"qubely_featured_image_url":{"full":["https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/pc.png?wsr",3840,2160,false],"landscape":["https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/pc-1200x750.png?wsr",1200,750,true],"portraits":["https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/pc-540x320.png?wsr",540,320,true],"thumbnail":["https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/pc-150x150.png?wsr",150,150,true],"medium":["https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/pc-300x169.png?wsr",300,169,true],"medium_large":["https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/pc-768x432.png?wsr",768,432,true],"large":["https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/pc-1024x576.png?wsr",1024,576,true],"timeline-express":["https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/pc-350x120.png?wsr",350,120,true],"timeline-express-thumbnail":["https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/pc-200x120.png?wsr",200,120,true],"1536x1536":["https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/pc-1536x864.png?wsr",1536,864,true],"2048x2048":["https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/pc-2048x1152.png?wsr",2048,1152,true],"trp-custom-language-flag":["https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/pc.png?wsr",18,10,false],"qubely_landscape":["https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/pc-1200x750.png?wsr",1200,750,true],"qubely_portrait":["https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/pc-540x320.png?wsr",540,320,true],"qubely_thumbnail":["https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/pc-140x100.png?wsr",140,100,true],"vp_sm":["https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/pc-500x281.png?wsr",500,281,true],"vp_md":["https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/pc-800x450.png?wsr",800,450,true],"vp_lg":["https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/pc-1280x720.png?wsr",1280,720,true],"vp_xl":["https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/pc-1920x1080.png?wsr",1920,1080,true],"vp_sm_popup":["https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/pc-500x281.png?wsr",500,281,true],"vp_md_popup":["https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/pc-800x450.png?wsr",800,450,true],"vp_xl_popup":["https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/pc-1920x1080.png?wsr",1920,1080,true],"tp-image-grid":["https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/pc.png?wsr",700,394,false],"profile_24":["https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/pc-24x24.png?wsr",24,24,true],"profile_48":["https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/pc-48x48.png?wsr",48,48,true],"profile_96":["https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/pc-96x96.png?wsr",96,96,true],"profile_150":["https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/pc-150x150.png?wsr",150,150,true],"profile_300":["https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/pc-300x300.png?wsr",300,300,true]},"qubely_author":{"display_name":"Bas van Opstal","author_link":"https:\/\/www.anamata.eu\/nl\/author\/basvanopstal\/"},"qubely_comment":0,"qubely_category":"<a href=\"https:\/\/www.anamata.eu\/nl\/category\/anamata\/\" rel=\"category tag\">Anamata<\/a> <a href=\"https:\/\/www.anamata.eu\/nl\/category\/mendix\/\" rel=\"category tag\">Mendix<\/a> <a href=\"https:\/\/www.anamata.eu\/nl\/category\/qa\/\" rel=\"category tag\">QA<\/a>","qubely_excerpt":"In this article, I will share my learning process for incorporating Client API calls into an automation framework for the purpose of testing.","yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.3 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Exploring the Mendix Client API for Testing<\/title>\n<meta name=\"description\" content=\"In this article, I will share my learning process for incorporating Client API calls into an automation framework for the purpose of testing.\" \/>\n<meta name=\"robots\" content=\"noindex, follow\" \/>\n<meta property=\"og:locale\" content=\"nl_NL\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Exploring the Mendix Client API for Testing\" \/>\n<meta property=\"og:description\" content=\"In this article, I will share my learning process for incorporating Client API calls into an automation framework for the purpose of testing.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.anamata.eu\/nl\/11275\/\" \/>\n<meta property=\"og:site_name\" content=\"Anamata\" \/>\n<meta property=\"article:published_time\" content=\"2024-03-15T07:58:20+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-05-29T09:53:42+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/pc-1024x576.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1024\" \/>\n\t<meta property=\"og:image:height\" content=\"576\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Bas van Opstal\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Geschreven door\" \/>\n\t<meta name=\"twitter:data1\" content=\"Bas van Opstal\" \/>\n\t<meta name=\"twitter:label2\" content=\"Geschatte leestijd\" \/>\n\t<meta name=\"twitter:data2\" content=\"5 minuten\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.anamata.eu\\\/nl\\\/11275\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.anamata.eu\\\/nl\\\/11275\\\/\"},\"author\":{\"name\":\"Bas van Opstal\",\"@id\":\"https:\\\/\\\/www.anamata.eu\\\/#\\\/schema\\\/person\\\/87c753025a3e5e4c203d6274444e5da9\"},\"headline\":\"Exploring the Mendix Client API for Testing\",\"datePublished\":\"2024-03-15T07:58:20+00:00\",\"dateModified\":\"2024-05-29T09:53:42+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.anamata.eu\\\/nl\\\/11275\\\/\"},\"wordCount\":1541,\"publisher\":{\"@id\":\"https:\\\/\\\/www.anamata.eu\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.anamata.eu\\\/nl\\\/11275\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.anamata.eu\\\/wp-content\\\/uploads\\\/2024\\\/03\\\/pc.png?wsr\",\"keywords\":[\"M-shaped\",\"Mendix\",\"QA\"],\"articleSection\":[\"Anamata\",\"Mendix\",\"QA\"],\"inLanguage\":\"nl-NL\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.anamata.eu\\\/nl\\\/11275\\\/\",\"url\":\"https:\\\/\\\/www.anamata.eu\\\/nl\\\/11275\\\/\",\"name\":\"Exploring the Mendix Client API for Testing\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.anamata.eu\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.anamata.eu\\\/nl\\\/11275\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.anamata.eu\\\/nl\\\/11275\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.anamata.eu\\\/wp-content\\\/uploads\\\/2024\\\/03\\\/pc.png?wsr\",\"datePublished\":\"2024-03-15T07:58:20+00:00\",\"dateModified\":\"2024-05-29T09:53:42+00:00\",\"description\":\"In this article, I will share my learning process for incorporating Client API calls into an automation framework for the purpose of testing.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.anamata.eu\\\/nl\\\/11275\\\/#breadcrumb\"},\"inLanguage\":\"nl-NL\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.anamata.eu\\\/nl\\\/11275\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"nl-NL\",\"@id\":\"https:\\\/\\\/www.anamata.eu\\\/nl\\\/11275\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.anamata.eu\\\/wp-content\\\/uploads\\\/2024\\\/03\\\/pc.png?wsr\",\"contentUrl\":\"https:\\\/\\\/www.anamata.eu\\\/wp-content\\\/uploads\\\/2024\\\/03\\\/pc.png?wsr\",\"width\":3840,\"height\":2160},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.anamata.eu\\\/nl\\\/11275\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Developing the Future. Today.\",\"item\":\"https:\\\/\\\/www.anamata.eu\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Exploring the Mendix Client API for Testing\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.anamata.eu\\\/#website\",\"url\":\"https:\\\/\\\/www.anamata.eu\\\/\",\"name\":\"Anamata\",\"description\":\"Quality from the heart\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.anamata.eu\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.anamata.eu\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"nl-NL\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.anamata.eu\\\/#organization\",\"name\":\"Anamata\",\"url\":\"https:\\\/\\\/www.anamata.eu\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"nl-NL\",\"@id\":\"https:\\\/\\\/www.anamata.eu\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.anamata.nl\\\/wp-content\\\/uploads\\\/2024\\\/03\\\/Emmetjepadding.png\",\"contentUrl\":\"https:\\\/\\\/www.anamata.nl\\\/wp-content\\\/uploads\\\/2024\\\/03\\\/Emmetjepadding.png\",\"width\":1067,\"height\":1067,\"caption\":\"Anamata\"},\"image\":{\"@id\":\"https:\\\/\\\/www.anamata.eu\\\/#\\\/schema\\\/logo\\\/image\\\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.anamata.eu\\\/#\\\/schema\\\/person\\\/87c753025a3e5e4c203d6274444e5da9\",\"name\":\"Bas van Opstal\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"nl-NL\",\"@id\":\"https:\\\/\\\/www.anamata.eu\\\/wp-content\\\/uploads\\\/2021\\\/04\\\/IMG_3188-1-150x150.jpeg?wsr\",\"url\":\"https:\\\/\\\/www.anamata.eu\\\/wp-content\\\/uploads\\\/2021\\\/04\\\/IMG_3188-1-150x150.jpeg?wsr\",\"contentUrl\":\"https:\\\/\\\/www.anamata.eu\\\/wp-content\\\/uploads\\\/2021\\\/04\\\/IMG_3188-1-150x150.jpeg?wsr\",\"caption\":\"Bas van Opstal\"},\"description\":\"Bas is one of the Founders of Anamata. He shares his thoughts and experiences in the Anamata stories. Bas has a strong technical background in low-code. Bas is Pega CSSA certified, is co-author of the Pega DevOps &amp; Testing training and holds a Mendix advanced certification. Bas has experience as a Developer, BA, Tester, Scrum master and Team lead.\",\"sameAs\":[\"www.linkedin.com\\\/in\\\/bas-van-opstal\"],\"url\":\"https:\\\/\\\/www.anamata.eu\\\/nl\\\/author\\\/basvanopstal\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Exploring the Mendix Client API for Testing","description":"In this article, I will share my learning process for incorporating Client API calls into an automation framework for the purpose of testing.","robots":{"index":"noindex","follow":"follow"},"og_locale":"nl_NL","og_type":"article","og_title":"Exploring the Mendix Client API for Testing","og_description":"In this article, I will share my learning process for incorporating Client API calls into an automation framework for the purpose of testing.","og_url":"https:\/\/www.anamata.eu\/nl\/11275\/","og_site_name":"Anamata","article_published_time":"2024-03-15T07:58:20+00:00","article_modified_time":"2024-05-29T09:53:42+00:00","og_image":[{"width":1024,"height":576,"url":"https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/pc-1024x576.png","type":"image\/png"}],"author":"Bas van Opstal","twitter_card":"summary_large_image","twitter_misc":{"Geschreven door":"Bas van Opstal","Geschatte leestijd":"5 minuten"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.anamata.eu\/nl\/11275\/#article","isPartOf":{"@id":"https:\/\/www.anamata.eu\/nl\/11275\/"},"author":{"name":"Bas van Opstal","@id":"https:\/\/www.anamata.eu\/#\/schema\/person\/87c753025a3e5e4c203d6274444e5da9"},"headline":"Exploring the Mendix Client API for Testing","datePublished":"2024-03-15T07:58:20+00:00","dateModified":"2024-05-29T09:53:42+00:00","mainEntityOfPage":{"@id":"https:\/\/www.anamata.eu\/nl\/11275\/"},"wordCount":1541,"publisher":{"@id":"https:\/\/www.anamata.eu\/#organization"},"image":{"@id":"https:\/\/www.anamata.eu\/nl\/11275\/#primaryimage"},"thumbnailUrl":"https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/pc.png?wsr","keywords":["M-shaped","Mendix","QA"],"articleSection":["Anamata","Mendix","QA"],"inLanguage":"nl-NL"},{"@type":"WebPage","@id":"https:\/\/www.anamata.eu\/nl\/11275\/","url":"https:\/\/www.anamata.eu\/nl\/11275\/","name":"Exploring the Mendix Client API for Testing","isPartOf":{"@id":"https:\/\/www.anamata.eu\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.anamata.eu\/nl\/11275\/#primaryimage"},"image":{"@id":"https:\/\/www.anamata.eu\/nl\/11275\/#primaryimage"},"thumbnailUrl":"https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/pc.png?wsr","datePublished":"2024-03-15T07:58:20+00:00","dateModified":"2024-05-29T09:53:42+00:00","description":"In this article, I will share my learning process for incorporating Client API calls into an automation framework for the purpose of testing.","breadcrumb":{"@id":"https:\/\/www.anamata.eu\/nl\/11275\/#breadcrumb"},"inLanguage":"nl-NL","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.anamata.eu\/nl\/11275\/"]}]},{"@type":"ImageObject","inLanguage":"nl-NL","@id":"https:\/\/www.anamata.eu\/nl\/11275\/#primaryimage","url":"https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/pc.png?wsr","contentUrl":"https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/pc.png?wsr","width":3840,"height":2160},{"@type":"BreadcrumbList","@id":"https:\/\/www.anamata.eu\/nl\/11275\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Developing the Future. Today.","item":"https:\/\/www.anamata.eu\/"},{"@type":"ListItem","position":2,"name":"Exploring the Mendix Client API for Testing"}]},{"@type":"WebSite","@id":"https:\/\/www.anamata.eu\/#website","url":"https:\/\/www.anamata.eu\/","name":"Anamata","description":"Quality from the heart","publisher":{"@id":"https:\/\/www.anamata.eu\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.anamata.eu\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"nl-NL"},{"@type":"Organization","@id":"https:\/\/www.anamata.eu\/#organization","name":"Anamata","url":"https:\/\/www.anamata.eu\/","logo":{"@type":"ImageObject","inLanguage":"nl-NL","@id":"https:\/\/www.anamata.eu\/#\/schema\/logo\/image\/","url":"https:\/\/www.anamata.nl\/wp-content\/uploads\/2024\/03\/Emmetjepadding.png","contentUrl":"https:\/\/www.anamata.nl\/wp-content\/uploads\/2024\/03\/Emmetjepadding.png","width":1067,"height":1067,"caption":"Anamata"},"image":{"@id":"https:\/\/www.anamata.eu\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/www.anamata.eu\/#\/schema\/person\/87c753025a3e5e4c203d6274444e5da9","name":"Bas van Opstal","image":{"@type":"ImageObject","inLanguage":"nl-NL","@id":"https:\/\/www.anamata.eu\/wp-content\/uploads\/2021\/04\/IMG_3188-1-150x150.jpeg?wsr","url":"https:\/\/www.anamata.eu\/wp-content\/uploads\/2021\/04\/IMG_3188-1-150x150.jpeg?wsr","contentUrl":"https:\/\/www.anamata.eu\/wp-content\/uploads\/2021\/04\/IMG_3188-1-150x150.jpeg?wsr","caption":"Bas van Opstal"},"description":"Bas is one of the Founders of Anamata. He shares his thoughts and experiences in the Anamata stories. Bas has a strong technical background in low-code. Bas is Pega CSSA certified, is co-author of the Pega DevOps &amp; Testing training and holds a Mendix advanced certification. Bas has experience as a Developer, BA, Tester, Scrum master and Team lead.","sameAs":["www.linkedin.com\/in\/bas-van-opstal"],"url":"https:\/\/www.anamata.eu\/nl\/author\/basvanopstal\/"}]}},"tpgb_featured_images":{"full":["https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/pc.png?wsr",3840,2160,false],"tp-image-grid":["https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/pc.png?wsr",700,394,false],"thumbnail":["https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/pc-150x150.png?wsr",150,150,true],"medium":["https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/pc-300x169.png?wsr",300,169,true],"medium_large":["https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/pc-768x432.png?wsr",768,432,true],"large":["https:\/\/www.anamata.eu\/wp-content\/uploads\/2024\/03\/pc-1024x576.png?wsr",1024,576,true],"default":"https:\/\/www.anamata.eu\/wp-content\/plugins\/the-plus-addons-for-block-editor\/assets\/images\/tpgb-placeholder.jpg"},"tpgb_post_meta_info":{"get_date":"maart 15, 2024","get_modified_date":"mei 29, 2024","category_list":{"category":[{"term_id":12,"name":"Anamata","slug":"anamata","term_group":0,"term_taxonomy_id":12,"taxonomy":"category","description":"","parent":0,"count":14,"filter":"raw"},{"term_id":24,"name":"Mendix","slug":"mendix","term_group":0,"term_taxonomy_id":24,"taxonomy":"category","description":"","parent":0,"count":8,"filter":"raw"},{"term_id":58,"name":"QA","slug":"qa","term_group":0,"term_taxonomy_id":58,"taxonomy":"category","description":"","parent":0,"count":6,"filter":"raw"}],"post_tag":[{"term_id":71,"name":"M-shaped","slug":"m-shaped","term_group":0,"term_taxonomy_id":71,"taxonomy":"post_tag","description":"","parent":0,"count":4,"filter":"raw"},{"term_id":70,"name":"Mendix","slug":"mendix","term_group":0,"term_taxonomy_id":70,"taxonomy":"post_tag","description":"","parent":0,"count":8,"filter":"raw"},{"term_id":74,"name":"QA","slug":"qa","term_group":0,"term_taxonomy_id":74,"taxonomy":"post_tag","description":"","parent":0,"count":5,"filter":"raw"}],"post_format":false},"author_name":"Bas van Opstal","author_url":"https:\/\/www.anamata.eu\/nl\/author\/basvanopstal\/","author_email":"basvanopstal@anamata.nl","author_website":"","author_description":"Bas is one of the Founders of Anamata. He shares his thoughts and experiences in the Anamata stories. Bas has a strong technical background in low-code. Bas is Pega CSSA certified, is co-author of the Pega DevOps &amp; Testing training and holds a Mendix advanced certification. Bas has experience as a Developer, BA, Tester, Scrum master and Team lead.","author_facebook":"","author_twitter":"","author_instagram":"","author_role":["author"],"author_firstname":"Bas","author_lastname":"van Opstal","user_login":"basvanopstal","author_avatar":"<img width=\"189\" height=\"200\" src=\"https:\/\/www.anamata.eu\/wp-content\/uploads\/2021\/04\/IMG_3188-1.jpeg?wsr\" class=\"avatar avatar-200 photo\" alt=\"\" decoding=\"async\" loading=\"lazy\" srcset=\"https:\/\/www.anamata.eu\/wp-content\/uploads\/2021\/04\/IMG_3188-1.jpeg 1816w, https:\/\/www.anamata.eu\/wp-content\/uploads\/2021\/04\/IMG_3188-1-284x300.jpeg 284w, https:\/\/www.anamata.eu\/wp-content\/uploads\/2021\/04\/IMG_3188-1-970x1024.jpeg 970w, https:\/\/www.anamata.eu\/wp-content\/uploads\/2021\/04\/IMG_3188-1-768x811.jpeg 768w, https:\/\/www.anamata.eu\/wp-content\/uploads\/2021\/04\/IMG_3188-1-1454x1536.jpeg 1454w\" sizes=\"auto, (max-width: 189px) 100vw, 189px\" \/>","author_avatar_url":"https:\/\/www.anamata.eu\/wp-content\/uploads\/2021\/04\/IMG_3188-1-150x150.jpeg?wsr","comment_count":0,"post_likes":0,"post_views":0},"tpgb_post_category":{"category":"<a href=\"https:\/\/www.anamata.eu\/nl\/category\/anamata\/\" alt=\"Anamata\"  class=\"category-anamata\">Anamata<\/a> <a href=\"https:\/\/www.anamata.eu\/nl\/category\/mendix\/\" alt=\"Mendix\"  class=\"category-mendix\">Mendix<\/a> <a href=\"https:\/\/www.anamata.eu\/nl\/category\/qa\/\" alt=\"QA\"  class=\"category-qa\">QA<\/a> ","post_tag":"<a href=\"https:\/\/www.anamata.eu\/nl\/tag\/m-shaped\/\" alt=\"M-shaped\"  class=\"post_tag-m-shaped\">M-shaped<\/a> <a href=\"https:\/\/www.anamata.eu\/nl\/tag\/mendix\/\" alt=\"Mendix\"  class=\"post_tag-mendix\">Mendix<\/a> <a href=\"https:\/\/www.anamata.eu\/nl\/tag\/qa\/\" alt=\"QA\"  class=\"post_tag-qa\">QA<\/a> "},"_links":{"self":[{"href":"https:\/\/www.anamata.eu\/nl\/wp-json\/wp\/v2\/posts\/11275","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.anamata.eu\/nl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.anamata.eu\/nl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.anamata.eu\/nl\/wp-json\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/www.anamata.eu\/nl\/wp-json\/wp\/v2\/comments?post=11275"}],"version-history":[{"count":13,"href":"https:\/\/www.anamata.eu\/nl\/wp-json\/wp\/v2\/posts\/11275\/revisions"}],"predecessor-version":[{"id":11298,"href":"https:\/\/www.anamata.eu\/nl\/wp-json\/wp\/v2\/posts\/11275\/revisions\/11298"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.anamata.eu\/nl\/wp-json\/wp\/v2\/media\/11281"}],"wp:attachment":[{"href":"https:\/\/www.anamata.eu\/nl\/wp-json\/wp\/v2\/media?parent=11275"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.anamata.eu\/nl\/wp-json\/wp\/v2\/categories?post=11275"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.anamata.eu\/nl\/wp-json\/wp\/v2\/tags?post=11275"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}