网站测试自动化系统—基于Selenium和VSTT

简介:

刚刚以SCRUM的方式结束了一个的ASP.NET网站的测试的第一个Spring,因为团队从无到有实现自动化测试系统,有必要把这次的经验和教训总结一下,以便后续的Spring可以获取一些有意义的借鉴。

因为是一个技术博客,所以使用SCRUM管理这个测试项目的经验放在别的地方分享,这系列的文章分享一下使用VSTTSelenium结合实现自动化测试系统的经验。

 

Selenium简介

Selenium主要是一个录制并回放的自动化测试用例编制工具,由一个录制工具Selenium IDE(一个Firefox插件,当然这个工具也可以回放啦),一个回放工具Selenium Remote Control在其他机器和其他操作系统上进行回放。Selenium的一个好处就是你可以使用它测试所有操作系统下的所有主流浏览器,至于Linux下面的konquerorgnome下面自带的浏览器,没有试过Selenium是否支持,当然那个控制台界面下的浏览器就更没有试过啦。Selenium还有一个Selenium Grid,据说很强大,因为项目比较紧,就没有花时间去看它。

至于Selenium各个工具的用法,它的官网上有详细的文档,如果文档也没说清楚的话,那就直接读源代码吧。

 

SeleniumVSTT的整合

Selenium可以根据录制的步骤生成直接在NUnit中使用的C#代码,这些代码基本上都可以在VSTT中直接使用,就是一些属性需要更改。例如[TestFixture]改成[TestClass][Test]改成[TestMethod]之类的,改好以后,启动Selenium-RC,就可以直接在VSTT里面当作普通的单元测试用例执行了。

 

Selenium代码优化

既然要做自动化测试,那么有一点是必须要时刻考虑的,就是在产品开发过程中,程序界面甚至是内部的类库接口也是时刻改变的。而Selenium只能记录当时录制测试用例的界面情况,因此需需要将它生成的代码分解一下,以面向对象的方式来重写。例如下面这段代码的目的是测试用户可以查看自己的博客:

[TestMethod]

public void TheTestTest()

{

    selenium.Open("/");

    selenium.Click("link=登录");

    selenium.WaitForPageToLoad("30000");

    selenium.Type("tbUserName""donjuan");

    selenium.Type("tbPassword""");

    selenium.Click("btnLogin");

    selenium.WaitForPageToLoad("30000");

    selenium.Click("link=donjuan");

    selenium.WaitForPageToLoad("30000");

    selenium.Click("link=博客");

    selenium.WaitForPageToLoad("30000");

}

但是网页页面布局,或者Html控件的Id、文本等内容随时都会被程序员修改,修改的原因有多种,例如修复新的错误(Bug),或者仅仅就是代码重构。因此作为测试团队,不能总是认为网页的内容一成不变的。而象登录这种操作,大部分测试用例都会用到,所以最好只要为登录动作创建唯一的代码 。有多个方案:

1.       为登录创建一个独立的测试用例,本来登录这个功能就是要测试的嘛,在编辑自动化测试用例列表的时候,把登录用例放在最前面。

2.       为登录动作创建一个单独的函数,例如LogOn(),然后在其他测试用例当中(包括登录的测试用例)调用这个函数,另外,因为可能会需要用到不同的 用户,所以最好把用户名和密码等变量提取出来,变成LogOn(string username, string password)之类的函数。

两个方案,显然是第二个方案的弹性大,但是对于第一个方案,如果测试人员都是新手,且对代码不熟悉的话,建议可以考虑。

于是我们的代码就变成类似下面的代码:

using System;

 

//

// 这个异常是故意创建出来,用来封装所有在测试代码中发生的错误

//

public class CaseErrorException : Exception

{

    public CaseErrorException(string message)

        : base()

    {

    }

 

    public CaseErrorException(Exception inner)

        : this(null, inner)

    {

    }

 

    public CaseErrorException(string message, Exception inner)

        : base(message == null ? "测试代码错误,请修复测试代码,查看InnerException属性!" :

                                 string.Format("测试代码错误,请修复测试代码,详细错误信息:{0};或者查看InnerException属性!", message),

               inner)

    {

    }

}

 

public class UserOperationsHelper

{

    public void LogOn(string username, string password)

    {

        // string.Empty留出来为测试目的服务

        if (username == null)

            throw new CaseErrorException(new ArgumentNullException("username"));

        if (password == null)

            throw new CaseErrorException(new ArgumentNullException("password"));

 

        selenium.Open("/");

        selenium.Click("link=登录");

        selenium.WaitForPageToLoad(Consts.TimeToWaitForPageLoad);

        selenium.Type("tbUserName", username);

        selenium.Type("tbPassword", password);

        selenium.Click("btnLogin");

        selenium.WaitForPageToLoad(Consts.TimeToWaitForPageLoad);

    }

}

 

public static class Consts

{

    // 将等待的时间提取成一个公开的函数,因为在今后大规模的测试

    // 过程中,很多自动化测试用例不简单地执行,会导致网站响应速度

    // 变慢,所以

    public const string TimeToWaitForPageLoad = "30000";

}

 

public class TestLibrary

{

    public UserOperationsHelper UserHelper { getprivate set; }

}

 

public class TestClass

{

    [TestMethod]

    public void LogOnTest()

    {

        var username = "donjuan";

        var password = "它是个秘密";

        TestLibrary.UserHelper.LogOn(username, password);

 

        // 在测试过程中,我们发现这个链接是

        // 根据用户名而变的,为了扩展性,动态生成其标识文本

        selenium.Click(string.Format("link={0}", username));

        selenium.WaitForPageToLoad(Consts.TimeToWaitForPageLoad);

        selenium.Click("link=博客");

        selenium.WaitForPageToLoad(Consts.TimeToWaitForPageLoad);

 

        // 执行一些必要的测试验证过程

        Assert.IsTrue(selenium.IsTextPresented(...));

    }

}

 

这里稍微解释一下,创建自动化测试代码,就是为了节省手工重复测试的工作量以及测试失误的风险。但只要是代码,都会有可能出错,因此自动化测试框架里面创建了一个CaseErrorException,这样在每次分析测试用例失败的时候,可以一眼区分开测试代码的错误和产品代码中的错误。例如在UserOperationHelper.LogOn函数中的参数检查,当然啦,在测试过程当中,有可能需要测试不输入用户名或者密码的情况下,验证登录界面是否正常工作的情况。因此在验证参数的时候,特意为这种情况留下了String.Empty的入口,而对于null值,则基本上可以判断是因为测试人员在编写代码上的失误(具体原因会在数据驱动测试里面讲到)。

至于TestLibrary的初始化,完全可以放到每一个测试类型的TestInitializer里面,如下表所示:

[TestClass]

public class AddBlogTest

{

    private TestContext testContextInstance;

    public TestContext TestContext

    {

        get

        {

                return testContextInstance;

        }

        set

        {

            testContextInstance = value;

        }

    }

 

    private TestLibrary TestLibrary;

    private ISelenium selenium;

 

    [TestInitialize]

    public void SetupTest()

    {

        TestLibrary = TestLibrary.SetupTest(TestContext);

        selenium = TestLibrary.Selenium;

    }

 

    [TestCleanup]

    public void TeardownTest()

    {

        TestLibrary.Shutdown();

    }

}

 

咋看起来,把LogOn测试用例分解成那么多的类型,有点画蛇添足,实际上这些函数库正是为了更方便地创建后续的测试用例耗费的磨刀的功夫。例如下面的代码是基于一些创建好了的函数编写的测试用例:

[TestMethod]

public void CreateBlog()

{

    TestLibrary.UserHelper.LogOnAsAdmin();

    var blog = TestLibrary.BlogHelper.CreateBlog("博客的标题""博客的链接");

 

    selenium.Click("link=管理博客");

    selenium.WaitForPageToLoad(Consts.TimeToWaitForPageLoad);

 

    Assert.IsTrue(selenium.IsElementPresent(string.Format("link={0}", blog.Title)));

}

 

下一篇文章网站测试自动化系统—数据驱动测试讲解这个框架和数据驱动测试的结合。


本文转自 donjuan 博客园博客,原文链接:  http://www.cnblogs.com/killmyday/archive/2010/03/13/1685249.html ,如需转载请自行联系原作者

相关实践学习
通过轻量消息队列(原MNS)主题HTTP订阅+ARMS实现自定义数据多渠道告警
本场景将自定义告警信息同时分发至多个通知渠道的需求,例如短信、电子邮件及钉钉群组等。通过采用轻量消息队列(原 MNS)的主题模型的HTTP订阅方式,并结合应用实时监控服务提供的自定义集成能力,使得您能够以简便的配置方式实现上述多渠道同步通知的功能。
相关文章
|
2月前
|
前端开发 测试技术 API
测试金字塔:别再只盯着UI自动化了
测试金字塔:别再只盯着UI自动化了
364 116
|
2月前
|
敏捷开发 测试技术 API
测试金字塔:构建高效自动化测试策略的基石
测试金字塔:构建高效自动化测试策略的基石
290 116
|
2月前
|
人工智能 自然语言处理 测试技术
从人工到AI驱动:天猫测试全流程自动化变革实践
天猫技术质量团队探索AI在测试全流程的落地应用,覆盖需求解析、用例生成、数据构造、执行验证等核心环节。通过AI+自然语言驱动,实现测试自动化、可溯化与可管理化,在用例生成、数据构造和执行校验中显著提效,推动测试体系从人工迈向AI全流程自动化,提升效率40%以上,用例覆盖超70%,并构建行业级知识资产沉淀平台。
从人工到AI驱动:天猫测试全流程自动化变革实践
|
2月前
|
人工智能 自然语言处理 JavaScript
利用MCP Server革新软件测试:更智能、更高效的自动化
MCP Server革新软件测试:通过标准化协议让AI实时感知页面结构,实现自然语言驱动、自适应维护的自动化测试,大幅提升效率,降低脚本开发与维护成本,推动测试左移与持续测试落地。
|
2月前
|
测试技术 API 数据库
测试金字塔:构建高效自动化测试策略的基石
测试金字塔:构建高效自动化测试策略的基石
318 114
|
4月前
|
存储 人工智能 算法
AI测试平台实战:深入解析自动化评分和多模型对比评测
在AI技术迅猛发展的今天,测试工程师面临着如何高效评估大模型性能的全新挑战。本文将深入探讨AI测试平台中自动化评分与多模型对比评测的关键技术与实践方法,为测试工程师提供可落地的解决方案。
|
5月前
|
JSON JavaScript 测试技术
用Postman玩转电商API:一键测试+自动化请求教程
Postman 是电商 API 测试的高效工具,涵盖基础配置、自动化测试、环境管理与请求自动化,助你快速提升开发效率。
|
3月前
|
机器学习/深度学习 人工智能 测试技术
EdgeMark:嵌入式人工智能工具的自动化与基准测试系统——论文阅读
EdgeMark是一个面向嵌入式AI的自动化部署与基准测试系统,支持TensorFlow Lite Micro、Edge Impulse等主流工具,通过模块化架构实现模型生成、优化、转换与部署全流程自动化,并提供跨平台性能对比,助力开发者在资源受限设备上高效选择与部署AI模型。
416 9
EdgeMark:嵌入式人工智能工具的自动化与基准测试系统——论文阅读
|
2月前
|
存储 人工智能 自然语言处理
拔俗AI自动化评价分析系统:让数据说话,让决策更智能
在用户体验为核心的时代,传统评价分析面临效率低、洞察浅等痛点。本文基于阿里云AI与大数据技术,构建“数据-算法-应用”三层智能分析体系,实现多源数据实时接入、情感与主题精准识别、跨模态融合分析及实时预警,助力企业提升运营效率、加速产品迭代、优化服务质量,并已在头部电商平台成功落地,显著提升用户满意度与商业转化。
|
5月前
|
运维 Prometheus 监控
系统崩了怪运维?别闹了,你该问问有没有自动化!
系统崩了怪运维?别闹了,你该问问有没有自动化!
194 9