自动化测试--protractor

简介: 前戏 面向模型编程; 测试驱动开发; 先保障交互逻辑,再调整细节。---by 雪狼。   为什么要自动化测试? 1,提高产出质量。 2,减少重构时的痛。反正我最近重构多了,痛苦经历多了。 3,便于新人接手。

前戏

面向模型编程;

测试驱动开发;

先保障交互逻辑,再调整细节。---by 雪狼。

 

为什么要自动化测试?

1,提高产出质量。

2,减少重构时的痛。反正我最近重构多了,痛苦经历多了。

3,便于新人接手。

 

angular自动化测试主要分:端到端测试和单元测试,很明显两者都要熟练掌握。

端到端测试是从用户的角度出发,认为整个系统是个黑盒,只会有UI暴露给用户,主要是模仿人工操作测试。

单元测试认为整个系统是白盒,可以用来测试服务,控制器,过滤器还有基础函数等。

端到端测试使用protractor,今天就扯这个。

 

为什么使用Protractor,也就是说Protractor有什么好处,有没有替代品?

1,不需要基于id,css选择器,xpath等查询元素,你可以基于绑定,模型,迭代器等等进行测试。

2,避免回调地狱。对比下面的代码就知道了。

复制代码
//没有protractor
driver.getTitle().then(function(title){
    expect(title).toBe('Baidu');
});

//使用protractor
expect(browser.getTitle()).toEqual('Baidu');
复制代码

替代品:capybara-angular等。

 

正事

前戏做完了,开始办正事吧。

第一步当然是配置Protractor,别人写好了,我就不累赘了,送上传送门:

配置

 

第二步,掌握最简单的测试(高手可以绕过)

describe('hello world', function() {
    it('标题是hello world', function() {
        browser.get('测试地址自己搞一个咯');
        expect(browser.getTitle()).toEqual('hello world');
    });
});

说白了就是希望指定的链接的标题是"hello world"

 

第三步,了解下大体编写流程。

首先我们必须跳转到指定的页面,跳转页面有两种方法。

1,browser.get,跳转到指定的页面,还会重新刷新整个页面。

2,browser.setLocation,更确切的说,是跳转路由,修改#后面部分。

 

“等待某个元素出现”而不是“等待页面加载完毕”,如果页面加载完毕之后,马上去获取某个元素,很可能改元素不存在,然后直接报错退出。

点击某个按钮之后,弹窗,弹窗有渐进动画,具体弹窗内的元素什么时候出现不确定,那么必须“等待某个元素出现”。怎么实现?

//等待ng-model="password"的出现,最多等待20秒
browser.wait(function(){
    return browser.isElementPresent(by.model("password"));
},20000);

 

封装页面对象,英文叫PageObject,我也不知道怎么翻译,说白了就是封装组件或者页面的选择器。

为什么要有这一步?

先看一段代码:

复制代码
describe('angularjs homepage', function() {
  it('should greet the named user', function() {
  browser.get('http://www.angularjs.org');
  element(by.model('yourName')).sendKeys('Julie');
  var greeting = element(by.binding('yourName'));
  expect(greeting.getText()).toEqual('Hello Julie!');
});

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

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

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

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

  expect(todoList.count()).toEqual(3);
  expect(todoList.get(2).getText()).toEqual('write a protractor test');
});
复制代码

这是没封装的情况。

1,语义化很差,根本很难看明白在做神马。

2,重复代码多。browser.get('http://www.angularjs.org');就不止出现了一次。

3,耦合严重。如果标签结构改动,代码很多地方都要改。

4,难以维护,随着项目的增长和时间的推移,没有人会乐意在这上面添加其它测试功能。

 

问题已经暴露出来了,怎么封装?

封装之前,建议过一遍官方的教程和API接口,常用的不多,难度不大。传送门

举个栗子,很简单的。现在有个滚动条。示意图有点丑,别笑。

封装出来应该如下,这样即使滚动条的代码结构改了什么的,只要改下面的代码,而具体测试逻辑不用动。

复制代码
function ScrollBarSelector(model){
    Object.defineProperty(this,"target",{
        get:function(){
            return typeof model == "string" ? element(by.model(model)) : model;
        }
    })
    Object.defineProperty(this,"pre",{
        get:function(){
            return this.target.$(".pre");
        }
    })

    Object.defineProperty(this,"next",{
        get:function(){
            return this.target.$(".next");
        }
    })

    Object.defineProperty(this,"scrollButton",{
        get:function(){
            return this.target.$(".scrollButton");
        }
    })
    Object.defineProperty(this,"value",{
        get:function(){
            return this.target.$("input").getAttribute("value");
 } })
}
复制代码

 

 

测试逻辑,基本上就是,

点击某个按钮:scrollBar.next.click()

希望某个输入框的内容为:expect(scrollBar.value).toBe("xx");

 

 

最后,还是附上登录的测试和路由跳转,google上面很多人都在问。很多人问的问题是,登录完了,跳转页面,怎么知道页面跳转了。

spec.js

复制代码
!function(){
    require(".LoginAction.js");
    require(".LogoutAction.js");
    require(".ScrollbarAction.js");
    
    describe("自动登录",function(){
        new LoginAction().execute("GetLiShu","123456");
    })


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

    describe("退出登录",function(){
        new LogoutAction().execute();
    });
}();
复制代码

 

LoginAction.js

复制代码
!function(){

    function LoginAction(){

    }
    var prop = LoginAction.prototype;
    prop.execute = function(userName,password){
        beforeEach(function () {
            //先跳转到登录页面
            browser.get("登录页面");
            //等待输入框出来
            browser.wait(function(){
                return browser.isElementPresent(by.model("username"));
            },20000);
        })
        
        //输入账号密码然后点击登录
        it('自动登录', function () {
            element(by.model("username")).sendKeys(userName);
            element(by.model("password")).sendKeys(password);
            element(by.css(".login-input-btn")).click();
        });
    }
    module.exports = LoginAction;
}();
复制代码

 

ScrollbarAction.js

复制代码
!function(){
    beforeEach(function () {
        browser.setLocation("/app/common/stepper");
    })
    it('测试滚动条', function () {
        var scrollbar = new ScrollbarSelector("vm.scroll");
        
        //等待滚动条出来,最多等待20秒,滚动条出来了,马上处理测试代码
        browser.wait(function(){
            return browser.isElementPresent(numberDefault.mius);
        },20000);

        //这里省略很多行测试代码
    });
}();
复制代码

 

http://www.cnblogs.com/geilishu/p/5801175.html

 

相关文章
|
12天前
|
Web App开发 Java 测试技术
反了!居然让我教她自动化测试!
反了!居然让我教她自动化测试!
30 1
|
3月前
|
存储 监控 安全
自动化测试适用场景
自动化测试适用场景
|
监控 JavaScript Java
Node.js 应用故障排查手册 —— 综合性 GC 问题和优化
本章前面两节生产案例分别侧重于单一的 CPU 高和单一的内存问题,我们也给大家详细展示了问题的定位排查过程,那么实际上还有一类相对更复杂的场景——它本质上是 V8 引擎的 GC 引发的问题。
1820 0
|
11月前
|
前端开发 JavaScript 调度
Webpack5模块联邦源码探究
虽然webpack5已经发布了一段时间了,但一直都没有研究过,最近正好在做微前端相关的调研,恰好看到了webpack5的模块联邦与微前端的相关方案,便想着探究下模块联邦的相关源码。
232 0
|
10月前
|
人工智能 前端开发 JavaScript
AI 如何辅助 Web 前端开发
随着人工智能(AI)的快速发展,它正逐渐渗透到各个领域,包括软件开发。Web 前端开发作为软件工程中重要的一环,也受益于人工智能的进步。本文将探讨如何利用 AI 技术来辅助 Web 前端开发,从代码生成、布局优化、错误检测和智能助手等方面展开讨论。
1609 2
|
10月前
|
边缘计算 前端开发 JavaScript
【微前端】手把手教你从0到1实现基于Webpack5 模块联邦(Module Federation)的微前端~(上)
【微前端】手把手教你从0到1实现基于Webpack5 模块联邦(Module Federation)的微前端~(上)
|
11月前
|
存储 缓存 编解码
pnpm 中的 .npmrc 文件配置
.npmrc 文件是一个使用 .ini 文件格式书写的配置文件。本文介绍pnpm 中的 .npmrc 文件配置方法。
1918 0
pnpm 中的 .npmrc 文件配置
|
前端开发 JavaScript
JS案例:将前端页面导出为PDF
JS案例:将前端页面导出为PDF
388 0
JS案例:将前端页面导出为PDF
|
编解码 前端开发 JavaScript
如何理解data URL?
canvas有一个非常常用的方法canvas.toDataURL(),它会将canvas转化为data URL的格式。 通常情况下这个data URL的类型为image。
如何理解data URL?
|
XML 存储 JSON
基础知识 - 为什么要使用 Base64 编码,有哪些情景需求?
基础知识 - 为什么要使用 Base64 编码,有哪些情景需求?
314 0