ExtremeSwat
ExtremeSwat

Reputation: 824

Method for a try-catch C#

I have a small issue, I have to try-catch each recorded method that I am currently using ( Coded UI Test project ) in order to generate a txt file where I see the results of the test. This is how it looks like :

[TestMethod(), TestCategory("Actions"), TestCategory("DataDriven"), DataSource("Microsoft.VisualStudio.TestTools.DataSource.CSV", @"|DataDirectory|\Actiuni\actions.csv", "actions#csv", DataAccessMethod.Sequential), DeploymentItem(@"..\Actiuni\actions.csv")]
public void ActionsInsertDataDrivenTest()
{
    methodNumber = 6;
    methName = "ActionsInsertDataDrivenTest";
    firstTime = true;
    var actionTest = new ActionsMap();

    //open actions
    try
    {
        actionTest.ActionsOpen();
        listaObj.Add("ActionsOpen()", "Passed ! ");
    }
    catch (Exception e) 
    {
        validator = false;
        listaObj.Add("ActionsOpen()", "Failed: " + e.Message);
    }
    //remove collumns
    try
    {
        actionTest.Actions_header_remove_colls();
        listaObj.Add("Actions_header_remove_colls()", "Passed ! ");
    }
    catch (Exception e)
    {
        validator = false;
        listaObj.Add("Actions_header_remove_colls()", "Failed: " + e.Message);
    }
   //click grid
    try
    {
        actionTest.Actions_click_insert_header();
        listaObj.Add("Actions_click_insert_header()", "Passed !");
    }
    catch (Exception e)
    {
        validator = false;
        listaObj.Add("Actions_click_insert_header()", "Failed : " + e.Message);
    }

My only problem is the fact that I have repetitive code, the fact that I have to try-catch each method is a pain, so I thought about making a void method that can do this automatically for me, but I am failing to do it.

void tryCatch(ActionsColMap object1, (methodofobject1), Boolean a, Boolean b{
}

the thing is that I have no idea how to pass a method to this function, it's a coded-ui-test method which can be invoked using the object1. Is there any way to do it ? I've failed trying with Action() [for void methods]

TestCleanup + Asserts

[TestCleanup]
public void TestCleanup()
{
    string path = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
    string date = DateTime.Now.ToString("MM-dd-yyyy");
    string realName = methodName + "_" + date + "_" + "Test";
    string fullPath = path + @"\" + realName + ".txt";


    if (!File.Exists(fullPath))
    {

        // using (System.IO.StreamWriter file = new System.IO.StreamWriter(path + @"\testDoc.txt"))
        using (System.IO.StreamWriter file = new System.IO.StreamWriter(fullPath))
        {

            file.WriteLine("Test: " + methodName);
            //file.WriteLine("Full Class Name: " + TestContext.FullyQualifiedTestClassName + " Method name: " + methName);
            //file.WriteLine("Date: " + DateTime.Now.ToString("MM-dd-yyyy HH:mm ss tt "));
            file.WriteLine(" ");

        }
    }
    else
    {
        //firstTime = true;
        // firstCounter = 0;

    }

    //XML decl---


    //-----------------------

    var lv1s = from lv1 in xDoc.Descendants("codedUITest")
               where lv1.Attribute("name").Value.Contains(methName)
               select new
               {
                   //Header = lv1.Attribute("name").Value,
                   Children = lv1.Descendants("description")
               };


    foreach (var lv1 in lv1s)
    {

        foreach (var lv2 in lv1.Children)
        {
            result.Clear();
            result.Append(lv2.Attribute("name").Value);
            list.Add(result.ToString());

        }
        // file.WriteLine(result);


    }

    //-------------------------------

    foreach (KeyValuePair<string, string> testMethod in listaObj)
    {
        counter++;
        //listaObj2 = listaObj;

        // MessageBox.Show(counter.ToString());


        using (System.IO.StreamWriter file = new System.IO.StreamWriter(fullPath, true))
        {

            if (firstTime == true && firstCounter == 0)
            {
                file.Write(" ");
                file.WriteLine("Full Class Name: " + TestContext.FullyQualifiedTestClassName + "Method Name: " + methName);
                file.WriteLine("Date: " + DateTime.Now.ToString("MM-dd-yyyy HH:mm ss tt "));
                file.WriteLine(" ");
                firstTime = false;
                firstCounter++;
            }



            // file.WriteLine(testMethod);

            for (; listCounter < list.Count; )
            {
                //  file.WriteLine(testMethod + " -- > " + list[listCounter]);
                file.WriteLine("-----" + list[listCounter]);
                file.WriteLine(testMethod);
               // file.WriteLine(" ");
                listCounter++;
                break;
            }


            if (counter % methodNumber == 0)
            {
                if (counter != methodNumber)
                {
                    file.WriteLine("Phase " + secondCounter.ToString() + " complete ! -----------------");
                    file.WriteLine(" ");

                    //Delete all this  block in case of problems--------

                    counter = 0;
                   // firstCounter = 0;
                   // secondCounter = 0;
                    listCounter = 0;
                    list = new List<string>();
                    listaObj = new Dictionary<string, string>();

                    //---------------------------------------------------------
                    //---------------------------------------------------------

                }
                else
                {
                    file.WriteLine("Phase " + secondCounter.ToString() + " complete ! -----------------");
                    file.WriteLine(" ");
                    // file.WriteLine("Full Class Name: " + TestContext.FullyQualifiedTestClassName + "Method name: " + methName);
                    //file.WriteLine("Date: " + DateTime.Now.ToString("MM-dd-yyyy HH:mm ss tt "));
                    file.WriteLine(" ");
                }

            }
        }

    }
    //Assert if the parent test was passed or not.
    Assert.IsTrue(validator, "One or more inner tests were failed.");

}

Upvotes: 0

Views: 1617

Answers (3)

Keith
Keith

Reputation: 330

It looks like you are looking for something like this:

using System;
using System.Collections.Generic;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            List<Tuple<string, string>> results = new List<Tuple<string, string>>();
            bool validator = true;

            TryCatch(Pass, results, ref validator);
            TryCatch(Fail, results, ref validator);
        }

        private static void Pass()
        {
        }

        private static void Fail()
        {
            throw new Exception("oops");
        }

        private static void TryCatch(Action action, List<Tuple<string, string>> results, ref bool validator)
        {
            try
            {
                action();
                results.Add(Tuple.Create(action.Method.DeclaringType.FullName + "." + action.Method.Name, "Passed !"));
            }
            catch (Exception ex)
            {
                validator = false;
                results.Add(Tuple.Create(action.Method.DeclaringType.FullName + "." + action.Method.Name, "Failed : " + ex.Message));
            }
        }
    }
}

Although I might honestly not go to this trouble, and do the right thing for unit tests, which is each unit test tests one thing.

EDIT for comment:

Small issue here : the problem is that I can't call just for the void method itself, I also need a reference of an object. Something as void(Action action) { try{ myObjectReference.action(); // etc }catch(exception ex) { bool = false; //etc } }

The problem is a method in C# does not just exist by itself. A method is always defined on a type, thus MethodInfo.DeclaringType.

So to do the kind of thing you're looking for you'd have to write awkward code like:

void TryCatch(object thing, Action action)
{
   action.Method.Invoke(thing);
}

You'd then have to handle the case where you are trying to call a method defined on Foo when thing is actually an instance of Bar that doesn't have the method. You will get an exception then. It's also really strange since the action parameter already carries with it the instance if there is one, and you're ignoring it, so a more correct answer might be:

void TryCatch(object thing, MethodInfo method)
{
   method.Invoke(thing);
}

As that doesn't carry information with it that you blatantly ignore, but then the caller is having to do the reflection to find the method, and if that method isn't on the object you pass in, you still have problems.

My original answer is relatively safe, in that it should always have an unambiguous answer to what needs to be called, trying to separate the instance (and potentially type) you are trying to call a method on, and what method you are trying to call is always going to leave you with problems you have to resolve.

It feels like you're trying to treat it as a type-less language, and it isn't. The types matter.

Upvotes: 3

weston
weston

Reputation: 54781

These should be separate tests, but you should have some asserts, otherwise these tests would pass with just empty methods.

private ActionsMap actionTest;

[TestInitialize]
public void Setup()
{
  actionTest = new ActionsMap();
}

[TestMethod]
public void can_open()
{
  actionTest.ActionsOpen();
  //asserts?
}

[TestMethod]
public void can_remove_header_columns()
{
  actionTest.ActionsOpen(); //assuming next method depends on this
  actionTest.Actions_header_remove_colls();
  //asserts?
}

[TestMethod]
public void can_insert_header_column()
{
  actionTest.ActionsOpen(); //assuming next method depends on this
  actionTest.Actions_header_remove_colls(); //assuming next method depends on this
  actionTest.Actions_click_insert_header();
  //asserts?
}

Upvotes: 1

Neel
Neel

Reputation: 11731

Well I guess all you need is method name which causes the exception so you can make it like as below :-

You require TargetSite for fetching the method that is causing the exception

//open actions
            try
            {
                actionTest.ActionsOpen();
                listaObj.Add("ActionsOpen()", "Passed ! ");
                actionTest.Actions_header_remove_colls();
                listaObj.Add("Actions_header_remove_colls()", "Passed ! ");
                actionTest.Actions_click_insert_header();
                listaObj.Add("Actions_click_insert_header()", "Passed !");
            }
            catch (Exception e) 
            {
                validator = false;
                MethodBase site = ex.TargetSite;
                string methodName = site == null ? null : site.Name;
                listaObj.Add(methodName, "Failed: " + e.Message);
            }

Upvotes: 1

Related Questions