Friday 6 May 2011

Assert two screenshots hack in Visual Studio Test

Here’s a workaround I came up with when trying to find a way to have visual comparisons during some of my tests. I’m using the free screenshot program Greenshot available from here to take care of my screenshots.

I set up Greenshot to dump a full screenshot automatically to a folder on each of my test machines without opening the image, here’s the settings I used:

GreenShot Settings1GreenShot Settings2

During the test run Greenshot will snap a full desktop image and dump it to a directory on the test machine, I’ll later crop the image during the test and compare. 


Comparing screenshots

Inside of the test file I have 2 Bitmap images, 1.bmp which is my baseline image and the dynamic screenshot(2.bmp) of my application taken during the test(this screenshot is also taken during the test using the Greenshot hotkey control+Print Screen in my app window).


CheckImages.cs file:

 //images to compare after taking screenshot  
 //baseline  
 Bitmap bmp1 = new Bitmap(@"C:\Dev\1.bmp");  
 //new screenshot  
 Bitmap bmp2 = new Bitmap(@"C:\Dev\2.bmp");  
 //crop the image x, y, width, height and then compare  
 Bitmap cropbmp1 = ComparingImages.CropBitmap(bmp1, 220, 200, 600, 200);  
 Bitmap cropbmp2 = ComparingImages.CropBitmap(bmp2, 220, 200, 600, 200);  
 ComparingImages.Compare(cropbmp1, cropbmp2);  



Cropping The Image

I found a simple function to crop the image, In my case I’m interested in a screenshot of a grid full of data.



 public Bitmap CropBitmap(Bitmap bitmap, int cropX, int cropY, int cropWidth, int cropHeight)  
 {  
 Rectangle rect = new Rectangle(cropX, cropY, cropWidth, cropHeight);  
 Bitmap cropped = bitmap.Clone(rect, bitmap.PixelFormat);  
 return cropped;  
 }  


Comparing The Hash

I found some code here which works perfectly for taking the two images and comparing the Hash of each, you can read more on the details of how it works here, I’m just happy that it works.


CompareHash.cs file:
 using System;  
 using System.Collections.Generic;  
 using System.Linq;  
 using System.Text;  
 using System.Drawing;  
 using System.Security.Cryptography;  
 using Microsoft.VisualStudio.TestTools.UITesting;  
 using Microsoft.VisualStudio.TestTools.UnitTesting;  
 using Microsoft.VisualStudio.TestTools.UITest.Extension;  
 using Keyboard = Microsoft.VisualStudio.TestTools.UITesting.Keyboard;  
 namespace CoreTestAutomation.Extended_Tests.Screen_Checks  
 {  
   public class ComparingImages  
   {  
     public static Bitmap CropBitmap(Bitmap bitmap, int cropX, int cropY, int cropWidth, int cropHeight)  
     {  
       Rectangle rect = new Rectangle(cropX, cropY, cropWidth, cropHeight);  
       Bitmap cropped = bitmap.Clone(rect, bitmap.PixelFormat);  
       return cropped;  
     }  
     public enum CompareResult  
     {  
       ciCompareOk,  
       ciPixelMismatch,  
       ciSizeMismatch  
     };  
     public static CompareResult Compare(Bitmap bmp1, Bitmap bmp2)  
     {  
       CompareResult cr = CompareResult.ciCompareOk;  
       CompareResult crmatch = CompareResult.ciCompareOk;  
         //Convert eachciCompareOk image to a byte array  
         System.Drawing.ImageConverter ic = new System.Drawing.ImageConverter();  
         byte[] btImage1 = new byte[1];  
         btImage1 = (byte[])ic.ConvertTo(bmp1, btImage1.GetType());  
         byte[] btImage2 = new byte[1];  
         btImage2 = (byte[])ic.ConvertTo(bmp2, btImage2.GetType());  
         //Compute a hash for each image  
         SHA256Managed shaM = new SHA256Managed();  
         byte[] hash1 = shaM.ComputeHash(btImage1);  
         byte[] hash2 = shaM.ComputeHash(btImage2);  
         //Compare the hash values  
         for (int i = 0; i < hash1.Length && i < hash2.Length  
                  && cr == CompareResult.ciCompareOk; i++)  
         {  
           if (hash1[i] != hash2[i])  
             cr = CompareResult.ciPixelMismatch;  
         }  
         Assert.AreEqual(crmatch, cr);  
         return cr;  
     }  
   }  
 }  


That's it, now i have a quick workaround to comparing some visual aspects of my application under test.

No comments:

Post a Comment