Question How to use aspect oriented programming concept in custom attributes to avoid writing try catch in methods

Palak Shah

Well-known member
Joined
Apr 29, 2020
Messages
88
Programming Experience
1-3
Hello Team,

In my tests, I want to introduce exception handling and if exception occurs, then to log error in extent report - So for that I'm thinking if I can use attribute using aspect oriented concept, but the only issue I'm facing is how do I access the logger, which is mentioned in different page



Logger Implementation:
public class Scenario1 : ManualRegressionSuite.Model.Abstractions.Test.TestBaseMSTestV2.TestBase
    {
        public CommonMethods CommonMethods { get; set; }
        public string countryName = "Austria";

        [TestInitialize]
        public void BeforeTest()
        {
            BaseSetup();
            CommonMethods = new CommonMethods(shared_parameters, _logger);
        }

        [TestCleanup]
        public void AfterTest()
        {
            BaseCleanUp();
        }
        [TestCategory("BOL")]
        [TestMethod]
        public void BOL_GB_3D_Product_EndToEnd_Scenario()
        {
        try{
            LineSeparatorHelper lineSeparator = GetInstance<LineSeparatorHelper>();
            lineSeparator.LineFormatter("Executing 3D Product End to End Scenario for BOL");

            _logger.Info("Reviewing Basket After updating delivery location!!");}
            catch{}
        
        }

public abstract class TestBase : Base
    {
        private ExtentReports _report;

        public List<IWebDriver> Drivers;
        public TestContext TestContext { get; set; }
        protected MasterPaths Paths { get => paths; set => paths = value; }

        private MasterPaths paths;
        private void SetupReport()
        {
            _report = ReportSingleton.GetInstance();
            _logger = _report.CreateTest(TestContext.TestName);
        }

        public IWebDriver SetupDriver(string userAgent, SiteBag siteBag,
            TestConfigurationCDO testConfiguration, bool noLoad = false)
    

public abstract class Base
    {
        public SharedParameters shared_parameters;

        public IWebDriver Driver { get; set; }
        public ExtentTest _logger;

        protected TPage GetInstance<TPage, TArgs>(TArgs arg, IWebDriver Driver = default)
            where TPage : ConstructablePage<TArgs>, new()
        {
            TPage pageInstance = new TPage();

            if (Driver == default)
                pageInstance.Driver = this.Driver;
            else
                pageInstance.Driver = Driver;

            pageInstance.shared_parameters = shared_parameters;
            pageInstance._logger = _logger;

            pageInstance.Construct(arg);

            return pageInstance;
        }

Now tried postsharp for AOP concept


Custom Attribute:
namespace Framework.Attributes
{
    /// <summary>
    /// This attribute depicts that in method static wait is used as no other alternative was found
    /// </summary>
    [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
    public class HandleException : OnMethodBoundaryAspect
    {
        public HandleException(AventStack.ExtentReports.ExtentTest _logger )
        {

        }
        public override void CompileTimeInitialize(System.Reflection.MethodBase method, AspectInfo aspectInfo)
        {
            base.CompileTimeInitialize(method, aspectInfo);
        }
        public override void OnException(MethodExecutionArgs args)
        {
            if (args.Exception != null) { }
                //System..Info($"OnException : {(!string.IsNullOrEmpty(args.Exception.Message) ? args.Exception.Message : "")}");


            //var Message = args.Exception.Message;
            //var StackTrace = args.Exception.StackTrace;

            //_logger.Info($"Application has got exception in method-{args.Method.Name} and message is {Message}");
        }
    }
}

Now I'm not sure how can I use _logger in HandleException attribute, can someone help?
 

Skydiver

Staff member
Joined
Apr 6, 2019
Messages
3,555
Location
Chesapeake, VA
Programming Experience
10+
Well, you have this line of code in your attribute's constructor:
C#:
public HandleException(AventStack.ExtentReports.ExtentTest _logger )

I assume that you wrote that because you need the logger to be passed in to the attribute. So why don't you just grab a reference of the logger during construction, and use it later when you actually need to log something.

A couple of quick asides:
1) The normal naming convention is for public properties and fields to be in Pascal case. _logger is in camel case.
2) A lot of people use the underscore prefix as a form of Hungarian notation to indicate that the field is private or protected. You are going against this common convention by declaring _logger as a public field.
3) Something feels wrong about your application of AOP to unit tests to catch exceptions. The point of unit tests is that if a condition fails or throws an exception, it is the unit test engine that catches failure or exception and reports it. Why are you trying to do the job of the unit test engine?
 

Palak Shah

Well-known member
Joined
Apr 29, 2020
Messages
88
Programming Experience
1-3
Well, you have this line of code in your attribute's constructor:
C#:
public HandleException(AventStack.ExtentReports.ExtentTest _logger )

I assume that you wrote that because you need the logger to be passed in to the attribute. So why don't you just grab a reference of the logger during construction, and use it later when you actually need to log something.

A couple of quick asides:
1) The normal naming convention is for public properties and fields to be in Pascal case. _logger is in camel case.
2) A lot of people use the underscore prefix as a form of Hungarian notation to indicate that the field is private or protected. You are going against this common convention by declaring _logger as a public field.
3) Something feels wrong about your application of AOP to unit tests to catch exceptions. The point of unit tests is that if a condition fails or throws an exception, it is the unit test engine that catches failure or exception and reports it. Why are you trying to do the job of the unit test engine?
_logger is declared in Base class, and in scenario class I'm getting Base._logger so I'm not sure how do I pass _logger to Handle Exception
 
Top Bottom