AngulaJS End-to-End Testing with Protractor

1. End-to-end

Các ứng dụng web hiện đại phải tích hợp một loạt các dịch vụ bên ngoài, hệ thống cơ sở dữ liệu và các API. Và làm sao cho phù hợp với sự thay đổi liên tục của các thiết bị và trinh duyệt web.

Đây là một lĩnh vực rất khó hoặc thậm chí hoàn toàn không thể test bằng phương pháp truyền thống như Unit test và simple mocks. Một cơ sở dữ liệu có thể fail, một dịch vụ bên ngoài có thể trả về một kết quả không hợp lệ và một phiên bản trình duyệt mới có thể có lỗi tìm ẩn.

Điều đó dẫn đến sự ra đời của end-to-end testing. Chúng ta muốn thử nghiệm ứng dụng của chúng ta một cách tổng quan và chắc chắn rằng nó hoạt động như mong đợi. Chúng ta muốn kiểm tra toàn bộ ứng dụng, bắt đầu từ giao diện người dùng xuống các hệ thống con người, chẳng hạn như lưu trữ dữ liệu hoặc gọi các dịch vụ bên ngoài.

Điều quan trọng cần lưu ý là end-to-end testing không phải là phương pháp kiểm thử tốt nhất mà chúng ta nên sử dụng nó cùng với các phương pháp thử nghiệm khác, nhưng mức độ cao và phạm vi rộng các kiểm thử end-to-end giúp chúng ta rất nhiều khi phát triển một ứng dụng web phức tạp.

2. PROTRACTOR

Google đã released an end-to-end testing framework cho AngularJS tích hợp các công nghệ hiện có như Selenium, Node.js và Jasmine và làm cho việc viết test script một cách dễ dàng.

Với protractor chúng ta có thể viết các test script tự động chạy trên một trình duyệt thực tế, đối với một trang web hiện có. Như vậy, chúng ta có thể dễ dàng kiểm tra xem một trang có làm việc như mong đợi. Ngoài ra việc sử dụng protractor giúp ta hiểu rõ thêm về AngularJS và tối ưu hóa cho nó.

Protractor is built on top of WebDriverJS

3. CÀI ĐẶT

Protractor yêu cầu chúng ta phải cài Node.js, Selenium và Jasmine trước trên máy. Cài Protractor globally với command line:
npm install -g protractor
Nó sẽ tự cài command line tools, protractor and webdriver-manager. Try running protractor --version to make sure it's working.
The webdriver-manager is a helper tool to easily get an instance of a Selenium Server running. Use it to download the necessary binaries with:
webdriver-manager update
Now start up a server with:
webdriver-manager start
Xem chi tiết tại đây.

4. FILE CẤU HÌNH

Giống như Karma, Protractor yêu cầu một file cấu hình để nó biết được làm thế nào để chạy, làm thế nào để kết nối với Selenium, vv
Phương pháp dễ nhất để tạo một tập tin cấu hình cho Protractor là copy một tập tin cấu hình tham khảo từ các thư mục cài đặt.
exports.config = {
  seleniumAddress: 'http://localhost:4444/wd/hub',

  capabilities: {
    'browserName': 'chrome'
  },

  specs: ['example-spec.js'],

  jasmineNodeOpts: {
    showColors: true
  }
};

5. VIẾT MỘT SIMPLE TEST

  File test mẫu example-spec.js có nội dung sau:
describe("E2E Testing", function() {

  // start at root before every test is run
  beforeEach(function() {
    browser().navigateTo('/');
  });

  // test default route
  it('should jump to the /home path when / is accessed', function() {
    browser().navigateTo('#/');
    expect(browser().location().path()).toBe("/login");
  });

  it('ensures user can log in', function() {
    browser().navigateTo('#/login');
    expect(browser().location().path()).toBe("/login");

    // ng-model specified, and this conbination will successfully login
    input('email').enter('test@test.com');
    input('password').enter('password');
    element('submit').click();

    // logged in route
    expect(browser().location().path()).toBe("/dashboard");

    // my dashboard page has a label for the email address of the logged in user
    expect(element('#email').html()).toContain('test@test.com');
  });

  it('should keep invalid logins on this page', function() {
    browser().navigateTo('#/login');
    expect(browser().location().path()).toBe("/login");

    // ng-model specified, and this conbination will successfully login
    input('email').enter('invalid@test.com');
    input('password').enter('wrong password');
    element('submit').click();

    expect(element('#message').html().toLowerCase()).toContain('failed');

    // logged out route
    expect(browser().location().path()).toBe("/login");

  });

});

*** Đễ tổ chức code tốt hơn ta nên tách các element đối tượng của một page thành một file riêng đặt tên là example-po.js


var LoginPage = function() {

  this.username = element(by.model('username'));
  this.password = element(by.model('password'));
  this.loginButton = element(by.id('btn-login'));
  this.passwordRequiredError = element(by.css('error-password-required'));

  this.visit = function() {
    browser.get('/login');
  };

  this.setUsername = function(username) {
    this.username.clear();
    this.username.sendKeys(username);
  };


  this.setPassword = function(password)
    this.password.clear();
    this.password.sendKeys(password);
  };

  this.login = function() {
    this.loginButton.click();
  };

};

module.exports = new LoginPage();

Import file *-po.js vào file *-spec.js 


var page = require('./sample-po.js');

describe('E2E Testing', function() {

  it('test case', function() {
    page.visit();
    page.setUsername('gandalf');
    page.login();

    expect(page.passwordRequiredError.isDisplayed()).toBe(true);
  });

});


6. CHẠY TEST

protractor *-conf.js

SHARE THIS

0 comments: