Thursday, December 20, 2007

Creating Custom Code Analysis Rule

In VS2005, code analysis can be run very easily selecting the rules individually. There might be occasions that these rules are not enough. The rule libraries in VS2005 are created using Fxcop and you can easily create your own coding rules. I will give an example on creating a rule that will force the application to use "Test" as the prefix in unit test methods.

Fxcop dlls are located under C:\Program Files\Microsoft Visual Studio 8\Team Tools\Static Analysis Tools\FxCop. While writing the rules FxCopSdk and Microsoft.Cci dlls need to be references. Introspection library has been introduced in Fxcop but I could not see documentation enough. With the reflection and file assembler add-on, it is very easy to open the dlls and see the rule project as a whole in c# code. You will have lots of examples to look at.

I will summarize the necessary steps

1) Create a class library, UnitTestsRules class library

2) Add a base class for your unit test rules, UnitTestIntrospectionRule.cs

using Microsoft.FxCop.Sdk;
using Microsoft.FxCop.Sdk.Introspection;
using System;
namespace Microsoft.FxCop.Rules.Naming
{
internal abstract class UnitTestIntrospectionRule : BaseIntrospectionRule
{
protected UnitTestIntrospectionRule(string name)
: base(name, "UnitTestRules.UnitTestRules", typeof(UnitTestIntrospectionRule).Assembly)
{
}
internal Resolution GetNamedResolutionInternal(string id, params string[] args)
{
return this.GetNamedResolution(id, args);
}
public override TargetVisibilities TargetVisibility
{
get
{
return TargetVisibilities.All;
}
}
}
}
As seen in the example the constructor refers to a resource. This resource is an xml file with the name UnitTestRules.xml. It should be selected as an embedded resource in the project. Since the default namespace is UnitTestsRules, it is possible to access to the resource as UnitTestRules.UnitTestRules. If you have any directories in place for the resource you need to add them to the path as well.

3) Add the rule class, MethodsMustStartWithTest.cs

In this class we will write the rule to make sure all the test methods start with "Test" To do that we will overriding the method checking for members. If you are doing any code analysis for types etc you need to override the appropriate one. To test if a test method starts with Test, we first get the method info and check the method's attributes to see whether it contains TestMethodAttribute attribute or not. If there is a problem we add a resolution to the problems collection. Since it is a problem in a member, name the resolution as Member. It will match to an entry in the xml file that we created earlier. We will pass the name of the method that does not conform to the standard in the resolution.
using Microsoft.Cci;
using Microsoft.FxCop.Sdk;
using Microsoft.FxCop.Sdk.Introspection;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Collections;
using System.Globalization;
using System.Reflection;
namespace Microsoft.FxCop.Rules.Naming
{
internal sealed class MethodsMustStartWithTest : UnitTestIntrospectionRule
{
public MethodsMustStartWithTest()
: base("MethodsMustStartWithTest")
{
}
public override ProblemCollection Check(Member member)
{
//Check if the member being processed is a method
Method method = member as Method;
if (member.NodeType != Microsoft.Cci.NodeType.Method)
{
return base.Problems;
}
//Chekc if the method is a test method
object[] info = method.GetMethodInfo().GetCustomAttributes(typeof(TestMethodAttribute), true);
if (info == null info.Length == 0)
{
return base.Problems;
}
//It is a test method, so check the name of the method to see if it starts with 'Test'
string name = member.Name.Name;
if (!name.StartsWith("Test"))
{
//Create a problem using 'Member' resolution
Problem problem = new Problem(this.GetNamedResolution("Member", new string[] { name }), name);
base.Problems.Add(problem);
}
return base.Problems;
}
}
}

4) Create the test rule content in UnitTestRules.xml

We will give a friendly name to the rule collection. It will be displayed in VS2005 using this name. We will also map the rule's type name to the name of the class that we just, MethodsMustStartWithTest.
For each rule give a different id. In this case it is UNITTEST0001. The other attributes are already self explanotory. We have a resolution named as Member and expects one paramaterwhich is the method name as explained in the previous step.

<Rules FriendlyName="Custom UnitTest Rules">
<Rule TypeName="MethodsMustStartWithTest" Category="UnitTests.Naming" CheckId="UNITTEST0001">
<Name>Methods Must Start With Test</Name>
<Description>Methods Must Start With Test</Description>
<Url>/UnitTesting/MethodsMustStartWithTest.html</Url>
<Resolution Name="Member">Method {0} does not start with Test</Resolution>
<Email>
</Email>
<MessageLevel Certainty="95">Error</MessageLevel>
<FixCategories>Breaking</FixCategories>
<Owner />
</Rule>
</Rules>

5) Deploy the rule dll

After building the dll, drop it under C:\Program Files\Microsoft Visual Studio 8\Team Tools\Static Analysis Tools\FxCop\Rules. It ius ready to use from VS2005!

TDD Standards, Naming Conventions


Standard naming conventions applied for code should also be applied for the test codes. But there might be some extra naming conventions in place like starting test methods with Test or having a specific keyword in the test class library name itself.

This page covers basic guidelines about the naming standards.
http://weblogs.asp.net/rosherove/archive/2005/04/03/TestNamingStandards.aspx



  • Test name should express a specific requirement

  • Test name should include the expected input or state and the expected result for that input or state

  • Test name should be presented as a statement or fact of life that expresses workflows and outputs

  • Test Name should only begin with Test if it is required by the testing framework or if it eases development and maintenance of the unit tests in some way.

  • Test name should include name of tested method or class


Fxcop is being used in VS2003 as a code analysis tool and in VS2005 it is already integrated to the development environment. You can enable code analysis and select specific rules. It can also be done in nightly builds to make sure your builds do not break your conventions. What if you need a new one? For example how do you make sure all the test methods start with "Test" if you have such a rule? I will explain how to create a custom rule in a different blog entry.

Wednesday, December 12, 2007

TDD Standards, Code Coverage


Code coverage defines the percentages of the methods tested by unit tests. Ideally it should be 100%. In this case all the lines in the code should be exercised. It does not tell about if all the possible scenarios are tested or not. With code coverage we try to execute every piece of code and test it. We can also use other coverage techniques to improve the quality of the tests. They are nicely written in this link. http://en.wikipedia.org/wiki/Code_coverage How many tests should we write then? Ideally all the tests should be written so that there is nothing left to break the code.


Thursday, December 06, 2007

What Should Be Tested in Unit Tests


Unit tests must be written to test general functionality and boundary conditions. Anything that can break the code should be tested. If there is an uncertainty for a piece of code, we should write a test method. It is better to use judgement while deciding about writing a unit test or not. It is not easy to test GUI. To be able to cover as much code as possible, GUI codes should be kept very small and business classes should be aimed at the tests. It also forces us to keep everything in the business classes and let the GUI do only the presentation work.


What to test:
- We should write test methods for all the public methods.
- Private methods should be tested via public methods. If a private method is very critic we can write a specific test method for it. In VS2005 it is very easy to add a unit test method. Visual Studio itself creates the unit test template using reflection.
- For each piece of requirement we should write a unit test. More than one requirement may be in one public method but usually each requirement represents one possible path in the code and each path should be tested.
-Expected or possible exceptions should be tested as well.
-Before fixing a bug, a unit test can be written first. We can then write the piece of code to fix the issue. It makes us sure that the code is bug-free.

What not to test
-There is no need to test accessors (to getvalues) or mutators (to set values). They are very simple get and set methods. They are unlikely to break the code.

Hints:
- Unit tests for each class must be placed in a separate test class.
- To test abstract classes implement abstract test classes. Respectively for the concrete classes, concrete test classes inheriting from the abstract ones should be written
- We should write the test methods for dependencies.


Wednesday, September 05, 2007

SCRUM

We are applying SCRUM in our software projects and I wanted to write about it summarizing its advantages, disadvantages and how to make good use of this approach in software projects.

During the middle of a project, requirements may change or the users may not like the application after it is delivered. Although lots of the requirements can be specified at the beginning of a project, we should be flexible enough depending on the conditions.

Scrum might be ideal if your project’s requirements are changing rapidly.

Scrum starts with the product backlog. In scrum, product backlog includes the tasks, stories which are prioritized by the product owner. Product owner should not be involved with technical details but should be focused on business goals. I would even describe the product owner as a business analyst. All team members contribute to find the estimates for the tasks. A task or a story is not about coding all time. It can also be documentation, testing and deployment, anything that needs to be done to deliver the application to the end users. Each task should be split into subtasks and they should be included in the product backlog. All the team members together determine the estimates. Estimates can be changed during the scrum sprint. A sprint can be defined as a bunch of tasks selected from the product backlog to finish in a given time and it should not be changed once it is agreed. No one from outside the team should change the sprint or interfere with it. Sprints can be 2-3 or 4 weeks. The meetings are managed by the scrum master. Scrum master’s role is basically like a project manager or a team leader. He helps team to achieve the tasks in the sprint. Sometimes the team members are unaware of the status for a sprint. It requires feedback from the scrum master.

Every day, the scrum team makes a meeting. These meetings should not be very long. In these meeting, the team members tell about the work they have done since the last meeting and what they intend to do until the next one. If there are any impediments, they should be discussed as well.

Scrum or RUP or XP?
Scrum does not have a defined software process. It concentrates on how team members are doing on the project with every day sprints. However RUP defines a process. With the given estimates, it requires good quality software to be delivered based on the requirements. For each activity, a template can be found in RUP. It can be a guideline, a template, defined sets of rules etc. Scrum is mainly about the management, while XP is about programming practises. They can be used together to come up with management and programming practices. They may overlay sometimes.

RUP, XP, Agile, SCRUM,…. Is it enough to rely on applying these methods and expect to succeed? Whichever of them you use, followings are very important.

- Good team: If the developers are good enough whichever method is being applied does not matter. It will bring the success. SCRUM tries to increase the communication between team members. So it gives management a bit more control. It is also good for developers since the estimates are discussed in sprint meetings and everyone gets aware of the difficulties. Every team member knows what the other colleagues are doing and how difficult task each team member has. Developers have their chance to express why a task takes long or short agreeing with all the team. Estimating tasks will be fair for all developers. Business owners will be aware of all this as well.

- Make sure you have the requirements: Having sprint tasks may not be enough. It is good to have the requirements. You do not have to update the requirement documents for the life time of the project. It does not have to be a heavy document but developers need the requirements. Product owner’s role is very important in SCRUM. If he changes his opinion about a task too frequently then there is something wrong. Trying to finish a project and then change it may cause bad coding practises in the project. It is difficult to have the good quality back.

- Make sure you have unit tests: It is always good to have unit test codes. If your requirements are changing rapidly, it is a must! There is no other way. It really helps you in the long term. It may not mean anything to product or business owners at first and they may not give any priority for writing test methods. But it is very essential. Applying test driven development might be a good choice in SCRUM since it also helps you to analyse what you are developing. In SCRUM we split tasks to the smallest tasks and assume that we do not need any more analysis. Test driven development fills the gaps missing from this task oriented development.

- Code reviews: If you have a new team member, it is wise to review the codes until he becomes more confident. It is not to track him but just to point in the right direction if anything goes wrong.

- Error handling: Is error handling a must or something good to have? For me, it is essential, especially in SCRUM. We have to capture the errors so that we can fix them. Without knowing what is causing the problems our products will be with the errors. From the beginning we should implement error handling and log the errors. It should not be waited until the end of the project. It should also be included in the way the coding is done.

Tuesday, July 10, 2007

TransactionScope

Recently I was looking to TransactionScope class to see what advantages I can have using it.
using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, new TimeSpan(0, 0, 10)))
{
. . .
}
When you use TransactionScope with only one connection to a SQL Server 2005 database, a local transaction is started. But if you have more than one connection, your transaction will be promoted to a distributed transaction.

If you have two methods opening a connection and doing some stuff, you should expect to use a distributed transaction. Use local transactions to gain performance. Do not even try the distributed transactions. But there are some scenarios that this class is very handy.

- Imagine that your method is executing a stored procedure, depending on the result you have to do a file processing or some other processes not related to the database. You can use TransactionScope in your business method to rollback the changes if the tasks that are not related to database go wrong. But be careful, you should only be opening only one connection to the database. Otherwise your transaction will be promoted to be a distributed transaction.

- Writing unit test is very helpful to test the codes. But it requires leaving the database in the same state before the test. Sometimes developers start writing messy codes and attach a few other stored procedures just to help the creation of test data. Usually we have data creation methods in our business layers. Instead of relying some codes which do not exist in a project, we can purely use the codes that exist in the project. Just wrap everything using TransactionScope. As long as you do not call Complete method all the changes will be rolled back at the end ensuring that the database will be left in its previous state. You may need to update the security settings of your COM+ services since the transactions will be distributed using COM+.

Goto Component Services->Computers-> My Computer->Properties->MSDTC->Security Configuration. Make sure Network DTC access is enabled and the authentication level is as you want

Tuesday, June 05, 2007

Regular expressions vs. string operations

I'm not an expert at using Regular expressions but I tend to use them where possible.
It is a very powerful and handy tool. It can be used for validation purposes, string manipulation or searching etc.
I admit that it is sometimes very difficult to understand a regular expression. In these cases using a regular expression tool, like Expresso, is very helpful to decode the expressions.

Using regular expressions is extremely helpful especially if you are dealing with html codes.

Let's define a string variable having a simple html output.

string html = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\"><html
xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\"><head><title>test
page</title></head><body><form action=\"\" method=\"post\"><p>Lorem
ipsum dolor sit amet, consectetuer adipiscing elit.Lorem ipsum dolor sit amet, consectetuer
adipiscing elit.Lorem ipsum dolor sit amet, consectetuer adipiscing elit.Lorem ipsum
dolor sit amet, consectetuer adipiscing elit.</p></form></body></html>";

Suppose that you want to retrieve the text between the form tags. Regular expressions is a very good candidate to do the job.

Regex regex = new Regex(@"<form\b[^>]*>(.*?)</form>");
Match match = regex.Match(html);
if (match.Success){
  result = match.Groups[1].Value;
}

The code does not look messy and it gives you what you want. It takes 0,070625904 ms. It is fast.

How about using string operations!

int index = html.IndexOf("<form");
if (index > 0){
  int formEndIndex = html.IndexOf('>', index);
  if (formEndIndex > 0){
    int endIndex = html.IndexOf("</form>");
    if (endIndex > 0){
      result = html.Substring(formEndIndex + 1, endIndex - formEndIndex - 1);
    }
  }
}

The string operation only takes 0,00312504 ms.

This is fast as well but it is 22.6 times faster than the regular expression. Although it may not reflect all the scenarios, using string operations seems faster than using regular expressions!!

Note: Each code snippet was executed 10000 times to calculate the speed. To calculate the average, the same process was repeated for 10 times.

Using RegexOptions.Compiled option as shown below might help but be careful!

Regex regex = new Regex(@"<form\b[^>]*>(.*?)</form>", RegexOptions.Compiled);

In this case the average becomes only 0,019062744 ms which is 3.7 times faster than the uncompiled regular expression execution.
(Regex expression was created once and executed 10000 times to get the results for each iteration)

If you are not caching the regex expression to use for other executions, or intend to use an expression only once, then do not use the compile option. If we compile the expression each time before we use the expression, it takes 4,330055424 ms !!! 61 times slower than using it without the compile option

we should use regular expressions but it should not become a behaviour. Using string operations is still a choice.
We should choice which method to use depending on the complexity and the conditions.

How do we decide then?
Here is the list to start with.
- The code should perform well.
- It should be readable
- It should be easy to maintain
- Documentation should be clear to understand
If you want to add anything to this list, send me an email.


Wednesday, May 30, 2007

Search engines and 500 internal server error

If your pages are not indexed by search engines, try to simulate their user agents. Make sure that the page can be viewed in that way and you do not get any 500 internal server error.

Possible causes:
- Creating SEO friendly urls at runtime using ASP.NET 2.0


Solution:
The default browser files are located in "C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\CONFIG\Browsers".
You need to add the browser definition for the new user agent to either this directory or or to App_Browsers directory under the application path.
http://msdn2.microsoft.com/en-us/library/ms228122.aspx

Browser definition files must have a .browser file name extension.

You may want to check this list to test if your application is working with other search engines' user agents.
http://www.spidermatic.com/en/supported_spiders.php

To simulate the user agents of search engines;
- Install User agent switcher addin to Firefox.
https://addons.mozilla.org/en-US/firefox/addon/59
- Create a new user agent in the options section of the add in.
- Set User Agent to the search engine's user agent.
For Google: "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)".
For Yahoo : "Mozilla/5.0 (compatible; Yahoo! Slurp; http://help.yahoo.com/help/us/ysearch/slurp)"
- Just put dummy text for the description. Let's say "Google Bot"
- When you run the same page on the browser with the new user agent selected, you should be able to see the page, otherwise search engines will not be able to crawl your page

You can also use Fiddle on IE to customize the user agent.
- Select Rules->Customize Rules menu option
- Go to the end of OnBeforeRequest method
- Add this line
oSession.oRequest["User-Agent"] = "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)";
-Save the changes

You can see the user agents having problem from IIS web logs under system32\LogFiles directory

Friday, April 27, 2007

X-WSSE UsernameToken timed out


A couple of days ago, our web service retrieving data from Movable Type server using the ATOM API, started not to work. The web service was in a different server and nothing was changed. Both servers were in the same network.

The status of the error was 403 (Forbidden) and the status code was
"X-WSSE UsernameToken timed out".


We found out that there was 2.5 minutes time difference between the servers.
Then I checked Movable Type's scripts from the link below:

http://www.dankohn.com/mt/lib/MT/AtomServer.pm

........................
use constant TIMEOUT_WINDOW => 120;
.........................

# xxx Expire sessions on shorter timeout?
my $user = MT::Author->load({ name => $auth->{Username} })
or return $app->auth_failure(403, 'Invalid login');
my $created_on_epoch = $app->iso2epoch($auth->{Created});
if (abs(time - $created_on_epoch) > TIMEOUT_WINDOW) {
return $app->auth_failure(403, 'X-WSSE UsernameToken timed out');
}


As it is seen, the time out value is set to 120 seconds. Since the servers were not sycnhed, the request was timing out.

Thursday, February 01, 2007

Using dll.config files in .NET 2.0

In .NET 2.0 you can you use dll.config files. But once you try to use these dll's in other applications, it is not possible to read the settings in these files. You need to merge the dl.config with the application configuration file to be able to read these settings. To merge the configuration files, copy all the content in the dll.config file and put it in the application config file. Then the dll will be able to read them again!