Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#

Automatic C# Unit Tester

3.33/5 (3 votes)
17 May 2012CPOL2 min read 39.1K   785  
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)