【问题标题】:How can I call the test case result on runtime to another file to update test case result in testRail?如何将运行时的测试用例结果调用到另一个文件以更新 testRail 中的测试用例结果?
【发布时间】:2020-03-25 07:25:43
【问题描述】:

我在 selenium webdriver 中使用 MSTEST C#。我的项目的层次结构是

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

现在我的单元测试用例出现在 AutomationCode.cs 文件中,这是主项目文件。我的 AutomationCode.cs 文件中的代码是

    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();
        }
    }

在 dpo 页面中:

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

在 dpc 页面中

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

在 gmethods 页面中:

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

TestRailPO 文件中的代码是

    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 };


            }

        }
    }

在 testrailpm.cs 中的代码是:

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);
        */


    }


}

我正在使用 MStest C#。我想要的只是运行我的主项目文件 AutomationCode.cs 并且测试用例的结果将是“通过/失败”将保存在 TestRailpo.cs 文件 testkeeperresult 或任何变量或属性等中其他属性。当然,保存的结果可能是通过或失败,但这是主要的。我需要以 1 或 5 的数字形式传递该结果。1 表示通过,5 表示失败。该结果我需要在 Resultoftestcase 中传递 TestRailpm.cs 文件。

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

我在 testcleanup 之前将 TestRail.pm 文件中的 TestRail() 方法调用到 AutomationCode.cs,因为我想在执行单元测试用例后更新 TestRail。考虑到我的详细描述,请帮助我在代码中以 1 或 5 的形式在 testRail.pm 文件中传递结果。请指导我如何做到这一点以及需要进行哪些更改?

【问题讨论】:

  • 您说您正在使用 NUnit,但您的测试代码绝对不是 NUnit - 例如,它没有使用 NUnit 属性。 OTOH,您的自定义属性绝对基于 NUnit。
  • 你不能指望 NUnit 自定义属性为非 NUnit 测试做任何事情。
  • @Charlie 你能提供解决方案吗?我该怎么做?
  • @Anna 我很想回答这个问题!但是,我只能发表评论,因为您还没有明确是要使用 NUnit 还是 MsTest 框架。你不能两个都用!如果是 NUnit,请尝试使用仅使用 NUnit 的新测试代码。
  • 你的代码能编译吗?如果是这样,那么您正在引用两个测试框架。如果可以,请删除对您不想要的引用并更正任何错误。如果你最终使用 NUnit,我可以回答。如果是 MsTest,那么知道该框架的人可以试一试!

标签: c# selenium-webdriver mstest visual-studio-2019 testrail


【解决方案1】:

原则上,这与您向herehere 提出的问题相同

这是给出的答案...

对于 NUnit,您可以访问测试的结果和其他详细信息 使用 TestContext.CurrentContext 中的属性。

对于您的问题,您可以将以下检查添加到测试拆解中 方法

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

对于 MSTest,将以下属性添加到您的测试类

public TestContext TestContext { get; set; } 

然后通过将以下内容添加到 TestCleanup

来使用它
if(TestContext.CurrentTestOutcome == UnitTestOutcome.Passed) { .... }

【讨论】:

  • 如果不清楚,您可以使用拆解中的代码并在那里调用相应的函数。
  • 考虑到这一点,我已经添加了你上面提到的内容。但是如何以 1 或 5 的形式将结果传递给参数 Resultoftestcase 中的 TestRailpm.cs 文件?
  • 在测试拆解中,您调用您的方法并根据结果传入 1 或 5。因此,在测试拆解中,您可以添加 UpdateTestRun.updateSingleTestCaseInATestRun(testRailUrl, testRailUser, testRailPassowrd, testRunIdInInt, singleTestCaseId, TestContext.CurrentTestOutcome == UnitTestOutcome.Passed ? 1 : 5, "testCaseComments", testRailUserId);
  • @BoladAsLove 你能举个例子考虑我的代码如何在拆解测试中调用方法吗?
  • @Amna 我在上面的评论中举了一个例子。如果您对您无法理解的事情提出更具体的问题,我可以尝试回答。
【解决方案2】:

请在您的自动化代码类中添加一个测试上下文属性,如下所示:

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

现在在您的 cleanup() 方法中添加以下代码,调用该方法将更新 TestRail 中的测试结果。像这样的东西:

[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();
        }

我不确定是否可以访问 TestRailpm.Resultoftestcase 属性,因为您尚未共享整个代码,但我已直接调用它来更新属性并稍后在 Testrail 中更新结果。

让我知道如果这对您不起作用,我有一种更简单的方法来使用相同的 testrail API 更新 testrail 中的测试结果。

实现这一点的更简单方法是从 here 下载 TestRail API 客户端,然后使用测试轨 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);
    }
}

现在你可以在测试方法的清理方法中调用这个类方法了。像这样的东西:

        [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);
        }
    }

要了解有关 testrail API 的更多信息,您可以参考this link。 对于 API 结果,您甚至可以参考this link

【讨论】:

  • TestRailpm.Resultoftestcase 属性不能这样访问。它对我不起作用。您能否分享一下您在 testRail 中使用相同的 TestRail API 更新 TestResult 的方式?
  • @Amna 更新 UTestResultKeeper.TestResult.Outcome 会改变TestRailpm.Resultoftestcase 的状态,如果不是,你能告诉我如何访问TestRailpm.Resultoftestcase 吗?
  • @Amna 可以分享一下TestRailpm.cs的全部代码吗?
  • 我已在 TestRailpm.cs 文件中更新了问题中的代码。请看。
  • 我还需要在开始执行时首先创建的单个测试运行中更新测试用例。现在我想在该测试运行中更新我所有的测试用例结果。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-25
  • 1970-01-01
  • 2020-01-26
  • 2021-05-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多