How can I call the test case result on runtime to another file to update test case result in testRail?

Viewed 693

I am using MSTEST C# in selenium webdriver. Hierarchy of my project is

Level1-MainProjectfile

     Level2-Properties

     Level2-Refernces

     Level2-AppObj(folder)

               Level3-DP(folder)

                        Level4-dpo.cs

                        Level4-dpc.cs

               Level3-TestRail(folder)

                         Level4-TestRailpm.cs

                         Level4-TestRailpo.cs

               Level3-gmethods.cs

      Level2-AUtomationCode.cs

      Level2-log4net.config

Now My Unit Testcases are present in AutomationCode.cs file this is the main project file. The code in my AutomationCode.cs file is

    public class AutomationCode
    {
        private IWebDriver WDriver;
        private log4net.ILog Testlog;
    
    
        [TestInitialize]
        public void wd()
        {
            WDriver = Helper.GetWebDriver(helperconst.browserType.Chrome);
            Testlog = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
        }
        [Priority(1)]
        [TestMethod]
        public void search()
        {
            Testlog.Info("Test ID:001, This test will select the criteria and update the customer dropdown");
    
            Testlog.Info("Step 1/1 : Select customer from cutomer dropdown");
            var dc = gmethods.GetSelectElement(WDriver, dpo.customermenu);
            dc.SelectByText(dpc.customer);
        }
///[Ignore]
        [Priority(2)]
        [Microsoft.VisualStudio.TestTools.UnitTesting.TestMethod]
        public void TestRailCall()
        {
            TestRailpm a = new TestRailPM();
            a.testrail();
        }

        [TestCleanup]
        public void CleanUp()
        {
            WDriver.Close();
            WDriver.Quit();
        }
    }

In dpo page:

public static class dpo
{
    public const string customermenu = "[data]";
}

In dpc page

public static class dpc
{
    public const string customer = "A";
}

In gmethods page:

static public SelectElement GetSelectElement(IWebDriver drv, string elem)
{
    SelectElement a = new SelectElement(drv.FindElement(By.CssSelector(elem)));
    return a;
}

In TestRailPO file the code is

    namespace Automation.AppObj.TestRail
{
    public class TestRailPO
    {

        public class TestResultKeeper
        {
            public static TestResult TestResult { get; set; }
            public static UnitTestOutcome TestOutcome => UnitTestOutcome.Failed;

            //TestResult ?? Outcome ?? UnitTestOutcome.Failed;

            public static bool IsPassed => TestOutcome == UnitTestOutcome.Passed;
            public static Exception Exception { get; set; }

            
        }

        public class TestMethodAttribute : Attribute
        {
            public virtual TestResult[] Execute(ITestMethod testMethod)
            {
                return new TestResult[] { };
            }
        }

        public class LogTestTestMethod : TestMethodAttribute
        {

            public override TestResult[] Execute(ITestMethod testMethod)
            {
                var testResult = base.Execute(testMethod)[0];

                TestResultKeeper.TestResult = testResult;
                //TestResultKeeper.Exception = testResult.TestFailureException;

                return new[] { testResult };


            }

        }
    }

In testrailpm.cs code is :

public class TestRailPM
{

   
    string testRailUrl = "https://test.testrail.io/";
    string testRailUser = "test@gmailcom";
    string testRailPassowrd = "test";
    int projectId = 1;
    int milestoneId = 1;
    int suiteId = 1;
    int testRailUserId = 1;
    string[] testCaseIds = { "12345", "21343" };


    public void testrail()
    {
        //Create Test Run in TestRail
        //Pass "true" against 'includeAll' parameter to insert all test cases in a suite; "false" to add specific test case id
        string testRunID = CreateTestRun.CreateRun(testRailUrl, testRailUser, testRailPassowrd, projectId, suiteId, milestoneId, "Automation of TestCases", "Automation of TestCases", testRailUserId, false, testCaseIds);
        int testRunIdInInt = Convert.ToInt16(testRunID);

        //Get TestCases Ids of a Run

        int[] newTestRunCaseIds = GetTestCases.getTestCaseIds(testRailUrl, testRailUser, testRailPassowrd, testRunIdInInt, true);
        int[] originalTestCaseIds = GetTestCases.getTestCaseIds(testRailUrl, testRailUser, testRailPassowrd, testRunIdInInt, false);

        //Add Result for Single Test Case in a Test Run
        /* testCaseStatus int The ID of the test status. The built-in test rail statuses have the following IDs:
        1 Passed
        2 Blocked
        3 Untested (not allowed when adding a result)
        4 Retest
        5 Failed
        */


        int singleTestCaseId = 716869;
        UpdateTestRun.updateSingleTestCaseInATestRun(testRailUrl, testRailUser, testRailPassowrd, testRunIdInInt, singleTestCaseId, TestContext.CurrentTestOutcome == UnitTestOutcome.Passed ? 1 : 5, "testCaseComments", testRailUserId);


        /*
        // Add Result for Multiple Test Cases in a Test Run at a time
        int[] testCaseIdsToUpdateResults = { 584003, 584004, 584005, 584006, 584007, 584008, 584009, 584075, 584076, 584213, 604458, 716869, 716870, 716871, 716872};
        int[] testCaseStatuses = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
        string[] testCaseComments = { "This case is passed", "This case is passed", "This case is passed", "This case is passed", "This case is passed", "This case is passed", "This case is passed", "This case is passed", "This case is passed", "This case is passed", "This case is passed", "This case is passed", "This case is passed", "This case is passed", "This case is passed"};
        UpdateTestRun.UpdateTestRunResults(testRailUrl, testRailUser, testRailPassowrd, testRunIdInInt, newTestRunCaseIds, testCaseStatuses, testCaseComments, testRailUserId);
        */


    }


}

I am using MStest C#. All I want is to Run my main project file that is AutomationCode.cs and the result of test case that would be "Pass/Fail" will get saved in a variable or attribute etc that is in TestRailpo.cs file testkeeperresult or any other attribute. Of course, the result saved would be either pass or fail but here is the main thing. I need to pass that result in the form of numbers that is 1 or 5. 1 for pass and 5 for Fail. That result I need to pass in TestRailpm.cs file in Resultoftestcase.

UpdateTestRun.updateSingleTestCaseInATestRun(testRailUrl, testRailUser, testRailPassowrd, testRunIdInInt, singleTestCaseId, Resultoftestcase, "testCaseComments", testRailUserId);
           }

I have called the TestRail() method from TestRail.pm file to AutomationCode.cs before testcleanup because I want to update TestRail after my unit test cases are executed. Keeping in view of my detailed description kindly help me in code to pass the result in the form of 1 or 5 in testRail.pm file. Please guide me how can I do that and what changes would be required?

2 Answers

In principal this is the same question you asked here and here

This is the answer given...

For NUnit you can access the result and other details of the test using properties found in TestContext.CurrentContext.

For your problem you can add the following check to the test teardown method

if(TestContext.CurrentContext.Result.Outcome.Status == TestStatus.Passed) { .... }

For MSTest add the following property to your test class

public TestContext TestContext { get; set; } 

Then use it by adding the following to TestCleanup

if(TestContext.CurrentTestOutcome == UnitTestOutcome.Passed) { .... }

Please add a test context property in you automationcode class, something like below :

public class AutomationCode
    {
        private IWebDriver WDriver;
        private log4net.ILog Testlog;
        public TestContext TestContext { get; set; }
    }

Now add the below code in your cleanup() method call the method which will update the test result in TestRail. Something like this :

[TestCleanup]
        public void CleanUp()
        {
            WDriver.Close();
            WDriver.Quit();

            TestRailpm a = new TestRailPM();

            if (TestContext.CurrentTestOutcome.Equals(UnitTestOutcome.Passed))
            {
                UTestResultKeeper.TestResult.Outcome = UnitTestOutcome.Passed;
                a.Resultoftestcase = "1";

            }
            else if (TestContext.CurrentTestOutcome.Equals(UnitTestOutcome.Failed)|| TestContext.CurrentTestOutcome.Equals(UnitTestOutcome.Timeout)|| TestContext.CurrentTestOutcome.Equals(UnitTestOutcome.Inconclusive))
            {
                TestResultKeeper.TestResult.Outcome = UnitTestOutcome.Failed;
                a.Resultoftestcase = "5";
            }
            //now that TestReultKeeper is updated wi can call the API method to update the test rail
            a.testrail();
        }

I am not sure if TestRailpm.Resultoftestcase property can be accessed or not as you have not shared the whole code but I have called it directly to update the property and later update the result in Testrail.

Let me know If this does not work for you, I have a simpler way of updating the testresult in testrail using the same testrail API.

The Simpler way to achieve this is downloading TestRail API Client from here and then updating the testrail test cases using the test rail API

 public class UpdateTestResult
{
    /// <summary>
    /// Update the test result in testrail
    /// </summary>
    /// <param name="serverUrl">e.g. "http://<server>/testrail/</param>
    /// <param name="userName">username to be used</param>
    /// <param name="userPassword">password of the user</param>
    /// <param name="testCaseID">testrail test case ID</param>
    /// <param name="testResult">stauts of the test. e.g. :1 is passed and 5 is failed.</param>
    public void UpdateResultInTestRail(string serverUrl, string userName, string userPassword, string testCaseID, int testResult)
    {
        APIClient client = new APIClient("http://<server>/testrail/") { User = "userName", Password = "userPassword" };

        var data = new Dictionary<string, object>
                            {
                                { "status_id", testResult },
                                { "comment", "This test worked fine!" }
                            };

        client.SendPost("add_result/:"+ testCaseID, data);
    }
}

And now you can call this class method in cleanup method of the test method. Something like this :

        [TestCleanup]
    public void CleanUp()
    {
        UpdateTestResult updateResult = new UpdateTestResult();
        if (TestContext.CurrentTestOutcome.Equals(UnitTestOutcome.Passed))
        {
            updateResult.UpdateResultInTestRail("serverUrl", "username", "Password", "testcaseID", 1);
        }
        else if (TestContext.CurrentTestOutcome.Equals(UnitTestOutcome.Failed)|| TestContext.CurrentTestOutcome.Equals(UnitTestOutcome.Timeout)|| TestContext.CurrentTestOutcome.Equals(UnitTestOutcome.Inconclusive))
        {
            updateResult.UpdateResultInTestRail("serverUrl", "username", "Password", "testcaseID", 5);
        }
    }

To learn more about testrail API you can refer this link. For API results you can even refer this link.

Related