SharePoint load testing made easier with Visual Studio 2012 Update
A lot of people ask me what was my favorite part of living in Australia for 7 years. Most assume it was something like the warm water, the amazing red wines, the beautiful beaches or the unspoiled landscape and yes while i miss all those things it is the people and their “mates” ideology of adopting practically anybody as their extended family at the drop of a hat (often over a pint) is what i miss the most…And Arian really exemplifies that behavior. He realized we needed a walk through article on the new SharePoint load testing features and with out any prompting offered to write the amazing piece below….Thanks Arian!!!!!!!!!
(By the way this applies to both Update1 and CTP for Update 2)
By: Arian Nevjestic, SharePoint PFE, Microsoft Australia
Planning to stay within SharePoint’s software boundaries / following Microsoft’s SharePoint coding best practices is a foundation to building SharePoint solutions; but does NOT give you any guarantees on how well the SharePoint solution will perform once it is released to the end users. Each client will have different requirements for their solutions; different user loads and the fact is no matter how much out of the box or customised your solutions are YOU NEED to run through custom tailored Load Testing activities to isolate any bottlenecks specific to your solution. SharePoint is a complex beast whose performance throughput relies on many layers ranging from healthy server / DISK IO / network infrastructure all the way through to healthy performing Web services (throttling / quotas) / ASP.NET engine (min/max threads / etc) / healthy SQL (index rebuild / reorgs) / caching strategies on hardware and software level / to custom code optimisation to reduce roundtrips.
Visual Studio has been providing us with the ability to build web test cases since 2005 days. The WebTests were intuitive to create as it allowed you to use a WebTest recorded plugin within the browser to quickly record your web test case. Although Visual Studio managed to detect dynamic parameters by replaying the transaction twice and checking which values have changed from server end – when it came to designing reusable test cases that interact with SharePoint Visual Studio wasn’t smart enough to detect SharePoint specific parameters such as list GUIDs / list item IDs / views / etc. Picture a typical SharePoint scenario where you are interacting with multiple files in a list. If you recorded a web test case to interact with a single item – and then wanted to replay the test case multiple times without knowing each list item ID you would need to spend a lot of time figuring out what HTML you need to extract to detect the next available list item ID. Although it was hard I am not here to say that it wasn’t possible to achieve this back in the VS2005/2008/2010 days but it did require a lot of trial and error guessing which parameters need to be dynamic such that SharePoint can process the request without failures.
With the introduction of Visual Studio 2012 Update 1 there have been a number of improvements built into the Testing tooling such that it can natively better support SharePoint load testing / unit testing and debugging through the use of IntelliTrace. In this post I will solely focus on the Load Testing component and specifically on the new SharePoint specific extraction rules that are available to use in VS2012 Update 1.
If we think about the common out of the box uses of SharePoint they generally fall into the following scenarios:
- Document Management scenarios (upload / check-in / check-out / performing workflow activities)
- Web Content Management activities (creating pages / adding web parts to pages / authoring page content on the page controls)
- Browsing scenarios (Could be browsing pages that have content rollup webparts / searching for content / etc)
The creation of web test cases in VS2012 Update 1 from above scenario can be greatly simplified by using the following pre built SharePoint 2010 extraction rules:
Extraction Rule Type
SharePoint – Extract Form Field
Extract the value of a specified SharePoint text box or hidden form field in the response and place it into the test context.
SharePoint – Extract GUID
Extract SharePoint GUID from the response and place it into the test context.
SharePoint – Extract GUID Form Field
Extract the value of the form field name, which contains a GUID, in the following format: BeginningOfName_mg_EmbeddedGUID_RemainderOfName. For example:
SharePoint – Extract Selected Option
Extract a value from a SharePoint ComboBox DropDown list in the response.
SharePoint – Extract Text On Key
Extract the value of a specified string, based on a key that is provided in the response, and place it into the test context.
SharePoint – Extract WebParts ListView Values
Extract all values from the script portion of webpart list view in the response using the list title as the search criteria.
SharePoint – Find Calendar Date
Extracts a date value in the response on a SharePoint calendar.
SharePoint – Find Calendar Item
Extracts the ID value of a specified event in the response on a SharePoint calendar list.
SharePoint – Find Document Item
Extracts the ID value of a specified document in the response from a SharePoint document list.
SharePoint – Find Hrefs
Extracts href references in the response that matches the search criteria.
SharePoint – Find List Item
Extracts the ID value of a specified list Item in the response.
Although the rules do appear to be quiet basic – they do cover a great deal of scenarios for the out of the box SharePoint functionality. These rules should be enough to get you quickly started with SharePoint load testing. Given the nature of SharePoint customisations – we cannot build an extraction rule for each customisation scenario that may come up in the real world – however making use of the above extraction rules will help with load testing even customised solutions. In the heavily SharePoint customised scenarios it would help knowing how and what parameters are passed from the customisations back to the server – such that you can hunt these guys down easily and parameterise again by using Visual Studio extraction rules. If you’re interested in these types of scenarios please view the second WebTest extraction rule example in this blog post as it walks you through a process on how to identify and parametric params which are not covered by the SharePoint extraction rules described in the table above. The process is the key take away for that example as it will help you with your custom solution web tests.
In scenarios where you really do not have an appropriate extraction rule provided by the VS2012 Update 1 web test package you can still write your own custom extraction rule in form of classes in the Microsoft.VisualStudio.TestTools.WebTesting.Rules namespace. For more information on custom extraction rules please view How to: Create a Custom Extraction Rule for a Web Performance Test.
Let see some example on how to make use of the extraction rules.
We will create a simple load test which will upload files to SharePoint.
1. Prior to Update 1, it was certainly possible to record web tests against SharePoint, but it required you to significantly hand edit the recording to do things such as remove extraneous requests and parameterize the site name / list guids / item ids etc. Update 1 performs more of these tedious tasks automatically, and this is configurable. View the available options by selecting Tools | Options | Web Performance Test Tools | Web Test | SharePoint in the main menu of Visual Studio.
Notice above that we are also handling SharePoint error pages which are HTTP 200 responses as errors. Should you use custom error pages in your solutions please update the Error pattern above to handle your user friendly error text.
Below is my Solution structure based on the new VS2012 Update 1 Web Test Project. Upload.webtest is simply a web test recording of a simple use case of browsing to a SharePoint site and then uploading a document. You will notice that I have also added some word documents that will act as my upload elements when I run the loadtest.
Here is a view of the Upload.web test transactions:
Note that the site name was automatically parameterized for us in all of the recorded requests. This makes it easy to data drive the site name if desired.
If I Expand the second request in the list and note that a SharePoint specific extraction rule was automatically added in to grab the list ID and store it as a context parameter.
The list ID context parameter is then used in subsequent requests, for example in the request to Upload.aspx.
2. The actual file that is uploaded during the test run is parameterized as well. Expand the second web request to Upload.aspx (there are two) and scroll to the bottom of the Form Post Parameters and select last option, which is a File Upload Parameter. This shows that when we run the web test, a unique filename will be used when uploading the Doc2.doc file.
In addition to a couple of new validation rules, Update 1 also provides a number of useful extraction rules that you can use with your SharePoint web requests. Right-click on one of the web requests and select the Add Extraction Rule option.
The additional SharePoint extraction rules allow you to do things like find specific list and document IDs, calendar dates, values of text boxes, workflow instance IDs, and so on.
Now we will look at the Download web test. This web test was recorded by navigating to a SharePoint site, loading the Shared Documents library, and downloading a specific document. After the test was recorded, a SharePoint extraction rule was added to find the document item and store it as a context parameter.
In the web request to Download.aspx, note that one of the query string parameters refers to the document previously extracted.
Now we are ready to wrap the web test inside a load test. You will notice that we now include SharePoint specific counters to capture on remote machines when running load tests.
Go ahead and run the load test to see it in action by selecting the Run Load Test button. The load test is configured to run for 1 minute.
3. After the results summary displays, you can see the individual page result details if you scroll down. To visualize the performance details over time, you can also try the Graphs view.
Simulate End user creation of publishing pages:
· Browse to Pages document library
· In Ribbon click on New Document select -> Article Page
· Populate the create Page wizard
Aim is to be able to create a single page creation test case and parameritise the recording such that it can be reused for creation of different types of pages with different webpart content. We will look at the new SharePoint extraction rules which are available to us to help with the extraction of dynamic parameters needed to make the above web test case work.
Web Test recording:
Let’s simply create a skeleton structure of what our Web test requests should look like. For this we will make use of the web test recorder. The next several screenshots document the flow of our recordings. It is a good practice to include comments while you’re recording your transactions for easier debugging of web test replay errors – as you will see further on in this blog post.
Edit the newly created page:
Insert webpart to the page:
Check-in the page:
Web Test parameters
Once out recording has completed Visual Studio will replay the recorded transaction twice and will by doing so identify dynamic parameters. As you will see further on in our blog post – not all dynamic parameters will be captured by Visual Studio.
Now it is time to replay back the recorded web test to see if we can replay the webtest without errors.
First error that we see in our web test replay is:
It appears that SharePoint has returned an error code back to the client saying that the parameter we placed in the URL Name already exists. We Mark this as another parameter that we will need to set dynamically during our load tests.
Fix for the above issue:
Let’s review the Form Post parameters that are posted for the above page from within the web test:
Now let’s modify the logic for the static values which need to be dynamic:
titleTextBox and urlNameTextBox
Selecting the above Form Post Paremeters you will notice under the properties window that you can easily set their values:
Since we need these parameters to be dynamic upon each test run we need to provide the web test a new value each time the http web request is called to ensure that we are not creating pages that already exist.
In this example we will create a CSV file which will store a unique list of PageUrlNames / Titles.
Create a new Folder named Data Source under your Load Test Project:
Add a new Text file which we will name CreatePage.csv
Let’s populate the contents of the CreatePage.csv file as per below:
Add the newly created data source:
Select the newly created CreatePage.csv as our source:
Confirm that the data source has been added to the web test:
Let’s check the Access Method property for our data source:
In this scenario we will pick unique as we only want the load test to execute the values within the CSV file once.
Let’s bind the data source values to our titleTextBox and urlNameTextBox parameters.
Rerunning the load test with the new parameters appears to fix the CreatePage error highlighted below – however we are still seeing a couple of issues:
1. Notice in the screenshot below requests highlighted in red boxes that the URL is still pointing to the TestPage.aspx instead of the newly created page as per the data source. We will need to paramertise this http request such that it is also picked up from the same data source.
2. We have a 400 Bad request formed in the inplview.aspx request. This could be due to the wrong TestPage Urls – so let’s first fix the TestPage URLS problem.
If we check the SharePoint list view for the pages library we notice that the web test replayed pages are not getting checked in properly either:
Fixing the TestPage.aspx URLS:
We fix the hardcoded TestPage.aspx from our recording by constructing a string which includes part of the substring from our CreaatePage.csv file datasource.
We set those particular web request URL and Expected Response URL properties to:
We repeat this where we see the hardcoded web request to TestPage.aspx such that it looks like below:
Let’s re-run the webtest and check for any issues this time round:
Let’s check if the file has been checked into SharePoint correctly:
We are not finished yet! What about dynamically changing page layouts and adding in different web-parts to the pages?
Now that we can successfully re-run our page creation web test it is time to add in some extra parameters to our load test to handle dynamic assignment of:
· Page Layouts
· Web parts
Please note: In this scenario we are assuming that we will always be adding a single web part to the page.
Let’s head back into our web test and find out what parameters we need to set to satisfy our web test scenario:
Dynamically assigning Page Layouts:
We know that the highlighted wizard page is responsible for assigning a page layout so let’s take a look at the params which we can control behind the http://ariansp2010_loc/_layouts/CreatePage.aspx request:
In our web test browse to http://ariansp2010_loc/_layouts/CreatePage.aspx request; expand out the form post parameters and locate the following:
You will notice that the paramter in this case is a dropdownList ID value:
You could manually browse to the CreatePage wizard – use the HTML element selection tool in the IE developer toolbar to understand the ID values in the dropdown list and their associated page layouts.
Once we know the HTML behind the page-layout selection we have two options for passing the values to the web test:
· We could create an extraction rule which will look for the HTML and pull out each page layout item
· We could simply add the ID variables to our CSV data source file and dictate the page layout assignments from here.
So there you have it a very quick and dirty blog post on some new VS2012 Load testing features for SharePoint. I hope that you do try out the tool and please provide the feedback! We want more of our clients to perform load testing so that you can mitigate any performance bottlenecks before solutions go to production.