51Testing软件测试论坛

 找回密码
 (注-册)加入51Testing

QQ登录

只需一步,快速开始

微信登录,快人一步

查看: 2975|回复: 2
打印 上一主题 下一主题

[转贴] angular自动化测试--protractor

[复制链接]
  • TA的每日心情
    无聊
    昨天 09:19
  • 签到天数: 933 天

    连续签到: 5 天

    [LV.10]测试总司令

    跳转到指定楼层
    1#
    发表于 2016-8-29 15:54:44 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
    为什么要自动化测试?
    1,提高产出质量。
    2,减少重构时的痛。反正我最近重构多了,痛苦经历多了。
    3,便于新人接手。

    angular自动化测试主要分:端到端测试和单元测试,很明显两者都要熟练掌握。
    端到端测试是从用户的角度出发,认为整个系统是个黑盒,只会有UI暴露给用户,主要是模仿人工操作测试。
    单元测试认为整个系统是白盒,可以用来测试服务,控制器,过滤器还有基础函数等。
    端到端测试使用protractor,今天就扯这个。

    为什么使用Protractor,也就是说Protractor有什么好处,有没有替代品?
    1,不需要基于id,css选择器,xpath等查询元素,你可以基于绑定,模型,迭代器等等进行测试。
    2,避免回调地狱。对比下面的代码就知道了。
    1. //没有protractor
    2. driver.getTitle().then(function(title){
    3.     expect(title).toBe('Baidu');
    4. });

    5. //使用protractor
    6. expect(browser.getTitle()).toEqual('Baidu');
    复制代码
    替代品:capybara-angular等。
    正事
    前戏做完了,开始办正事吧。
    第一步当然是配置Protractor,别人写好了,我就不累赘了,送上传送门:
    [url=http://www.cnblogs.com/sallyzhang/p/4980729.htmlhttp://sentsin.com/web/658.html]配置[/url]

    第二步,掌握最简单的测试(高手可以绕过)
    1. describe('hello world', function() {
    2.     it('标题是hello world', function() {
    3.         browser.get('测试地址自己搞一个咯');
    4.         expect(browser.getTitle()).toEqual('hello world');
    5.     });
    6. });
    复制代码
    说白了就是希望指定的链接的标题是"hello world"
    第三步,了解下大体编写流程。
    首先我们必须跳转到指定的页面,跳转页面有两种方法。
    1,browser.get,跳转到指定的页面,还会重新刷新整个页面。
    2,browser.setLocation,更确切的说,是跳转路由,修改#后面部分。

    “等待某个元素出现”而不是“等待页面加载完毕”,如果页面加载完毕之后,马上去获取某个元素,很可能改元素不存在,然后直接报错退出。
    点击某个按钮之后,弹窗,弹窗有渐进动画,具体弹窗内的元素什么时候出现不确定,那么必须“等待某个元素出现”。怎么实现?
    1. /等待ng-model="password"的出现,最多等待20秒
    2. browser.wait(function(){
    3.     return browser.isElementPresent(by.model("password"));
    4. },20000);
    复制代码
    封装页面对象,英文叫PageObject,我也不知道怎么翻译,说白了就是封装组件或者页面的选择器。
    为什么要有这一步?
    先看一段代码:
    1. describe('angularjs homepage', function() {
    2.   it('should greet the named user', function() {
    3.   browser.get('http://www.angularjs.org');
    4.   element(by.model('yourName')).sendKeys('Julie');
    5.   var greeting = element(by.binding('yourName'));
    6.   expect(greeting.getText()).toEqual('Hello Julie!');
    7. });

    8. describe('todo list', function() {
    9.   var todoList;
    10.   beforeEach(function() {
    11.   browser.get('http://www.angularjs.org');
    12.   todoList = element.all(by.repeater('todo in todos'));
    13. });

    14. it('should list todos', function() {
    15.   expect(todoList.count()).toEqual(2);
    16.   expect(todoList.get(1).getText()).toEqual('build an angular app');
    17. });

    18. it('should add a todo', function() {
    19.   var addTodo = element(by.model('todoText'));
    20.   var addButton = element(by.css('[value="add"]'));

    21.   addTodo.sendKeys('write a protractor test');
    22.   addButton.click();

    23.   expect(todoList.count()).toEqual(3);
    24.   expect(todoList.get(2).getText()).toEqual('write a protractor test');
    25. });
    复制代码
    这是没封装的情况。
    1,语义化很差,根本很难看明白在做神马。
    2,重复代码多。browser.get('http://www.angularjs.org');就不止出现了一次。
    3,耦合严重。如果标签结构改动,代码很多地方都要改。
    4,难以维护,随着项目的增长和时间的推移,没有人会乐意在这上面添加其它测试功能。

    问题已经暴露出来了,怎么封装?
    封装之前,建议过一遍官方的教程和API接口,常用的不多,难度不大。传送门
    举个栗子,很简单的。现在有个滚动条。示意图有点丑,别笑。
    封装出来应该如下,这样即使滚动条的代码结构改了什么的,只要改下面的代码,而具体测试逻辑不用动。
    1. function ScrollBarSelector(model){
    2.     Object.defineProperty(this,"target",{
    3.         get:function(){
    4.             return typeof model == "string" ? element(by.model(model)) : model;
    5.         }
    6.     })
    7.     Object.defineProperty(this,"pre",{
    8.         get:function(){
    9.             return this.target.$(".pre");
    10.         }
    11.     })

    12.     Object.defineProperty(this,"next",{
    13.         get:function(){
    14.             return this.target.$(".next");
    15.         }
    16.     })

    17.     Object.defineProperty(this,"scrollButton",{
    18.         get:function(){
    19.             return this.target.$(".scrollButton");
    20.         }
    21.     })
    22.     Object.defineProperty(this,"value",{
    23.         get:function(){
    24.             return this.target.$("input").getAttribute("value");
    25. } })
    26. }
    复制代码
    测试逻辑,基本上就是,
    点击某个按钮:scrollBar.next.click()
    希望某个输入框的内容为:expect(scrollBar.value).toBe("xx");


    最后,还是附上登录的测试和路由跳转,google上面很多人都在问。很多人问的问题是,登录完了,跳转页面,怎么知道页面跳转了。
    spec.js
    1. !function(){
    2.     require(".LoginAction.js");
    3.     require(".LogoutAction.js");
    4.     require(".ScrollbarAction.js");
    5.    
    6.     describe("自动登录",function(){
    7.         new LoginAction().execute("GetLiShu","123456");
    8.     })


    9.     describe('testScrollbar', function () {
    10.         new ScrollbarAction().execute();
    11.     });

    12.     describe("退出登录",function(){
    13.         new LogoutAction().execute();
    14.     });
    15. }();
    复制代码
    LoginAction.js
    1. !function(){

    2.     function LoginAction(){

    3.     }
    4.     var prop = LoginAction.prototype;
    5.     prop.execute = function(userName,password){
    6.         beforeEach(function () {
    7.             //先跳转到登录页面
    8.             browser.get("登录页面");
    9.             //等待输入框出来
    10.             browser.wait(function(){
    11.                 return browser.isElementPresent(by.model("username"));
    12.             },20000);
    13.         })
    14.         
    15.         //输入账号密码然后点击登录
    16.         it('自动登录', function () {
    17.             element(by.model("username")).sendKeys(userName);
    18.             element(by.model("password")).sendKeys(password);
    19.             element(by.css(".login-input-btn")).click();
    20.         });
    21.     }
    22.     module.exports = LoginAction;
    23. }();
    复制代码
    ScrollbarAction.js
    1. !function(){
    2.     beforeEach(function () {
    3.         browser.setLocation("/app/common/stepper");
    4.     })
    5.     it('测试滚动条', function () {
    6.         var scrollbar = new ScrollbarSelector("vm.scroll");
    7.         
    8.         //等待滚动条出来,最多等待20秒,滚动条出来了,马上处理测试代码
    9.         browser.wait(function(){
    10.             return browser.isElementPresent(numberDefault.mius);
    11.         },20000);

    12.         //这里省略很多行测试代码
    13.     });
    14. }();
    复制代码
    努力把自己打造成一本WEB百科全书
    文章出自:博客园


    分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
    收藏收藏2
    回复

    使用道具 举报

    该用户从未签到

    2#
    发表于 2019-1-17 11:16:51 | 只看该作者
    楼主,页面跳转好像要使用窗口句柄,请问怎么写呀?
    回复 支持 反对

    使用道具 举报

    本版积分规则

    关闭

    站长推荐上一条 /1 下一条

    小黑屋|手机版|Archiver|51Testing软件测试网 ( 沪ICP备05003035号 关于我们

    GMT+8, 2024-4-20 10:09 , Processed in 0.065838 second(s), 22 queries .

    Powered by Discuz! X3.2

    © 2001-2024 Comsenz Inc.

    快速回复 返回顶部 返回列表