Showing posts with label Unit Testing. Show all posts
Showing posts with label Unit Testing. Show all posts

Wednesday, June 9, 2010

VS2008 to VS2010 Upgrade Notes

UPDATE 6/23/2010:

The issue with one of our setup project builds has been successfully resolved with a workaround that I thought didn’t work at first.  It turns out our Microsoft contact couldn’t reproduce the issue.  It was the end of the day so I decided to shelve this issue until this morning.  I tried running the setup project from my XP machine with the workaround and it worked.  More importantly, I ran it on our build machine and it worked!  The thing that threw me off was that it failed on my Windows 7 development machine, which is where I initially tested the issue.  I suspect it might have to do with the fact that the interop assemblies were actually built on my old XP development environment and that something isn’t jiving now when I use the same assemblies to build on my Windows 7 machine.  In any case, copying the interop dlls to the same path as the vdproj file works like a charm.

 

 

Using the latest and greatest development environment is always fun.  However, upgrading from a previous version isn’t always easy.  When we converted our dev environment from VS2005 to VS2008, there were a number of headaches to get everything working properly.  So far, upgrading to VS2010 from VS2008 is proving no different.  Since we’re still on TFS2008, we used this workaround to build VS2010 solutions on our Build machines. 

So after our build machines had VS2010 installed and the above MSBuildPath workaround was applied, I ran my first build.  It was a ClickOnce build and it actually ran without any issues.  The application compiled and everything got copied over to our drop location…Cool!  So then I tried running our MSI build for the same project.  I was expecting it to build fine since the ClickOnce build is a little bit more complex, but the MSI build failed.  After thoroughly checking all settings in the Setup project, I couldn’t figure out why it was failing.  The only reason in the BuildLog.txt was EXEC : error : Unable to update the dependencies of the project.  Could the message be a bit more vague, please?

After searching the web, it seemed others were having the same problem.  The workarounds suggested on that page didn’t work for us.  So instead of waiting around, we decided to open up a support ticket, which our contact at Microsoft is currently looking into.  I had a feeling that Interop assemblies in our project might be causing the problem, but it wasn’t until today that my suspicion was gaining ground.  We have a few projects that have MSI builds, so I went ahead and converted and built those out.  What do you know?  The MSI builds that don’t have Interop assemblies build fine on our build machine.  We’re still waiting for a real solution to this problem, until then, we’re building the MSI package locally for that one project.

Another one of our builds has unit tests.  I ran this project’s build without the unit tests first and it completed.  I then ran the build with the unit tests and 99.9% of the unit tests failed, but not all of them, which was weird to me.  These unit tests passed completely when we were using VS2008, so maybe the MSTest reference needed to be updated or something.  I searched MSDN and found this post about the same exact issue we were having.  I tried the solutions suggested, but they didn’t work.  There were some other odd issues with the build with the unit tests, so I just decided to delete the workspace associated with that build.  After I did this, the unit tests passed and everything looked good.

I hope when we upgrade our TFS2008 to TFS2010, that there aren’t going to be more issues.  I have my fingers crossed…

Monday, April 27, 2009

Visual Studio Unit Testing – System.TypeLoadException

So I was trying to write unit tests today and I ran into quite a weird issue.  My test failed on a simple constructor test.  When I looked at the error message I noticed something odd: 

VersionErrorMessage

The referenced assembly version in the picture is x.x.x.91, but the current version it should be is a later version.  What gives?  I tried creating a new unit test project because I thought maybe our unit test project got messed up somehow, but the same error message kept on happening.  Another frustrating issue was that when I ran the unit test in debug mode, it passed correctly. 

After some searching on the web I ran into this page, which led me to check the project’s code coverage instrumentation section.  Sure enough, the project was pointing to an assembly that no longer existed.  The red one was the non-existent assembly, the green one is the correct one.

WrongArtifact

My guess as to why this happened was because initially, the solution was setup to build against Any CPU and this was changed to x86 somewhere along the way.  The LocalTestRun.testrunconfig probably never got updated.  After pointing to the correct assembly, the test passes and no odd version issues exist. 

Incidentally, I asked Greg if his laptop ran into some slowness lately because my hard drive would thrash and adding unit tests literally took me longer than 5 minutes via right-click.  Correcting the instrumented assembly corrected this issue as well.  One would think that Visual Studio would let the user know that something was up :)

Tuesday, December 9, 2008

Visual Studio Unit Testing – Reducing Redundant Tests

When I first started unit testing, I tested as many methods as I could.  These included public and private ones.  A bit of searching on the web about public versus private method testing will yield mixed results.  I personally test both since I aim for at least 70% code coverage.  Visual Studio creates Accessor classes for private methods and properties for you so testing private methods is easy.

I used to write at least one test per method (some require more than one to test conditional code paths), but this can get redundant.  The steps I take to reduce redundancy today are as follows.  First, I turn on code coverage.  This will give a visual indicator of what has been covered in my classes. 

SetCodeCoverage

SetCodeCoverage2

When I run my tests, code that has been covered is in blue and the code that hasn’t been covered is in red.

bluered

I test my constructors first, then public methods, and finally private methods.  Doing it in this order gives me a better idea of what private methods need to be tested.  Most of the time public methods will call private methods so writing a single test will cover those methods as well.  I collapse whatever has been covered each time I create and run a test.  Doing my tests this way has greatly reduced the number of redundant tests written and has kept the same amount of code coverage.

Thursday, July 24, 2008

Visual Studio and Data Driven Unit Tests

Unit testing can be tedious when you have a battery of data to test against.  If you’re just testing against a small number of different data, then using Data Driven Unit Tests might be a bit overkill.  However, Data Driven Unit Tests gives you is a single location of data that can be used throughout your unit testing project.  Instead of modifying the data you typed in your unit test code, you can just modify it in your data file.  I used this MSDN entry as a starting point.

The method we’ll be testing is shown below.

Public Function SomeMethod(ByVal data As String) As Integer
   Return data.Length
End Function

You create the unit test for SomeMethod as usual.  Now what about our data file?  I’ll use an XML data file that just holds a few strings named test.xml.

<Samples>
    <Sample0>My Sample</Sample0>
    <Sample1>This is another sample</Sample1>
</Samples>

Now you have your simple data file.  To hook it into your unit test project, open up the Test List Editor in Visual Studio.  Find the test that you want to use test.xml with and click on that test.

testlisteditor

In the Properties, find the Data Connection String entry and press the ellipses button.  This will bring up the New Test Data Source Wizard.

properties

wizard1

Select XML File and press Next to bring up the next screen.  Press the ellipses button and find test.xml.  This should fill in Table and Preview data for you.

wizard2

Pressing Next will bring you to the final page of the wizard.  Highlight the table and press Finish.

wizard3

You’ll see a dialog after the previous step.  Press Yes and Visual Studio will add test.xml to your unit test project.

wizarddialog

dataadded

If you look at your Data Connection String property, it should now point to test.xml within your unit test project.  The next step is using the data in your unit test.  Here’s a simple example of how to use your data.

<DataSource("Microsoft.VisualStudio.TestTools.DataSource.XML", "|DataDirectory|\test.xml", "Samples", DataAccessMethod.Sequential)> _
<DeploymentItem("TestProject1\test.xml")> _
<TestMethod()> _
Public Sub SomeMethodTest()
  Dim target As Form1 = New Form1
  Dim data As String = String.Empty

  Assert.IsTrue(target.SomeMethod(TestContext.DataRow("Sample0")) = TestContext.DataRow("Sample0").ToString.Length)
End Sub

The attributes for SomeMethodTest get automatically added when you add test.xml to your Data Connection String property.  The main point here is that TestContext.DataRow() is used to access your data.

One issue that I’ve run into was that I wanted to move my data into a sub folder called Data within my unit test project.  This will work, but the path to test.xml is a hard path.  Why does this matter?  I’m part of a team and having a hard path breaks the unit test since not all of our workspace paths are the same.  If you look at the Data Connection String property, you’ll notice that |DataDirectory| is at the beginning before the xml file location.  This transfers fine over different workspaces, however you’ll have to leave the data file where it gets inserted into the project by default.

Tuesday, April 15, 2008

Unit Testing (Part 2)

Our team aims for at least 70% code coverage with our unit tests.  I've read that quite a few people only test public methods as the private methods will eventually be reached this way. From my experience this isn't always the case.

We use Visual Studio 2008's built in unit testing framework.  The nice thing about this framework is that it's integrated into the IDE and simply right-clicking on a method or class will bring up options to create unit tests.  Along with this, accessor classes are created so that you have access to private fields and methods.

I test both public and private methods just to be exhaustive. Sometimes I run into conditional statements that I can't test fully without the class accessors.  I've hit 80%+ code coverage on my current project, but I will be looking into white to test the UI in my project as well. This will certainly boost code coverage.

Order matters in unit tests.  For example, I have classes that depend on other classes to work.  The unit test stubs that get inserted by the IDE do not account for this, it merely gives you a very trivial skeleton.  It is up to you to make sure that you have all of the dependent classes instantiated before testing the class that you actually want to test.

Monday, April 14, 2008

Unit Testing (Part 1)

I've heard about unit testing before I started here at KPMG, but had zero experience with it.  My software developer friends have experience with unit testing because most of them are part of huge development teams and deal with mission critical software.  I understood the concept, but really didn't understand its value... until I added unit testing to my current project.

I'll be honest, I don't find writing unit tests fun.  I'd much rather be developing new stuff or even fixing bugs, but I found numerous bugs that I wouldn't have found without unit tests. Users would most likely have found these bugs while using the application which would require tracking the issue, fixing the problem, testing the solution, and finally releasing a new version.  This is a lot of time (and money) wasted.