Jan
25
2012

Working with WebDeployment in MS Project files

Great article: http://stackoverflow.com/questions/2959964/vs2010-web-deploy-how-to-remove-absolute-paths-and-automate-setacl

The displayed path is determined by the property _MSDeployDirPath_FullPath.

This property is setted by this chain of properties:

  • <_MSDeployDirPath_FullPath>@(_MSDeployDirPath->'%(FullPath)')</_MSDeployDirPath_FullPath>
  • <_MSDeployDirPath Include="$(_PackageTempDir)" />
  • <_PackageTempDir>$(PackageTempRootDir)\PackageTmp</_PackageTempDir>
  • <PackageTempRootDir>$(IntermediateOutputPath)Package</PackageTempRootDir>
_MSDeployDirPath_FullPath <-- @(_MSDeployDirPath->'%(FullPath)') <-- _PackageTempDir <-- $(PackageTempRootDir)\PackageTmp
AS you can see, you can't have a relative path, because _MSDeployDirPath_FullPath is the fullpath of _MSDeployDirPath.

But you can simplify the displayed path by overriding the property _PackageTempDir with the path you want to be displayed to your customer. (This path will be used as a temporary directory for the package generation)

You could override the property :

  • In command line :

    msbuild.exe projectfile.csproj /t:Package /p:_PackageTempDir=C:\Package
  • Or directly in the project file :

    <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
    <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" />
    
    
    <!-- Must be after Microsoft.WebApplication.targets import -->
    <PropertyGroup>
      <_PackageTempDir>C:\Package</_PackageTempDir>
    </PropertyGroup>

 

Nov
22
2011

Tool for working with .NET config file transforms

Check out this great tool for working with .NET config file transforms

http://www.hanselman.com/blog/SlowCheetahWebconfigTransformationSyntaxNowGeneralizedForAnyXMLConfigurationFile.aspx

Nov
22
2011

Multiple app.config files (just like web.config files)

Good article from stackoverflow

http://stackoverflow.com/questions/3004210/app-config-transformation-for-projects-which-are-not-web-projects-in-visual-stud

Great article from:

http://www.olegsych.com/2010/12/config-file-transformation/

----

 

Nov
17
2011

Prevent ASP.NET web.config inheritance, and inheritInChildApplications attribute

If you have ever had the scenario where you have a main ASP.NET web application and then need to create one or more sub virtual folders that contain completely independant applications (different authentication, error pages, etc), then you have probably run up against the need to prevent the normal web.config inheritianace.  Do do this is pretty simple, just setup the PARENT web.config like this
 
<!-- Root web.config file -->
<?xml version="1.0"?>
<configuration>

  <location path="." inheritInChildApplications="false"> 

    <system.web>

      <compilation debug="false" />

      <!-- other configuration attributes -->

    </system.web> 
  </location>
</configuration>
The one catch when doing this is that you'll probably notice Visual Studio compain about the "inheritInChildApplications" attribute.  Turns out this is because the Schema XSD files for web.config that shipped with VS2005/2008/2010 left out support for this attribute (Note: this doesn't prevent your app from work, it just means VS IDE will complain).
To fix this, open up the following files located in %ProgramFiles%\Microsoft Visual Studio XX\Xml\Schemas (XX is 8.0, 9.0, or 10.0 depending on your version)
  • DotNetConfig.xsd
  • DotnetConfig20.xsd
  • DotnetConfig30.xsd
  • DotnetConfig35.xsd
For each of the files -- Find the <xs:element name="location"> tag and change it to look like this
<xs:element name="location">
  <xs:complexType>
    <xs:choice>
      <xs:any namespace="##any" processContents="lax" />
    </xs:choice>
    <xs:attribute name="path" type="xs:string" use="optional" />
    <xs:attribute name="allowOverride" type="small_boolean_Type" use="optional" />
    <xs:attribute name="inheritInChildApplications" type="xs:boolean" use="optional" />
  </xs:complexType>
</xs:element>
Basically what you are doing is adding this one line to that complex type declaration
<xs:attribute name="inheritInChildApplications" type="xs:boolean" use="optional" />
 
And thatsit -- you're good to go.
Apr
1
2011

Branching and Looping in a Declarative Web Test

Note: This is a repost from this artcile from MSDN Blogs

Visual Studio 2010 in a huge number of new features and capabilities across a wide range of disciplines.  In many cases these features are small continual improvements to existing features areas and they tend to get lost in the hubbub of the big new shiny stuff.  Since its first release in Visual Studio Team System 2005 the web and load testing features have quietly and steadily been improved in each release.  Each time we have added more functionality and more valuable to one of the least marketed but potentially most valuable parts of the suite.  In this post I will cover one of the small features that I believe will have a big impact on users that are writing Web Performance Tests (formerly Web Tests).

In the previous two releases of Visual Studio Team System (new Visual Studio ALM Tools) if a user wanted to put any conditional logic into their web tests they were forced to drop in to code.  While this is not too big of a deal on the surface, as soon as you drop into code you loose a lot of productivity that the visual editor affords you.  In addition there are many cases were the person writing the web test is not a developer and they do not have knowledge to write in C# or VB.NET code.  In that case they had no ability to have condition or looping logic in their web tests.

In Visual Studio 2010 you now have the ability to add both branches and loops into your declarative web tests, in addition you have the ability to create your own conditional rules to control your branching and looping logic.

Adding a loop to your web test

Lets take the example of a simply web test on our ecommerce web site.  In this test we want to simulate a user that is simply browsing our catalog.

 

 

As you can see we have only two requests, one to the product list page and one to the product details page.  While this test is all a browsing customer will do you our site, it is not a very good representation of that customer.  In the current test each customer will browse only 1 product and it will always be the same product of the same category.  Let’s see if we can make it a little more repetitive of what we might expect.

The first thing we would do for this test is to databind it to a list of products so we can as least have the user browse a different product each time.

 

 

After this modification each time a user runs this test they will at least browse for a different category of products and a different product.  However, in most cases we hope that a user will spend more than just a few seconds on our site and we would like them to browse more than one Item. In previous releases of Visual Studio you would have two options. 

The first option would be to drop into code, however, that has a bunch of drawbacks on productivity so we don’t want to go that route.  The second option would be to add a bunch of requests to the products list and product details page.  While this would work we would be stuck with each user executing the same number of requests per test iteration and in each of those requests would request the same category and the same product per test iteration as the data source cursor does not advance during the execution of the test only between iterations.

To get around these issues and create a test that is more realistic to a browsing customer on our site we will add a loop around the two key requests.

 

 

Right-click on the request where you want the loop to start and select “Insert Loop…” from the context menu to launch the “Add Conditional Rule and Items to the Loop” dialog.


As you can see in the dialog there are a variety of different conditional rules you can use to control the flow of your loop.  There are some basic loops like the “For Loop” or simple “Counting Loop” that will execute the selected requests a specific number of times before exiting.  In our cases we want to simulate a broad set of our browsing customers so we want a loop that will execute the set of requests a random number of times so we have picked a “Probability Rule”.

The “Probability Rule” will execute our loop based on a percentage so such that each time the loop comes around it will “roll the dice” and if it returns true the loop will execute and if it returns false it will not.  In our site we have determined that 70% of the time our customers look at more than 1 product when they are browsing so we will put that number in.

There are a couple of other properties on this rule that are interesting:

The first one is the “Advance Data Cursors”.  When set to “True” as we have here this tells the engine to advance the cursor on our data source forward with each iteration of the loop.  This has the effect of having the user browser for a different category and product each time they execute the requests in the loop.  The second on is “Max Number of Iterations”.  This will force the loop to execute after a maximum number of iterations, in this case 8, as been reached regardless of the outcome of the processing of the conditional rule.

Once we have completed the dialog we see the rule added to our test

 

And when we run our test we can see that our loop has executed more than once


Adding a branch to your web test

Lets take our same example of a simple web test but in this case we want the user to login into our site unless they have already logged in before.  

 

 

Right-click on the request where you want to begin your branch and select “Insert Condition…” from the context menu to launch the “Add Conditional Rule and Items to Condition” dialog.


You will notice that this dialog looks exactly the same as the previous dialog right down to even having some of the same conditional rules for branches as loops.  In our case we are going to select the “Cookie Exists” rule from the list, set the properties and click “Ok”.

Now that we have inserted the rule into our test we see the following:

 

 

One thing that you will have to know about branching conditional rules is sometimes you will have to negate a rule in order to get the behavior you want.  In our case we will have to set “Check for Existence” to False in order to let the rule execute if the cookie is not there and not execute if the cookie is there.

Summary

Declarative branching and looping in Visual Studio 2010 allows you to build more complicated and realistic web tests without having to resort to code.  This lets you maintain the high level of productivity of the visual editor for web tests and lets those non-coder users have more power.

Apr
1
2011

How to test jQuery enabled Apps using JSON with Visual Studio

Note: This artcile is a repost of one written by Andreas Grabner -- all credit goes to him for his excellent artcile

Visual Studio Team System offers a nice Web- and Load-Testing Feature that allows you to easily create tests to verify your web application’s functionality as well as verifying how it performs under load. Web Applications that make use of AJAX Frameworks likejQuery execute additonal web requests to request information from the Web Server without causing the browser to reload the complete page. JSON is one of the formats that is used to exchange information between the Web Server and the AJAX Framework running in the browser.

Challenges with AJAX in Web- and Load-Testing

Asynchronous calls executed by AJAX frameworks can be very hard to deal with for web- and loadtesting tools? Why? Because those requests can most often not easily be correlated to a Page Request done by the browser and therefore its not easy to create a nice script that shows the sequential logic of all user interactions.
The next problem with AJAX requests is that its hard to verify if the simulated request produced the correct result and whether the result of one request needs to feed a subsequent request. An example for this would be a login call that returns a user id. This user id needs to be used for subsequent calls. If the testing tool doesn’t understand JSON and is not able to automatically detect the dependency between those calls its up to the test engineer to add parsing statements for the first call and use the parsed value in subsequent calls.

How to test JSON with Visual Studio?

I’ve downloaded the following ASP.NET MVC Sample App (KIGG) that uses jQuery and JSON. My task was to create a web script with Visual Studio that creates new user accounts. In order to do that a user needs to sign on to the page with username, password and email. The user account can then be activated by following an activation link that is sent via email.

Necessary steps for the Test Script

  • Execute the request to sign up a new user by providing username, password and email
  • Get the information about the activation link
  • Execute the request to activate the user account

The default procedure for the activation uses an email that is sent out. As I didn’t want to bother with email during my web testing I extended the JSON message that is returned when signing up a new account to include the information about the activation link. Having that information as part of the response allows me to finish all the steps.

How to deal with JSON messages?

Here is the JSON message that is responded by the user signup request:

{"isSuccessful":true,"userId":"9JU51KDxp0-3Llw1BU2h7w","errorMessage":null}

 

The userId is the value that I am interested in. This is the value I need to use to call the Activate page. Another interesting value is the isSuccessful property. This allows me to add additional logic to my web script. I can verify if the sign-up request was successful. In order to do all this I need to extend Visual Studio Web Testing by writing my own Extraction andValidation Rule. Visual Studio offers an interface to provide custom implementations for value parsing and validation. Here is my implementation for the ExtractorRule using a helper class that parses the JSon string:

 

public override void Extract(object sender, Microsoft.VisualStudio.TestTools.WebTesting.ExtractionEventArgs e) {
  NameValueCollection jsonProperties = JSonHelper.ParseJSonString(e.Response.BodyString);
  string propertyValue = jsonProperties.Get(JSonPropertyName);
  if (propertyValue != null) {
    e.WebTest.Context.Add(ContextParameterName, propertyValue);
    e.Success = true;
  } else
    e.Success = false;
}

 

In a similar way I implemented the ValidationRule. Using it all in my web test allows me to specify the Extractor and Validation Rule in my web test.


 

Conclusion

With Visual Studios extensibility mechanisms its easy to build support for those emerging technologies like jQuery and JSON. Let me know if you need the library that implements the two extension Rules.

 

Apr
1
2011

Randomizing Input Data for Visual Studio Load Tests

Note: This artcile is a repost of one written by Andreas Grabner -- all credit goes to him for his excellent artcile

While preparing for my presentation Load and Performance Testing: How to do Transactional Root-Cause Analysis with Visual Studio Team System for Testers that I gave at the Boston .NET User Group on May 13th I came across certain load-testing topics. One was: How to randomize Input Data.

If you go with Visual Studio you can code your web tests in any .NET Language giving you the freedom to create random data by using e.g.: System.Random. If you however want to use the “nicer” UI Driven Web Test Development (that’s how I call it) – you are limited in your options. You add web requests – you can parameterize input values by using Context Parameters with hard coded values, you can reuse values extracted from a previous request or you can use data from an external data source like a database, CSV or XML file.

Basic random numbers for VSTS Web Tests

One thing that I missed was the ability to use basic random values, e.g.: a random number from 1 to 5 that would be used for a quantity field of a web form or a random username with the pattern “testuserX” where X is in the range of my test user accounts.

In order to do that there only seems to be one way – implementing a WebTest or WebTestRequest Plugin that generates random data and makes it available as Context Parameter to the test.

Sample: Randomizing username and password

Lets get back to my username/password example. Following illustration shows my original Web Test:

 

 

Hard Coded values for Username and Password

I extracted the hard coded values from the recorded web request into a context parameter – but still using the hard coded values. One option that I would have here – as indicated in the first paragraph – would be to make this test data driven by binding the Context Parameters to an external data source. But this is not what I want in my example. I really want to randomize the input data so that every web request uses a new random value. I therefore created a WebTestRequestPlugin as shown in the following image:

 

 

 

 

Random Parameter WebTest Request Plugin

My plugin defines two properties that can be configured with a Parameter Name (or names) and a random value pattern. In the PreRequest override I use a random value generator that generates the random value based on the passed pattern and put the generated value in the Test Context.

Now I can use the plugin in my webtest as follows:

 

 

 

Randomize Context Parameters with Request Plugin

Now I can run my Web Test either “standalone” by defining the number of iterations or using it in a Load Test. Every time the WebRequest will be executed the WebTestRequestPlugin will create a new random value that will then be used by the request. This allows me to run this test over and over again – always using a different username and password.

Conclusion

Check out the option to create your own WebTestRequestPlugin or WebTestPlugin. This extension option gives you more flexibility when creating web tests for Visual Studio.

 

Mar
31
2011

Useful Visual Studio 2010 Extensions

Free Extensions

Commercial Extension

Dec
13
2010

Leveraging ILMerge to simplify deployment and your users experience

Reposted from here

Leveraging ILMerge to simplify deployment and your users experience

ILMerge is one of those little-known gems that are an absolute must-have once you know how to apply them effectively to scenarios you didn't even think about.

Specifically, whenever you work on a multi-project solution that may also use external projects in turn, forcing your users to add (say) five assembly references just to your "entry point" library is clearly a bad experience. One example that comes to mind isEnterprise Library, where you add a minimum of 3 (IIRC) assembly references to use just about *any* block in isolation. If you use more than one, it quickly becomes quite a big list. Wouldn't you want to just give your users a single EnterpriseLibrary.dll?

Of course, you wouldn't do it if the price of that end-user simplicity was that you had to merge all your projects into a single one, complicating the dependency management and isolation between layers.

Also, if you use a bunch of external libraries, do you think your users care? Having a single Dll gives a feeling that "this is small, I can manage to take a dependency on this single library".

ILMerge to the rescue

The two scenarios are precisely ILMerge targets. It allows you to merge multiple assemblies into a single one, offering various options when doing so.

Let's see a concrete example: Moq. Moq is a (fairly popular) mocking library for .NET. It depends on two awesome external libraries: Castle.Core.dll and Castle.DynamicProxy2.dll, which provide the runtime interception infrastructure that Moq builds upon. Moq users are not exposed to that internal implementation detail ever: they just add a reference to a single Moq.dll assembly and that's it.

Typically, you will merge all the assembly references that have Copy Local = true (that is, dependencies that you distribute with your project as local, non-GAC'ed assemblies). So in order to automate this, in Moq we use an MSBuild target that is enabled only on release builds:

1.<Target Name="AfterBuild" Condition=" '$(Configuration)' == 'Release' ">
2.<Exec Command="&quot;$(MSBuildProjectPath)..\Tools\Ilmerge.exe&quot; /ndebug /keyfile:$(AssemblyOriginatorKeyFile) /out:@(MainAssembly) &quot;@(IntermediateAssembly)&quot; @(ReferenceCopyLocalPaths->'&quot;%(FullPath)&quot;', ' ')" />
3.<Delete Files="@(ReferenceCopyLocalPaths->'$(OutDir)%(DestinationSubDirectory)%(Filename)%(Extension)')" />
4.</Target>

Let's go over it:

  • The target has a condition that it will run only on Release builds.
  • The /ndebug parameter to ilmerge tells it to merge the PDB/debug files if present. Very handy :)
  • The /keyfile ensures that the merged assembly is signed with the same key file as your original project.
  • The /out is obvious, and we specify the MainAssembly item reference so as to replace the main output of the compilation.
  • Finally, the ilmerge tool receives the list of assemblies to merge. In addition to passing the IntermediateAssembly item which is the current output of the compilation process, we need to build a list of references that have CopyLocal set to true. We use the ReferenceCopyLocalPaths items, which is conveniently populated by the core MSBuild targets file Microsoft.Common.targets which is automatically imported in all your projects (and contains the resolved primary assembly references). We basically project the full path of those references and build a coma-separated list for ilmerge.
  • Finally, we delete all these references as they are now merged in the main assembly.

ILMerge Silverlight assemblies

For Silverlight, the above command will generate a desktop .NET assembly, which doesn't work in Silverlight, even if the original assembly was a Silverlight one. You need to pass a couple more arguments to ilmerge:

  • /targetplatform: need to explicitly specify v2 as well as the platform directory, which is basically the folder that contains mscorlib.dll. In my case, for Windows x64 and Silverlight 2.0, I specified: /targetplatform:v2,"C:\Program Files (x86)\Microsoft SDKs\Silverlight\v2.0\Reference Assemblies"
  • /lib: all other non-mscorlib assemblies need to be resolved to the Silverlight folder too, rather than the GAC/desktop ones. This switch receives the same path as the previous one.

So for Silverlight, the full task looks like this for Moq.Silverlight:

1.<Target Name="AfterBuild" Condition=" '$(Configuration)' == 'Release' ">
2.<Exec Command="&quot;$(MSBuildProjectPath)..\Tools\Ilmerge.exe&quot; /targetplatform:v2,&quot;C:\Program Files (x86)\Microsoft SDKs\Silverlight\v2.0\Reference Assemblies&quot; /lib:&quot;C:\Program Files (x86)\Microsoft SDKs\Silverlight\v2.0\Reference Assemblies&quot; /ndebug /keyfile:$(AssemblyOriginatorKeyFile) /out:@(MainAssembly) &quot;@(IntermediateAssembly)&quot; @(ReferenceCopyLocalPaths->'&quot;%(FullPath)&quot;', ' ')" />
3.<Delete Files="@(ReferenceCopyLocalPaths->'$(OutDir)%(DestinationSubDirectory)%(Filename)%(Extension)')" />
4.</Target>

Internalizing Dependencies

Merging multiple assemblies into one gets you a long way towards making your library look dead-simple. However, it may be the case that after adding a reference to your main assembly, users get a ton of foreign namespaces that they don't know about and they will never need to know about. These are the external dependencies of your library that are only used internally in your product.  You can change the visibility of all these dependencies just by specifying one additional switch to the ilmerge tool: /internalize.

Internalize receives an optional "exclude file" which is a text file containing a type name on each line for types you don't want to touch (leave their visibility intact). In Moq case, the runtime interception needs for runtime-generated code a few public types from Castle, so we provide an exclude file with the following content:

Castle.Core.Interceptor.IProxyTargetAccessor
Castle.DynamicProxy.AbstractInvocation
Castle.DynamicProxy.Generators.AttributesToAvoidReplicating

So the full Exec task looks like the following:

<Exec Command="&quot;$(MSBuildProjectPath)..\Tools\Ilmerge.exe&quot; /internalize:&quot;$(MSBuildProjectPath)ilmerge.exclude&quot; /ndebug /keyfile:$(AssemblyOriginatorKeyFile) /out:@(MainAssembly) &quot;@(IntermediateAssembly)&quot; @(ReferenceCopyLocalPaths->'&quot;%(FullPath)&quot;', ' ')" />

 

Happy ILmerging ;)

Aug
20
2010

Keyboard shortcut to enable/disable track activity in solution explorer

When I'm working in Visual Studio, I generally turn off the option to automatically track the curent item in the Solution Explorer. I don't like the Solution Explorer hopping about as I switch from file to file. Sometimes I do like to find whatever I'm working on, though, and that can be painful if you do it manually.

Fortunately, Visual Studio has a command you can bind to a keystroke to do exactly that: View.TrackActivityinSolutionExplorer

It's not bound to a key by default, but you can go to Tools -> Options and bind it yourself. I've got mine bound to Ctrl+Shift+Alt+T. ('T' for 'Track' but you might want something more memorable for you.)

NOTE: This will TOGGLE the Track Activity -- so remember to hit it again to turn it off!