- Last Updated: [[2020-12-04]] - [[Visual Studio Load Testing]] [[Load Testing]] - # Problem - Visual Studio's built-in regular expression extraction rule only returns one match (the first, unless otherwise specified). There could be a reason why you would need to extract ALL the matches of a regex, and not just the first. - # Solution - Create a custom extraction plugin. - # Instructions - Create a new class in the project. - Right click on the project > Add > Class. - Write the code for the new plugin, taking care to extend the class `ExtractionRule`. This will ensure that the plugin will be detected in the Extraction Rule choices. See "Extract All Regex Matches". - Add a reference to the new class. - Right click on References > Add reference > Select Microsoft.[VisualStudio]([[VisualStudio]]).[QualityTools]([[QualityTools]]).[CodedUITestFramework]([[CodedUITestFramework]])/[LoadTestFramework]([[LoadTestFramework]])/ [UnitTestFramework]([[UnitTestFramework]])/ [WebTestFramework]([[WebTestFramework]]) (not sure which, if any). - Build the project. - Use the new extraction rule. - Select the request from which you want to extract data. Right click > Add Extraction Rule > Select the extraction rule you created. Fill out the values as required and click OK. - Use the values extracted in the code. - Now that the values have been extracted in an array, it's time to actually do something with those values. Pretend that you've used the code above, and the list you've saved the variables onto is called "cbUsers". Let's say that for each item on the list, you want to send a post parameter with name "ui_hdnauth_cb" and the value of each item. As a little twist, you need a different parameter (a toggle) to be passed before the last parameter/item on the list. Below is the code to do that, to be inserted in the Post Parameter section of the relevant request: - ```javascript /*This section takes the list of strings that were extracted (cbUsers, which contains the users given permissions in this item, and passes them as parameters in the request. The last parameter, however, needs to be separated out because the "on" toggle for parameter auth_cb must first be switched on before the name of the user is passed.*/ int i = 0; int count = ((List<string>)this.Context["cbUsers"]).Count -2; string s; //This for loop iterates through the list (except for the last one) and forms the post parameter for each one. for (i = 0; i < count; i++) { s = ((List<string>)this.Context["cbUsers"])[i]; request11Body.FormPostParameters.Add("ui_hdnauth_cb" + i, s); } //This next part adds the post parameter for the toggle first, and then the parameter with the actual user to delete. i = i + 1; s = ((List<string>)this.Context["cbUsers"])[i]; request11Body.FormPostParameters.Add("auth_cb" + i, "on"); request11Body.FormPostParameters.Add("ui_hdnauth_cb" + i, s);``` - # Extract All Regex Matches - ## Code - ```javascript using System; using System.Collections.Generic; using System.Linq; using System.Text; using Microsoft.VisualStudio.TestTools.WebTesting; using System.Text.RegularExpressions; namespace ExtractAllMatchesRegex { public class ExtractAllMatchesRegex : ExtractionRule { private string regularexpression; public string MyRegularExpression { get { return this.regularexpression; } set { this.regularexpression = value; } } public override void Extract(object sender, ExtractionEventArgs e) { List<String> lst = new List<String>(); Regex rg = new Regex(MyRegularExpression); MatchCollection mcoll = rg.Matches(e.Response.BodyString, 0); for (int i = 0; i < mcoll.Count; i++) { lst.Add(mcoll[i].Groups[1].ToString()); } e.WebTest.Context.Add(this.ContextParameterName, lst); } } }``` - ## Explanation - Extracts all matches of the regular expression and puts it into a Match Collection - Iterates through each item of the match collection and puts THE FIRST GROUP of each item (as indicated by the .Groups[1] part of the code) into a list of strings. - Adds the list as a context parameter to be used in the code.