8

当尝试在 Visual Studio 2008 中运行一个非常简单的 WatiN 2.0 (CTP3) 测试时,我发现第一个总是执行得很好。第二种测试方法似乎破坏了 IE 对象中的某些内容,产生以下异常:

测试方法 testProject.WatinTest.testTwo 抛出异常:System.Runtime.InteropServices.InvalidComObjectException:无法使用已与其底层 RCW 分离的 COM 对象。

示例代码如下。由于初始化方法在 VS2008 中的工作方式,必须定义浏览器变量static,我认为这可能是问题的关键。不幸的是,除非浏览器以通用方法打开,否则这意味着每个测试都有一个单独的窗口,这并不理想

我将非常感谢有关如何解决此问题的任何想法。谷歌搜索和 SO 搜索没有产生任何有用的结果,所以我希望这个问题的一个好的答案能够帮助社区。非常感谢,


    private static IE ie

    [ClassInitialize]
    public static void testInit(TestContext testContext)
    {
        ie = new IE("http://news.bbc.co.uk");
    }

    [TestMethod]
    public void testOne()
    {
        Assert.IsTrue(ie.ContainsText("Low graphics"));
    }

    [TestMethod]
    public void testTwo()
    {
        Assert.IsTrue(ie.ContainsText("Low graphics"));
    }
4

3 回答 3

10

我以前听说过这个问题,并打算调查一段时间。现在 WatiN 2.0 beta 1 已经可用,我坐下来创建了一个帮助类来使用 Visual Studios 测试运行器解决这个问题。跟随助手类和改进的测试类。我还 发布了有关此解决方案的博客,以使其获得更多曝光。

public class IEStaticInstanceHelper
{
    private IE _ie;
    private int _ieThread;
    private string _ieHwnd;

    public IE IE
    {
        get
        {
            var currentThreadId = GetCurrentThreadId();
            if (currentThreadId != _ieThread)
            {
                _ie = IE.AttachToIE(Find.By("hwnd", _ieHwnd));
                _ieThread = currentThreadId;
            }
            return _ie;
        }
        set
        {
            _ie = value;
            _ieHwnd = _ie.hWnd.ToString();
            _ieThread = GetCurrentThreadId();
        }
    }

    private int GetCurrentThreadId()
    {
        return Thread.CurrentThread.GetHashCode();
    }
}

以及使用这个助手的测试类:

[TestClass]
public class UnitTest 
{
    private static IEStaticInstanceHelper ieStaticInstanceHelper;

    [ClassInitialize]
    public static void testInit(TestContext testContext)
    {
        ieStaticInstanceHelper = new IEStaticInstanceHelper();
        ieStaticInstanceHelper.IE = new IE("http://news.bbc.co.uk");
    }

    public IE IE
    {
        get { return ieStaticInstanceHelper.IE; }
        set { ieStaticInstanceHelper.IE = value; }
    }

    [ClassCleanup]
    public static void MyClassCleanup()
    {
        ieStaticInstanceHelper.IE.Close();
        ieStaticInstanceHelper = null;
    }

    [TestMethod]
    public void testOne()
    {
        Assert.IsTrue(IE.ContainsText("Low graphics"));
    }

    [TestMethod]
    public void testTwo()
    {
        Assert.IsTrue(IE.ContainsText("Low graphics"));
    }
}

HTH,杰伦

于 2009-03-31T13:19:21.323 回答
8

我一直在寻找同样的东西,jvmenen 的回答帮助了我。但是,自从给出答案以来,WatiN 已经进行了一些更新,因此我不得不稍微重写帮助程序类以与最新的 WatiN 版本(当前为 2.0.20)保持一致。

WatiN 不再包含该IE.AttachToIE功能,因此我不得不对其进行一些修改。此外,我还使用泛型制作了辅助类,这样任何浏览器类型都可以使用,而不仅仅是 IE(我相信现在 WatiN 支持 IE 和 Firefox,Chrome 即将到来)。

因此,如果其他人也在寻找这个,这是我的版本IEStaticInstanceHelper(现在称为StaticBrowserInstanceHelper):

class StaticBrowserInstanceHelper<T> where T : Browser
{
    private Browser _browser;
    private int _browserThread;
    private string _browserHwnd;

    public Browser Browser
    {
        get
        {
            int currentThreadId = GetCurrentThreadId();
            if (currentThreadId != _browserThread)
            {
                _browser = Browser.AttachTo<T>(Find.By("hwnd", _browserHwnd));
                _browserThread = currentThreadId;
            }
            return _browser;
        }
        set
        {
            _browser = value;
            _browserHwnd = _browser.hWnd.ToString();
            _browserThread = GetCurrentThreadId();
        }
    }

    private int GetCurrentThreadId()
    {
        return Thread.CurrentThread.GetHashCode();
    }
}

希望这可以帮助某人:)

于 2010-07-12T08:11:03.033 回答
0

我认为这与您保留 IE 变量的方式有关。我一直在毫无问题地使用它,如示例中所示:http ://watin.sourceforge.net/ 。我将 watin 测试视为比单元测试更多的功能/集成测试,因此每个测试更像是一个具有不同交互的故事。我使用页面对象模式来帮助构建代码 - 请参阅http://code.google.com/p/webdriver/wiki/PageObjects

附言。我考虑过重用该实例,但还没有真正尝试过。打开/关闭浏览器实例确实增加了测试时间。

于 2009-03-25T00:05:22.560 回答