angular自動化測試--protractor


前戲

面向模型編程;

測試驅動開發;

先保障交互邏輯,再調整細節。---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);

        //這里省略很多行測試代碼
    });
}();

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM