在编写自动化测试时,处理Try Catch的最佳实践是什么?

时间:2016-08-12 10:47:16

标签: c# selenium testing automated-tests

我目前正在为我的公司编写基于Web的应用程序的测试自动化。我正在使用C#,Visual Studio测试套件和Selenium来执行测试。

今天我向我的同事提出这样一个问题:'有没有时间代码中有太多的Try Catch块?'。他的回答是不能像我现在那样工作(参见示例1),但只是让较低级别的try-catch抛出到上层try-catch,以便可以在那里写入异常并且测试失败(见例2)。

示例1:

TestCase.cs

[TestMethod]
public void TestLogin()
{
    Assert.IsTrue(FW_Shared.Perform_Login(FW_Shared.OrgCode, FW_Shared.Username, FW_Shared.Password));
    Console.WriteLine(@"Login Successful");    
}

FW_Shared.cs

public static class FW_Shared
{
    public static string OrgCode = "Test123";
    public static string Username = "Tester";
    public static string Password = "Password";

    public static void Perform_Login(string OrgCode, string Username, string Password)
    {
        try
        {
            Driver.Url = "http://test.app.com/";
            Driver.FindElement(By.Id("org_code")).SendKeys(OrgCode);
            Driver.FindElement(By.Id("username")).SendKeys(Username);
            Driver.FindElement(By.Id("password")).SendKeys(Password);
            Driver.FindElemenet(By.Id("btnsubmit)).Click();
        }
        catch (Exception ex)
        {
             Console.WriteLine(@"Error occurred logging on: " + ex.ToString());
             return false;
        }
        return true;
    }
}

示例2

TestCase.cs

[TestMethod]
public void TestLogin()
{
    try
    {
        Assert.IsTrue(FW_Shared.Perform_Login(FW_Shared.OrgCode, FW_Shared.Username, FW_Shared.Password));
        Console.WriteLine(@"Login Successful");  
    }
    catch (Exception ex)
    {
        Console.WriteLine(@"Exception caught, test failed: " + ex.ToString());
        Assert.Fail();
    }  
}

FW_Shared.cs

public static class FW_Shared
{
    public static string OrgCode = "Test123";
    public static string Username = "Tester";
    public static string Password = "Password";

    public static void Perform_Login(string OrgCode, string Username, string Password)
    {
        try
        {
            Driver.Url = "http://test.app.com/";
            Driver.FindElement(By.Id("org_code")).SendKeys(OrgCode);
            Driver.FindElement(By.Id("username")).SendKeys(Username);
            Driver.FindElement(By.Id("password")).SendKeys(Password);
            Driver.FindElemenet(By.Id("btnsubmit)).Click();
        }
        catch (Exception)
        {
             throw;
        }
        return true;
    }
}

现在我知道抛出要捕获的异常在典型编码中通常是无用的,因为你想要处理返回的特定异常,但我希望能够捕获任何常规网页或元素问题,这样测试就会失败关于Web应用程序的一般问题。例如:

  • 如果网页返回503或404问题
  • 如果当前网页上没有元素
  • 如果元素名称已更改。

在测试其他更复杂的应用程序部分时,我处理无法访问的部分/元素并使用true / false bool返回并断言,但是因为我在不同的类中引用多个函数会坚持我所拥有的最好的,转移到顶级捕获所有较低的异常,或者我应该做其他什么?

2 个答案:

答案 0 :(得分:0)

我通常喜欢在自己的类中创建一个名为" TestRunner.cs"的测试辅助方法。我有一个方法用于所有可能引发异常的测试,我想测试例如的结果。

public static Exception RunCodeThatMayThrowException(Action action)
{
    try
    {
        action.Invoke();
        return null;
    }
    catch (Exception ex)
    {
        return ex;
    }
}

然后我可以使用如下方法:

// Act
var actualException = TestRunner.RunCodeThatMayThrowExeption(() => {//some code});

// Assert
//Do some asserts

答案 1 :(得分:0)

你原来的 Perform_Login 方法没有声明返回参数('void')并且总是返回'true'(除非发生崩溃) - 这两个都暗示该方法需要一些重新分解。

我会重新考虑如下因素,它将调用代码与异常隔离开来,使调用者不知道调用方法中的任何错误,并避免一系列try-catches传递调用堆栈(如果你的测试有一个try-catch,然后调用该方法的生产代码可能需要相同的):

Public Static Class FW_Shared
{
    public static string OrgCode = "Test123";
    public static string Username = "Tester";
    public static string Password = "Password";

    public static bool Perform_Login(string OrgCode, string Username, string Password)
    {
        Try
        {
            Driver.Url = "http://test.app.com/";
            Driver.FindElement(By.Id("org_code")).SendKeys(OrgCode);
            Driver.FindElement(By.Id("username")).SendKeys(Username);
            Driver.FindElement(By.Id("password")).SendKeys(Password);
            Driver.FindElemenet(By.Id("btnsubmit)).Click();
        }
        Catch (Exception ex)
        {
             Console.WriteLine(@"Error occurred logging on: " + ex.ToString());
             return false;
        }
        return true;
    }
}

[TestMethod]
Public Void TestLoginSuccess()
{
    Assert.IsTrue(FW_Shared.Perform_Login(FW_Shared.OrgCode, FW_Shared.Username, FW_Shared.Password));
    Console.WriteLine(@"Login Successful");    
}


[TestMethod]
Public Void TestLoginFailure()
{
    Assert.IsFalse(FW_Shared.Perform_Login(FW_Shared.OrgCode, “foo”, “bar”));
    Console.WriteLine(@"Login Failed");    
}