{"id":1537,"date":"2010-09-27T09:00:57","date_gmt":"2010-09-27T13:00:57","guid":{"rendered":"http:\/\/www.webperformanceinc.com\/load_testing\/blog\/?p=1537"},"modified":"2017-05-24T11:49:43","modified_gmt":"2017-05-24T15:49:43","slug":"custom-extractors-in-web-performance-load-tester","status":"publish","type":"post","link":"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/2010\/09\/custom-extractors-in-web-performance-load-tester\/","title":{"rendered":"Custom Extractors in Web Performance Load Tester"},"content":{"rendered":"<p>This tutorial will outline the steps to configure a custom extractor in Load Tester.\u00a0 Extractors are used to recognize small pieces of data in your application and apply them to future transactions within a test case.<\/p>\n<p><!--more--><\/p>\n<p>I will be assuming that you are already familiar with <a href=\"https:\/\/www.webperformance.com\/load-testing-tools\/demo\/Tutorial.html\">building and running a simple test case<\/a> in Web Performance Load Tester.\u00a0 I will also assume that you already know how to <a href=\"https:\/\/www.webperformance.com\/library\/tutorials\/UserInput\/index.html\">use a dataset to generate unique input<\/a> for a test case.<\/p>\n<p>If you prefer, you can watch this tutorial in the form of a <a href=\"https:\/\/www.webperformance.com\/load-testing-tools\/demo\/ExtractorTutorial.html\">screen cast<\/a>.<\/p>\n<p>We&#8217;ll be using <a href=\"http:\/\/www.sugarcrm.com\/crm\/\">SugarCRM<\/a> as the object of our test.\u00a0 Let&#8217;s begin by establishing the use case.<\/p>\n<p><strong>Our Use Case<br \/>\n<\/strong><\/p>\n<p>1) We log in to Sugar, using a username and password we have already created:<\/p>\n<p><a href=\"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-content\/uploads\/2010\/09\/00100-sugar-login-prompt.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-1544\" title=\"00100-sugar-login-prompt\" src=\"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-content\/uploads\/2010\/09\/00100-sugar-login-prompt-300x225.png\" alt=\"00100-sugar-login-prompt\" width=\"300\" height=\"225\" \/><\/a><\/p>\n<p>2) Then we choose to create a new contact:<\/p>\n<p><a href=\"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-content\/uploads\/2010\/09\/00200-sugar-create-contact.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-1546\" title=\"00200-sugar-create-contact\" src=\"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-content\/uploads\/2010\/09\/00200-sugar-create-contact-300x225.png\" alt=\"00200-sugar-create-contact\" width=\"300\" height=\"225\" \/><\/a><\/p>\n<p>3) And we choose to assign an account to that contact:<\/p>\n<p><a href=\"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-content\/uploads\/2010\/09\/00300-sugar-select-account.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-1550\" title=\"00300-sugar-select-account\" src=\"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-content\/uploads\/2010\/09\/00300-sugar-select-account-300x225.png\" alt=\"00300-sugar-select-account\" width=\"300\" height=\"225\" \/><\/a><\/p>\n<p>4) We type &#8220;Account 7&#8221; into the &#8220;Account Search&#8221; form and click &#8220;Search.&#8221;\u00a0 Account 7 appears in the list and we click it.\u00a0 For the purpose of this tutorial, it&#8217;s important that we actually use the search feature.\u00a0 This assigns &#8220;Account 7&#8221; to our contact:<\/p>\n<p><a href=\"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-content\/uploads\/2010\/09\/00400-sugar-account-dialog.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-1551\" title=\"00400-sugar-account-dialog\" src=\"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-content\/uploads\/2010\/09\/00400-sugar-account-dialog-300x226.png\" alt=\"00400-sugar-account-dialog\" width=\"300\" height=\"226\" \/><\/a><\/p>\n<p>5) And Sugar should now confirm that our new contact is associated with Account 7.<\/p>\n<p><a href=\"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-content\/uploads\/2010\/09\/00600-sugar-added-account-correctly.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-1552\" title=\"00600-sugar-added-account-correctly\" src=\"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-content\/uploads\/2010\/09\/00600-sugar-added-account-correctly-300x226.png\" alt=\"00600-sugar-added-account-correctly\" width=\"300\" height=\"226\" \/><\/a><\/p>\n<p><strong>Building a Test Case<br \/>\n<\/strong><\/p>\n<p>Now we&#8217;re going to create a test case in Web Performance Load Tester that will simulate this user interaction.\u00a0 Recording the test case is a simple matter of performing the above actions inside Load Tester&#8217;s record feature.<\/p>\n<p>Naturally, when we go to replay this test case, it won&#8217;t work, because on the subsequent run SugarCRM wisely complains that we already have a contact named George Jetson.\u00a0 Sugar&#8217;s complaint diverges from our canonical use case, triggering an error.<\/p>\n<p>The solution is to build a dataset of unique names:<\/p>\n<p><a href=\"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-content\/uploads\/2010\/09\/00700-set-up-data-table-of-names-and-accounts1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-1554\" title=\"00700-set-up-data-table-of-names-and-accounts\" src=\"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-content\/uploads\/2010\/09\/00700-set-up-data-table-of-names-and-accounts1-300x146.png\" alt=\"00700-set-up-data-table-of-names-and-accounts\" width=\"300\" height=\"146\" \/><\/a><\/p>\n<p>We went ahead and associated each name with a unique phone number and account &#8212; a good way to exercise our database.\u00a0 But when we go to replay our test case we notice another problem:<\/p>\n<p><a href=\"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-content\/uploads\/2010\/09\/00800-oh-noes-account-1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-1555\" title=\"00800-oh-noes-account-1\" src=\"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-content\/uploads\/2010\/09\/00800-oh-noes-account-1-300x172.png\" alt=\"00800-oh-noes-account-1\" width=\"300\" height=\"172\" \/><\/a><\/p>\n<p>Somehow Aaron Smith was associated with Account 1, when his line item associates him with Account 0.\u00a0 How did this happen?<\/p>\n<p>The first step is to look at our fields view, which is a table of all of the configurable outgoing data in any HTTP transaction.<\/p>\n<p><a href=\"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-content\/uploads\/2010\/09\/00900-fields-view.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-1557\" title=\"00900-fields-view\" src=\"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-content\/uploads\/2010\/09\/00900-fields-view-300x227.png\" alt=\"00900-fields-view\" width=\"300\" height=\"227\" \/><\/a><\/p>\n<p>We see that while Load Tester is correctly configured to pass in an account name from our data set (highlighted in blue), somehow there is an &#8220;account_id&#8221; (highlighted in red) field that has not been configured.<\/p>\n<blockquote><p>We know whether or not a field is configured by the\u00a0<a href=\"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-content\/uploads\/2010\/09\/01000-configured-icon.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1559\" title=\"01000-configured-icon\" src=\"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-content\/uploads\/2010\/09\/01000-configured-icon.png\" alt=\"01000-configured-icon\" width=\"18\" height=\"17\" \/><\/a> icon, which is present only for dynamic fields.\u00a0 If this icon is absent, then the field is a static literal.\u00a0 If this icon is present, then the field is taken from either a dataset or a user state variable.<\/p><\/blockquote>\n<p>It&#8217;s a fair guess that Sugar uses this 128-bit hex string as a unique identifier into account names.\u00a0 Although we pass the account name properly into the search field, Sugar sends back this unique identifier and uses it for the rest of the test case.<\/p>\n<p><strong>Configuring a Custom Extractor<\/strong><\/p>\n<p>We can use an extractor to grab this hex string and store it in a user state variable.\u00a0 But we have to find it first:<\/p>\n<p style=\"text-align: center;\"><a href=\"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-content\/uploads\/2010\/09\/01100-grep-the-hex.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-1561 aligncenter\" title=\"01100-grep-the-hex\" src=\"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-content\/uploads\/2010\/09\/01100-grep-the-hex-300x172.png\" alt=\"01100-grep-the-hex\" width=\"300\" height=\"172\" \/><\/a><\/p>\n<p>It takes a little bit of application-specific knowledge to know which instance of the hex string to extract.\u00a0 If we extract from the first page that contains it, we&#8217;re actually just extracting from a default list of accounts.\u00a0 The second page in our search results here also happens to represent the search results from SugarCRM.<\/p>\n<p>We see that the hex string appears in a &#8220;send_back&#8221; javascript onclick handler.<\/p>\n<p>We&#8217;ll create an extractor on that page.\u00a0 First, select Sugar&#8217;s account search results page in Load Tester.\u00a0 Click the &#8220;Actors&#8221; tab and choose &#8220;Extractors.&#8221;\u00a0 Then click the green plus (&#8216;+&#8217;) sign to add an extractor:<\/p>\n<p style=\"text-align: center;\"><a href=\"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-content\/uploads\/2010\/09\/01150-add-an-extractor.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-1562 aligncenter\" title=\"01150-add-an-extractor\" src=\"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-content\/uploads\/2010\/09\/01150-add-an-extractor-300x235.png\" alt=\"01150-add-an-extractor\" width=\"300\" height=\"235\" \/><\/a><\/p>\n<p>The simplest type of extractor is the &#8220;String Delimited Extractor.&#8221;\u00a0 This extractor needs a prefix and suffix string to capture a value from the HTML content of the search page.\u00a0 We use this extractor to recognize the onclick handler and function call and capture everything between single-quote marks, representing SugarCRM&#8217;s internal hex string.<\/p>\n<p><a href=\"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-content\/uploads\/2010\/09\/01200-making-the-extractor.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-1563\" title=\"01200-making-the-extractor\" src=\"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-content\/uploads\/2010\/09\/01200-making-the-extractor-282x300.png\" alt=\"01200-making-the-extractor\" width=\"282\" height=\"300\" \/><\/a><\/p>\n<p><a href=\"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-content\/uploads\/2010\/09\/01300-extractor-configured-and-named.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-1564\" title=\"01300-extractor-configured-and-named\" src=\"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-content\/uploads\/2010\/09\/01300-extractor-configured-and-named-281x300.png\" alt=\"01300-extractor-configured-and-named\" width=\"281\" height=\"300\" \/><\/a><\/p>\n<p>We then store the result of the extractor into a user state variable called &#8220;account_id.&#8221;\u00a0 We choose this name to match the &#8220;account_id&#8221; field, but we could have named it anything, such as &#8220;foo&#8221; or &#8220;value_of_account_id&#8221;.<\/p>\n<blockquote><p>User state variables that are created by Load Tester&#8217;s Application State Management Wizard get a hash prefix (&#8216;#&#8217;) and, if it occurs more than once, an index number in square brackets.\u00a0 For example, &#8220;#record [2]&#8221;.\u00a0 These annotations are designed to help the human user interpret the Application State Management Wizard&#8217;s behavior.\u00a0 You should name variables according to any convention that you find easy to understand, but note that the Application State Management Wizard may overwrite your work if you begin a variable name with a non-alphanumeric character,<\/p><\/blockquote>\n<p>We also see that the &#8220;Create Extractor&#8221; dialog box displays the extracted value and highlights the extraction in blue.\u00a0 This is a way to verify that we are actually extracting the value we intended.<\/p>\n<p>Click OK, switch to the fields view, and double click the unconfigured &#8220;account_id&#8221; field to bring up the configuration dialog box:<\/p>\n<p><a href=\"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-content\/uploads\/2010\/09\/01400-double-click-the-configure-for-the-field.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-1565\" title=\"01400-double-click-the-configure-for-the-field\" src=\"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-content\/uploads\/2010\/09\/01400-double-click-the-configure-for-the-field-300x265.png\" alt=\"01400-double-click-the-configure-for-the-field\" width=\"300\" height=\"265\" \/><\/a><\/p>\n<p>We then set the &#8220;account_id&#8221; field to read a value dynamically from the &#8220;account_id&#8221; user state variable:<\/p>\n<p><a href=\"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-content\/uploads\/2010\/09\/01500-store-account-id-to-field.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-1566\" title=\"01500-store-account-id-to-field\" src=\"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-content\/uploads\/2010\/09\/01500-store-account-id-to-field-300x255.png\" alt=\"01500-store-account-id-to-field\" width=\"300\" height=\"255\" \/><\/a><\/p>\n<p>We can then test our new configuration by running another replay.\u00a0 We should find that new contacts get associated with the correct account name on each replay:<\/p>\n<p><a href=\"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-content\/uploads\/2010\/09\/01600-account-id-works-yay.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-1568\" title=\"01600-account-id-works-yay\" src=\"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-content\/uploads\/2010\/09\/01600-account-id-works-yay-300x240.png\" alt=\"01600-account-id-works-yay\" width=\"300\" height=\"240\" \/><\/a><\/p>\n<p><strong>Configuring a Detection Rule<br \/>\n<\/strong><\/p>\n<p>We made this extractor work correctly.\u00a0 But do we need to configure a new extractor every time we perform a recording that uses this &#8220;account_id&#8221; field?\u00a0 No &#8212; we can extend the Application State Management Wizard&#8217;s logic to recognize the javascript &#8220;send_back&#8221; method.<\/p>\n<p>Access the Detection Rules editor inside Load Tester&#8217;s preferences dialog box.\u00a0 Browse to Web Performance &gt; Configuration Wizards &gt; Application State &gt; Detection Rules.<\/p>\n<p><a href=\"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-content\/uploads\/2010\/09\/01700-detection-rule-preferences-box.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-1569\" title=\"01700-detection-rule-preferences-box\" src=\"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-content\/uploads\/2010\/09\/01700-detection-rule-preferences-box-300x211.png\" alt=\"01700-detection-rule-preferences-box\" width=\"300\" height=\"211\" \/><\/a><\/p>\n<p>We can parametrize nearly any rule via a system of name-value pairs.\u00a0 For our detector, we&#8217;ll use &#8220;sdd&#8221; (String Delimited Detector) as the detector type, and enter the correct prefix and suffix string.\u00a0 The &#8220;detector.name&#8221; name-value pair is an arbitrary name for our detector, but the &#8220;field.name&#8221; tells the Application State Management Wizard which field it should try to apply the detection rule to.<\/p>\n<p>Use the \u201cTest selected Rule(s)\u201d button to verify that your name-value pairs match the legal expected format of the Application State Management Wizard&#8217;s logic model.<\/p>\n<p>Whenever we create another recording, or simply re-run the Application State Management Wizard, Load Tester will scan for additional onclick handlers that call \u201csend_back\u201d with the &#8216;Accounts&#8217; parameter, and match those handlers with any outgoing fields.<\/p>\n<p>Custom Detection Rules are, however, an advanced feature of Load Tester, so you should review the reference documentation before you create your own.\u00a0 You can find reference documentation under the headings \u201c<a href=\"http:\/\/files.webperformance.com\/manuals\/manual60\/Content\/Application_State_Advanced.html\">Advanced Field Assignments<\/a>\u201d and \u201c<a href=\"http:\/\/files.webperformance.com\/manuals\/manual60\/AnalyzerHelp.html\">Configuring Dynamic Fields<\/a>\u201d in Load Tester&#8217;s build-in help service.<\/p>\n<p><strong>Summary<br \/>\n<\/strong><\/p>\n<p>Extractors capture data from HTTP responses, user state variables retain this data until it is needed, and the fields view allows us to direct this data back to the server.\u00a0 The Application State Management Wizard can automatically configure the overwhelming majority of dynamic fields, but occasionally an important field is left unconfigured, and we can use a custom extractor to configure that field.<\/p>\n<p>We can use custom detection rules to generate custom extractor-field pairs automatically.\u00a0 Detection rules are an advanced feature, so we should only use a custom detection rule when we find that manually configuring an extractor is too repetitive.\u00a0 However, when we actually need them, detection rules can save hours of our time.<\/p>\n<p>&#8212; Lane, Engineer at Web Performance<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This tutorial will outline the steps to configure a custom extractor in Load Tester.\u00a0 Extractors are used to recognize small pieces of data in your application and apply them to future transactions within a test case.<\/p>\n","protected":false},"author":53,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[42],"tags":[53,103,104,30],"class_list":["post-1537","post","type-post","status-publish","format-standard","hentry","category-load-tester-software","tag-extractor","tag-field","tag-sugarcrm","tag-tutorial"],"_links":{"self":[{"href":"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-json\/wp\/v2\/posts\/1537","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-json\/wp\/v2\/users\/53"}],"replies":[{"embeddable":true,"href":"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-json\/wp\/v2\/comments?post=1537"}],"version-history":[{"count":40,"href":"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-json\/wp\/v2\/posts\/1537\/revisions"}],"predecessor-version":[{"id":5793,"href":"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-json\/wp\/v2\/posts\/1537\/revisions\/5793"}],"wp:attachment":[{"href":"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-json\/wp\/v2\/media?parent=1537"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-json\/wp\/v2\/categories?post=1537"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.webperformance.com\/load-testing-tools\/blog\/wp-json\/wp\/v2\/tags?post=1537"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}