Click here to Skip to main content
15,867,141 members
Articles / Programming Languages / C#

Automatic C# Unit Tester

Rate me:
Please Sign up or sign in to vote.
3.33/5 (3 votes)
17 May 2012CPOL2 min read 38.1K   781   8   9
This automatic unit tester written in C# uses Black Box testing strategy to test a source code.

Introduction

A unit testing is a method by which individual units of source code are tested to determine if they are fit for use. A unit is the smallest testable part of an application. Unit is often an entire interface, such as a class, but could be an individual method. Unit tests are created by programmers or occasionally by white box testers during the development process. This Automatic unit tester written in C# uses Black Box testing strategy to test a source code.

Automatic Unit Tests are tests that take parameters. Unlike traditional unit tests, which are usually closed methods, it takes any set of parameters. Suitable parameters for the unit tests supplied are automatically generated by the Automatic Unit Tester classes.

Automatic Unit Tests are tests that take parameters. Unlike traditional unit tests, which are usually closed methods, it takes any set of parameters. Suitable parameters for the unit tests supplied automatically generated by the Automatic Unite Tester classes.

Background

Automated unit test suite reduces the need for manual testing. Some manual testing will always be needed because humans excel at discovering bugs that involve complex data and workflow processes. Automatic Unit tester works on two level of testing, first is automatic compile time testing and second is runtime testing of all methods with custom user inputs, then a DLL will be generated for the test class.

Compiler.cs: This class is used to compile a source code and generate respective DLLs.

C#
public string GetDll(string filepath)
{
   int x = 0;
   Test ts = new Test();
   CSharpCodeProvider codeProvider = new CSharpCodeProvider();
   ICodeCompiler icc = codeProvider.CreateCompiler();
   string[] assemblyReferences = new string[9] { "System.dll", 
     "System.ServiceProcess// .dll", "System.Xml.dll", 
     "System.Windows.Forms.dll", "System.Drawing.dll", 
     "System.Deploymen// t.dll", "System.Data.dll", 
     "System.Web.dll", "System.Web.Services.dll" };
   int len = assemblyReferences.Length + refer.Length;
   string[] newassemblyReferences = new string[len+1];
   
   foreach (string sr in assemblyReferences)
   {
       newassemblyReferences[x] = sr;
       x++;
   }
   foreach (string sr in refer)
   {
       newassemblyReferences[x] = sr;
       x++;
   }
   CompilerParameters parameters = new CompilerParameters(newassemblyReferences);
   parameters.GenerateExecutable = false;
   parameters.OutputAssembly = filepath.Substring(0,(filepath.Length-3))+"_Anup.dll";

   CompilerResults results = icc.CompileAssemblyFromFile(parameters,filepath);

   if (results.Errors.Count > 0)
   {
      foreach (CompilerError CompErr in results.Errors)
      {
         errors = errors +
           "Line number " + CompErr.Line +
           ", Error Number: " + CompErr.ErrorNumber +
           ", '" + CompErr.ErrorText + ";" +
           Environment.NewLine + Environment.NewLine;
     }
     return "error";
  }
  else
    return filepath.Substring(0, (filepath.Length - 3)) + "_Anup.dll";} 

Runner.cs: Class for method execution from generated DLL.

C#
public class Runner
{
   public static string[] status;
    public static string[] results;
   public static string errors;
   public static object[,] paramet;
   public static bool Errorstatus = false;
   public static string connString;
   public static void run(Assembly asm)
   {
       Info f = new Info();
      
       foreach (Type type in asm.GetTypes())
       {           
           if (type.IsClass == true)
           {
               object iObject = Activator.CreateInstance(type);
              FieldInfo[] ffi = type.GetFields(BindingFlags.Public 
            | BindingFlags.Instance);
              object obj = "anup";
              bool a = true;
              int b = 123;
              string c = "Er.ANUP";
              float d = 1.1F;
              double e = 2.2;
              DateTime dd = DateTime.Parse("11/11/2002");
              for (int i = 0; i < ffi.Length; i++)
              {
                  try
                  {
                      if (ffi[i].FieldType == typeof(object))
                      {
                          ffi[i].SetValue(iObject, obj);
                          continue;
                      }
                      if (ffi[i].FieldType == typeof(bool))
                      {
                          object oo = (object)a;
                          ffi[i].SetValue(iObject, oo);
                          continue;
                      }
                      if (ffi[i].FieldType == typeof(Int32))
                      {
                          object oo = (object)b;
                          ffi[i].SetValue(iObject, oo);
                          continue;
                      }
                      if (ffi[i].FieldType == typeof(String))
                      {
                          object oo = (object)c;
                          ffi[i].SetValue(iObject, oo);
                          continue;
                      }
                      if (ffi[i].FieldType == typeof(float))
                      {
                          object oo = (object)d;
                          ffi[i].SetValue(iObject, oo);
                          continue;
                      }
                      if (ffi[i].FieldType == typeof(double))
                      {
                          object oo = (object)e;
                          ffi[i].SetValue(iObject, oo);
                          continue;
                      }
                      if (ffi[i].FieldType == typeof(DateTime))
                      {
                          object oo = (object)dd;
                          ffi[i].SetValue(iObject, oo);
                          continue;
                      }
                      if (ffi[i].FieldType == typeof(OleDbConnection))
                      {
                          new ConnectionDialogBox().ShowDialog();
                          OleDbConnection db = new OleDbConnection(connString);
                          ffi[i].SetValue(iObject, db);
                          continue;
                      }
                  }
                  catch (Exception ex)
                  {
                      System.Windows.Forms.MessageBox.Show(
                        "Error in the Assignment of Public DataTypes Variables!!!!!");
                  }
              }
              int aa = 0;
              foreach(MethodInfo m in f.GetMethodsName(type))
              {
                   if (m.ToString() == "System.Type GetType()" && 
                       m.ToString() == "Int32 GetHashCode()" && 
                       m.ToString() == "System.String ToString()" && 
                       m.ToString() == "Boolean Equals(System.Object)")
                   {
                       continue;
                   }
                   Test.mess = m.Name;
                   status = new string[f.GetMethodsName(type).Length];
                   results = new string[f.GetMethodsName(type).Length];
                   ParameterInfo[] p = f.GetParameterinfo(m);
                   object[] o = new object[p.Length];
                   paramet = new object[f.GetMethodsName(type).Length,p.Length];
                   int x = -1;
                   foreach(ParameterInfo pp in p)
                   {
                       x++;
                       if (pp.ParameterType == a.GetType())
                       {
                          
                            o[x] = (object)a;
                           paramet[aa,x] = (object)a;
                            continue;
                       }
                       if (pp.ParameterType == obj.GetType())
                       {
                           
                           o[x] = obj;
                           paramet[aa, x] = obj;
                           continue;
                       }
                       if (pp.ParameterType == b.GetType())
                       {
                          
                           o[x] = (object)b;
                           paramet[aa,x] = (object)b;
                           continue;
                       }
                       if (pp.ParameterType == c.GetType())
                       {
                           o[x] = (object)c;
                           paramet[aa,x] = (object)c;
                           continue;
                       }
                       if (pp.ParameterType == d.GetType())
                       {
                           o[x] = (object)d;
                           paramet[aa,x] = (object)d;
                           continue;
                       }
                       if (pp.ParameterType == e.GetType())
                       {
                           o[x] = (object)e;
                           paramet[aa,x] = (object)e;
                           continue;
                       }
                       if (pp.ParameterType == dd.GetType())
                       {
                           o[x] = (object)dd;
                           paramet[aa,x] = (object)dd;
                           continue;
                       }   
                   }
                   try
                   {
                      type.InvokeMember(m.Name,
                                BindingFlags.Default | BindingFlags.InvokeMethod,
                                null,
                                iObject,
                                o);
                    
                      results[aa] = m.ToString()+"   :   "+"OK";
                      status[aa] = "OK";
                   }
                   catch(Exception ex)
                   {
                      results[aa] = m.ToString() + "   :   " + ex.InnerException.Message;
                      Errorstatus = true;
                      status[aa] = "Error";
                   }
                   errors = errors + Environment.NewLine  + "\n "+results[aa] + Environment.NewLine ;
                   aa++;  
               }
           }
       }
}

Test.cs: Dynamic code execution engine...

C#
Info i = new Info();
Compiler comp = new Compiler();

spanel.Refresh();
msglabel.Text = "Reading Namespace........ ";
spanel.Refresh();

msglabel.Text = "Reading Class.......";
spanel.Refresh();
     
msglabel.Text = "Compiling Class..........";
spanel.Refresh();
string temp = comp.GetDll(filepath);
if (temp == "error")
{
   status = "Compile Error";
   flag = true;
   return;
}
else
{
   filepath = temp;
   status = "Compiled Successfully";
}
           
msglabel.Text = status;
spanel.Refresh();
msglabel.Text = "Loading Assembly in Memory...........";
spanel.Refresh();
Assembly am =  Assembly.LoadFrom(filepath);
msglabel.Text = "While Executing Please Wait........";
spanel.Refresh();
Runner.run(am);
foreach (Type tt in am.GetTypes())
{
   MethodInfo[] mm = i.GetMethodsName(tt);
  
   foreach (MethodInfo mmm in mm)
   {
       if (mmm.ToString() != "System.Type GetType()" && 
            mmm.ToString() != "Int32 // GetHashCode()" && 
            mmm.ToString() != "System.String ToString()"&& 
            mmm.ToString() != "Boolean // Equals(System.Object)")
       methodsname = methodsname + Environment.NewLine + mmm.ToString() + Environ// ment.NewLine;      
   }
   foreach (FieldInfo fi in tt.GetFields(BindingFlags.Public | 
            BindingFlags.Instance))
   {
       fieldsname = fieldsname + Environment.NewLine + fi.ToString() + Environmen// t.NewLine;
   }
}

Summary

The recipe for better software with less people is simple: unit test early, unit test often, and refactor when needed. Unit tests find problems automatically, early and will never grow tired of testing the same feature again and again.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) NIC
India India
I have more then 5 years of experience in the software development sectors with more then 15 softwares in C#, WPF, SQL SERVER, WCF, LINQ, intel perceptual computing sdk, digital signature, snmp.

Comments and Discussions

 
GeneralGreat idea Anup ! Pin
Slawek30720-Jan-17 4:05
Slawek30720-Jan-17 4:05 
QuestionInfo Class Pin
bhagya@036-Jan-13 19:18
bhagya@036-Jan-13 19:18 
What Info Class contains?
Questionwhat is info class Pin
supriya293-Jan-13 18:41
supriya293-Jan-13 18:41 
QuestionMy example based on yours Pin
Jukka Aakula13-Jun-12 21:36
Jukka Aakula13-Jun-12 21:36 
QuestionYou should clarify the code more using prosa text. Pin
Jukka Aakula10-Jun-12 23:41
Jukka Aakula10-Jun-12 23:41 
SuggestionNeeds more comments Pin
Shahin Khorshidnia26-May-12 20:32
professionalShahin Khorshidnia26-May-12 20:32 
GeneralMy vote of 1 Pin
Vijay Gill11-May-12 4:02
professionalVijay Gill11-May-12 4:02 
GeneralRe: My vote of 1 Pin
Anup Kumar Verma16-May-12 19:51
Anup Kumar Verma16-May-12 19:51 
GeneralRe: My vote of 1 Pin
Vijay Gill30-May-12 3:38
professionalVijay Gill30-May-12 3:38 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.