Thước đo góc - Hướng dẫn nhanh
Chương này cung cấp cho bạn phần giới thiệu về Thước đo góc, nơi bạn sẽ tìm hiểu về nguồn gốc của khung kiểm thử này và tại sao bạn phải chọn nó, cách làm việc và những hạn chế của công cụ này.
Thước đo góc là gì?
Protractor là một khung kiểm tra end-to-end mã nguồn mở cho các ứng dụng Angular và AngularJS. Nó được Google xây dựng trên đầu trang WebDriver. Nó cũng đóng vai trò thay thế cho khung thử nghiệm AngularJS E2E hiện có được gọi là “Angular Scenario Runner”.
Nó cũng hoạt động như một bộ tích hợp giải pháp kết hợp các công nghệ mạnh mẽ như NodeJS, Selenium, Jasmine, WebDriver, Cucumber, Mocha, v.v. Cùng với việc thử nghiệm ứng dụng AngularJS, nó cũng viết các bài kiểm tra hồi quy tự động cho các ứng dụng web thông thường. Nó cho phép chúng tôi kiểm tra ứng dụng của mình giống như một người dùng thực vì nó chạy thử nghiệm bằng trình duyệt thực tế.
Sơ đồ sau đây sẽ cung cấp một cái nhìn tổng quan ngắn gọn về Thước đo góc -
Quan sát rằng trong sơ đồ trên, chúng ta có -
Protractor - Như đã thảo luận trước đó, nó là một trình bao bọc trên WebDriver JS đặc biệt được thiết kế cho các ứng dụng góc cạnh.
Jasmine- Về cơ bản, nó là một khung phát triển theo hướng hành vi để kiểm tra mã JavaScript. Chúng ta có thể viết các bài kiểm tra một cách dễ dàng với Jasmine.
WebDriver JS - Nó là một triển khai liên kết Node JS cho selenium 2.0 / WebDriver.
Selenium - Nó chỉ đơn giản là tự động hóa trình duyệt.
Gốc
Như đã nói trước đó, Thước đo góc là sự thay thế cho khung thử nghiệm AngularJS E2E hiện có được gọi là “Angular Scenario Runner”. Về cơ bản, nguồn gốc của Protractor bắt đầu từ phần cuối của Scenario Runner. Một câu hỏi được đặt ra ở đây là tại sao chúng ta cần xây dựng Thước đo góc? Để hiểu điều này, trước tiên chúng ta cần kiểm tra về người tiền nhiệm của nó - Scenario Runner.
Sự khởi đầu của thước đo góc
Julie Ralph, người đóng góp chính cho sự phát triển của Thước đo góc, đã có kinh nghiệm sau đây với Angular Scenario Runner trong dự án khác của Google. Điều này càng trở thành động lực để xây dựng Thước đo góc, đặc biệt để lấp đầy những khoảng trống -
“Chúng tôi đã thử sử dụng Scenario Runner và chúng tôi nhận thấy rằng nó thực sự không thể làm được những thứ mà chúng tôi cần kiểm tra. Chúng tôi cần kiểm tra những thứ như đăng nhập. Trang đăng nhập của bạn không phải là trang Angular và Scenario Runner không thể giải quyết điều đó. Và nó không thể giải quyết những thứ như cửa sổ bật lên và nhiều cửa sổ, điều hướng lịch sử trình duyệt, những thứ tương tự. "
Ưu điểm lớn nhất của Thước đo góc là sự trưởng thành của dự án Selenium và nó kết thúc các phương pháp của nó để có thể dễ dàng sử dụng cho các dự án Angular. Thiết kế của Protractor được xây dựng theo cách mà nó kiểm tra tất cả các lớp như giao diện người dùng web, dịch vụ phụ trợ, lớp liên tục, v.v. của một ứng dụng.
Tại sao thước đo góc?
Như chúng ta biết rằng hầu hết các ứng dụng đang sử dụng JavaScript để phát triển. Nhiệm vụ của người kiểm thử trở nên khó khăn khi JavaScript tăng kích thước và trở nên phức tạp đối với các ứng dụng do số lượng ứng dụng ngày càng tăng. Hầu hết các trường hợp trở nên rất khó nắm bắt các phần tử web trong ứng dụng AngularJS, sử dụng cú pháp HTML mở rộng để thể hiện các thành phần ứng dụng web bằng cách sử dụng JUnit hoặc Selenium WebDriver.
Câu hỏi đặt ra ở đây là tại sao Selenium Web Driver không thể tìm thấy các phần tử web AngularJS? Lý do là vì các ứng dụng AngularJS đang có một số thuộc tính HTML mở rộng như ng-repeater, ng-controller và ng-model, v.v. không có trong bộ định vị Selenium.
Ở đây, tầm quan trọng của Thước đo góc xuất hiện vì Thước đo góc trên đỉnh Selenium có thể xử lý và kiểm soát các phần tử HTML mở rộng đó trong các ứng dụng web AngularJS. Đó là lý do tại sao chúng ta có thể nói rằng hầu hết các framework đều tập trung vào việc thực hiện các bài kiểm tra đơn vị cho các ứng dụng AngularJS, Thước đo góc được sử dụng để kiểm tra chức năng thực tế của một ứng dụng.
Làm việc của thước đo góc
Protractor, khung kiểm tra, hoạt động cùng với Selenium để cung cấp cơ sở hạ tầng kiểm tra tự động để mô phỏng tương tác của người dùng với ứng dụng AngularJS đang chạy trong trình duyệt hoặc thiết bị di động.
Hoạt động của Thước đo góc có thể được hiểu với sự trợ giúp của các bước sau:
Step 1- Bước đầu tiên, chúng ta cần viết các bài kiểm tra. Nó có thể được thực hiện với sự giúp đỡ của Jasmine hoặc Mocha hoặc Dưa chuột.
Step 2- Bây giờ, chúng ta cần chạy thử nghiệm có thể được thực hiện với sự trợ giúp của Thước đo góc. Nó còn được gọi là người chạy thử nghiệm.
Step 3 - Ở bước này, máy chủ Selenium sẽ giúp quản lý các trình duyệt.
Step 4 - Cuối cùng, các API của trình duyệt được gọi với sự trợ giúp của Selenium WebDriver.
Ưu điểm
Khung thử nghiệm end-to-end mã nguồn mở này cung cấp những ưu điểm sau:
Một công cụ mã nguồn mở, Thước đo góc rất dễ cài đặt và thiết lập.
Hoạt động tốt với khuôn khổ Jasmine để tạo thử nghiệm.
Hỗ trợ phát triển theo hướng thử nghiệm (TDD).
Chứa các lượt chờ tự động có nghĩa là chúng ta không cần thêm các lượt đợi và chế độ chờ một cách rõ ràng vào thử nghiệm của mình.
Cung cấp tất cả các ưu điểm của Selenium WebDriver.
Hỗ trợ kiểm tra song song qua nhiều trình duyệt.
Cung cấp lợi ích của tự động đồng bộ hóa.
Có tốc độ kiểm tra tuyệt vời.
Hạn chế
Khung thử nghiệm end-to-end mã nguồn mở này có các hạn chế sau:
Không phát hiện ra bất kỳ ngành dọc nào trong tự động hóa trình duyệt vì nó là trình bao bọc cho WebDriver JS.
Kiến thức về JavaScript là điều cần thiết cho người dùng, vì nó chỉ có sẵn cho JavaScript.
Chỉ cung cấp thử nghiệm giao diện người dùng vì nó là một công cụ thử nghiệm theo hướng giao diện người dùng.
Vì kiến thức về JavaScript rất cần thiết để làm việc với Thước đo góc, nên trong chương này, chúng ta hãy hiểu chi tiết các khái niệm về kiểm thử JavaScript.
Kiểm tra và tự động hóa JavaScript
JavaScript là ngôn ngữ kịch bản được đánh máy và thông dịch động phổ biến nhất, nhưng nhiệm vụ thách thức nhất là kiểm tra mã. Đó là bởi vì, không giống như các ngôn ngữ biên dịch khác như JAVA và C ++, không có bước biên dịch nào trong JavaScript có thể giúp người kiểm tra tìm ra lỗi. Bên cạnh đó, kiểm tra dựa trên trình duyệt rất mất thời gian; do đó cần có các công cụ hỗ trợ kiểm tra tự động cho JavaScript.
Các khái niệm về kiểm tra tự động
Luôn luôn là một thực hành tốt để viết bài kiểm tra vì nó làm cho mã tốt hơn; vấn đề với kiểm tra thủ công là nó hơi tốn thời gian và dễ xảy ra lỗi. Quá trình kiểm tra thủ công cũng khá nhàm chán đối với lập trình viên vì họ cần phải lặp lại quy trình, viết thông số kỹ thuật kiểm tra, thay đổi mã và làm mới trình duyệt nhiều lần. Bên cạnh đó, kiểm thử thủ công cũng làm chậm quá trình phát triển.
Do những lý do trên, luôn hữu ích khi có một số công cụ có thể tự động hóa các bài kiểm tra này và giúp các lập trình viên thoát khỏi những bước lặp đi lặp lại và nhàm chán này. Nhà phát triển nên làm gì để làm cho quá trình thử nghiệm trở nên tự động?
Về cơ bản, một nhà phát triển có thể triển khai bộ công cụ trong CLI (Bộ thông dịch dòng lệnh) hoặc trong IDE phát triển (Môi trường phát triển tích hợp). Sau đó, các bài kiểm tra này sẽ chạy liên tục trong một quy trình riêng biệt ngay cả khi không có đầu vào từ nhà phát triển. Kiểm tra tự động JavaScript cũng không phải là mới và rất nhiều công cụ như Karma, Protractor, CasperJS, v.v. đã được phát triển.
Các loại kiểm tra cho JavaScript
Có thể có các bài kiểm tra khác nhau cho các mục đích khác nhau. Ví dụ: một số bài kiểm tra được viết để kiểm tra hoạt động của các chức năng trong một chương trình, trong khi một số bài kiểm tra khác được viết để kiểm tra luồng của một mô-đun hoặc tính năng. Do đó, chúng tôi có hai loại kiểm tra sau:
Kiểm tra đơn vị
Việc kiểm tra được thực hiện trên phần nhỏ nhất có thể kiểm tra được của chương trình được gọi là đơn vị. Về cơ bản, thiết bị được thử nghiệm độc lập mà không có bất kỳ loại phụ thuộc nào của thiết bị đó vào các bộ phận khác. Trong trường hợp JavaScript, phương thức hoặc hàm riêng lẻ có một hành vi cụ thể có thể là một đơn vị mã và các đơn vị mã này phải được kiểm tra theo cách riêng biệt.
Một trong những ưu điểm của kiểm thử đơn vị là việc kiểm thử các đơn vị có thể được thực hiện theo bất kỳ trình tự nào vì các đơn vị này độc lập với nhau. Một ưu điểm khác của kiểm thử đơn vị thực sự quan trọng là nó có thể chạy kiểm tra bất kỳ lúc nào như sau:
- Ngay từ đầu của quá trình phát triển.
- Sau khi hoàn thành việc phát triển bất kỳ mô-đun / tính năng nào.
- Sau khi sửa đổi bất kỳ mô-đun / tính năng nào.
- Sau khi thêm bất kỳ tính năng mới nào trong ứng dụng hiện có.
Để kiểm tra đơn vị tự động của các ứng dụng JavaScript, chúng tôi có thể chọn từ nhiều công cụ và khuôn khổ kiểm tra như Mocha, Jasmine và QUnit.
Kiểm tra từ đầu đến cuối
Nó có thể được định nghĩa là phương pháp thử nghiệm được sử dụng để kiểm tra xem luồng của ứng dụng từ đầu đến cuối (từ đầu này đến đầu kia) có hoạt động tốt theo thiết kế hay không.
Kiểm thử end-to-end còn được gọi là kiểm thử chức năng / luồng. Không giống như kiểm thử đơn vị, kiểm thử đầu cuối kiểm tra cách các thành phần riêng lẻ hoạt động cùng nhau như một ứng dụng. Đây là điểm khác biệt chính giữa kiểm thử đơn vị và kiểm thử đầu cuối.
Ví dụ: giả sử nếu chúng tôi có một mô-đun đăng ký mà người dùng cần cung cấp một số thông tin hợp lệ để hoàn tất việc đăng ký thì quá trình kiểm tra E2E cho mô-đun cụ thể đó sẽ thực hiện theo các bước sau để hoàn tất kiểm tra -
- Đầu tiên, nó sẽ tải / biên dịch biểu mẫu hoặc mô-đun.
- Bây giờ, nó sẽ lấy DOM (Mô hình đối tượng tài liệu) của các phần tử của biểu mẫu.
- Tiếp theo, kích hoạt sự kiện nhấp vào nút gửi để kiểm tra xem nó có hoạt động hay không.
- Bây giờ, với mục đích xác nhận, hãy thu thập giá trị từ các trường đầu vào.
- Tiếp theo, các trường đầu vào phải được xác thực.
- Với mục đích thử nghiệm, hãy gọi một API giả để lưu trữ dữ liệu.
Mỗi bước đưa ra kết quả của riêng nó sẽ được so sánh với tập kết quả mong đợi.
Bây giờ, câu hỏi được đặt ra là, trong khi loại E2E hoặc thử nghiệm chức năng này cũng có thể được thực hiện theo cách thủ công, tại sao chúng ta cần tự động hóa cho việc này? Lý do chính là tự động hóa sẽ giúp quá trình kiểm tra này trở nên dễ dàng. Một số công cụ có sẵn có thể dễ dàng tích hợp với bất kỳ ứng dụng nào, cho mục đích này là Selenium, PhantomJS và Protractor.
Công cụ & Khung kiểm tra
Chúng tôi có nhiều công cụ và khuôn khổ thử nghiệm khác nhau để thử nghiệm Angular. Sau đây là một số công cụ và khuôn khổ nổi tiếng -
Nghiệp
Karma, được tạo ra bởi Vojta Jina, là một người chạy thử nghiệm. Ban đầu dự án này được gọi là Testacular. Nó không phải là một khung thử nghiệm, có nghĩa là nó cung cấp cho chúng tôi khả năng dễ dàng và tự động chạy các thử nghiệm đơn vị JavaScript trên các trình duyệt thực. Karma được xây dựng cho AngularJS vì trước Karma không có công cụ kiểm tra tự động nào dành cho các nhà phát triển JavaScript dựa trên web. Mặt khác, với sự tự động hóa do Karma cung cấp, các nhà phát triển có thể chạy một lệnh đơn giản và xác định xem toàn bộ bộ thử nghiệm đã đạt hay không.
Ưu điểm của việc sử dụng Karma
Sau đây là một số ưu điểm của việc sử dụng Karma so với quy trình thủ công -
- Tự động kiểm tra trên nhiều trình duyệt cũng như thiết bị.
- Theo dõi các tập tin để tìm lỗi và sửa chúng.
- Cung cấp hỗ trợ trực tuyến và tài liệu.
- Dễ dàng tích hợp với một máy chủ tích hợp liên tục.
Nhược điểm của việc sử dụng Karma
Sau đây là một số nhược điểm của việc sử dụng Karma:
Nhược điểm chính của việc sử dụng Karma là nó yêu cầu một công cụ bổ sung để cấu hình và bảo trì.
Nếu bạn đang sử dụng Karma test runner với Jasmine, thì sẽ có ít tài liệu hơn để tìm thông tin về cách thiết lập CSS của bạn trong trường hợp có nhiều id cho một phần tử.
Hoa nhài
Jasmine, một khung phát triển theo hướng hành vi để kiểm tra mã JavaScript, được phát triển tại Pivotal Labs. Trước khi có sự phát triển tích cực của khuôn khổ Jasmine, một khuôn khổ thử nghiệm đơn vị tương tự có tên là JsUnit cũng đã được phát triển bởi Pivotal Labs, có một trình chạy thử nghiệm có sẵn. Các bài kiểm tra trình duyệt có thể được chạy thông qua các bài kiểm tra Jasmine bằng cách bao gồm tệp SpecRunner.html hoặc bằng cách sử dụng nó như một trình chạy kiểm tra dòng lệnh. Nó có thể được sử dụng có hoặc không có Karma cũng được.
Ưu điểm của việc sử dụng hoa nhài
Sau đây là một số ưu điểm của việc sử dụng Jasmine -
Một khuôn khổ độc lập với trình duyệt, nền tảng và ngôn ngữ.
Hỗ trợ phát triển theo hướng kiểm tra (TDD) cùng với phát triển theo hướng hành vi.
Có tích hợp mặc định với Karma.
Cú pháp dễ hiểu.
Cung cấp các chức năng gián điệp kiểm tra, giả mạo và chuyển qua hỗ trợ kiểm tra như các chức năng bổ sung.
Nhược điểm của việc sử dụng hoa nhài
Sau đây là một mẹo sử dụng Jasmine -
Người dùng phải trả lại các bài kiểm tra khi chúng thay đổi vì không có tính năng xem tệp nào khả dụng trong Jasmine khi đang chạy thử nghiệm.
Mocha
Mocha, được viết cho các ứng dụng Node.js, là một khung thử nghiệm nhưng nó cũng hỗ trợ thử nghiệm trình duyệt. Nó khá giống Jasmine nhưng sự khác biệt chính giữa chúng là Mocha cần một số plugin và thư viện vì nó không thể chạy độc lập như một khung thử nghiệm. Mặt khác, Jasmine là độc lập. Tuy nhiên, Mocha sử dụng linh hoạt hơn Jasmine.
Ưu điểm của việc sử dụng Mocha
Sau đây là một số ưu điểm của việc sử dụng Mocha:
- Mocha rất dễ cài đặt và cấu hình.
- Tài liệu thân thiện với người dùng và đơn giản.
- Chứa các plugin với một số dự án nút.
Nhược điểm của việc sử dụng Mocha
Sau đây là một số nhược điểm của việc sử dụng Mocha:
- Nó cần các mô-đun riêng biệt để xác nhận, gián điệp, v.v.
- Nó cũng yêu cầu cấu hình bổ sung để sử dụng với Karma.
QUnit
QUint, ban đầu được phát triển bởi John Resig vào năm 2008 như một phần của jQuery, là một bộ thử nghiệm đơn vị JavaScript mạnh mẽ nhưng dễ sử dụng. Nó có thể được sử dụng để kiểm tra bất kỳ mã JavaScript chung nào. Mặc dù nó tập trung vào việc thử nghiệm JavaScript trong trình duyệt, nhưng nó rất thuận tiện để sử dụng bởi nhà phát triển.
Ưu điểm của việc sử dụng QUnit
Sau đây là một số ưu điểm của việc sử dụng QUnit:
- Dễ dàng cài đặt và cấu hình.
- Tài liệu thân thiện với người dùng và đơn giản.
Nhược điểm của việc sử dụng QUnit
Sau đây là một vấn đề của việc sử dụng QUnit:
- Nó chủ yếu được phát triển cho jQuery và do đó không tốt để sử dụng với các khung công tác khác.
Selen
Selenium, ban đầu được phát triển bởi Jason Huggins vào năm 2004 như một công cụ nội bộ tại ThoughtWorks, là một công cụ tự động hóa thử nghiệm mã nguồn mở. Selenium tự định nghĩa là “Selenium tự động hóa các trình duyệt. Đó là nó!". Tự động hóa các trình duyệt có nghĩa là các nhà phát triển có thể tương tác với các trình duyệt rất dễ dàng.
Ưu điểm của việc sử dụng Selenium
Sau đây là một số ưu điểm của việc sử dụng Selenium:
- Chứa bộ tính năng lớn.
- Hỗ trợ thử nghiệm phân tán.
- Có hỗ trợ SaaS thông qua các dịch vụ như Sauce Labs.
- Dễ sử dụng với các tài liệu đơn giản và nguồn tài nguyên phong phú có sẵn.
Nhược điểm của việc sử dụng Selenium
Sau đây là một số nhược điểm của việc sử dụng Selenium:
- Một nhược điểm chính của việc sử dụng Selenium là nó phải được chạy như một quá trình riêng biệt.
- Cấu hình hơi rườm rà vì nhà phát triển cần thực hiện theo một số bước.
Ở các chương trước, chúng ta đã tìm hiểu những kiến thức cơ bản về Thước đo góc. Trong chương này, chúng ta hãy tìm hiểu cách cài đặt và cấu hình nó.
Điều kiện tiên quyết
Chúng tôi cần đáp ứng các điều kiện tiên quyết sau trước khi cài đặt Thước đo góc trên máy tính của bạn -
Node.js
Thước đo góc là một mô-đun Node.js, do đó điều kiện tiên quyết rất quan trọng là chúng ta phải cài đặt Node.js trên máy tính của mình. Chúng tôi sẽ cài đặt gói Protractor bằng npm (một trình quản lý gói JavaScript), đi kèm với Node.js.
Để cài đặt Node.js, vui lòng theo liên kết chính thức - https://nodejs.org/en/download/. Sau khi cài đặt Node.js, bạn có thể kiểm tra phiên bản của Node.js và npm bằng cách viết lệnhnode --version và npm --version trong dấu nhắc lệnh như hình dưới đây -
Trình duyệt Chrome
Google Chrome, một trình duyệt web do Google xây dựng, sẽ được sử dụng để chạy các bài kiểm tra end-to-end trong Protractor mà không cần máy chủ Selenium. Bạn có thể tải xuống chrome bằng cách nhấp vào liên kết -https://www.google.com/chrome/.
Selenium WebDriver dành cho Chrome
Công cụ này được cung cấp cùng với mô-đun Protractor npm và cho phép chúng tôi tương tác với các ứng dụng web.
Cài đặt thước đo góc
Sau khi cài đặt Node.js trên máy tính, chúng ta có thể cài đặt Thước đo góc với sự trợ giúp của lệnh sau:
npm install -g protractor
Khi thước đo góc được cài đặt thành công, chúng tôi có thể kiểm tra phiên bản của nó bằng cách viết protractor --version lệnh trong dấu nhắc lệnh như hình dưới đây:
Cài đặt WebDriver cho Chrome
Sau khi cài đặt Protractor, chúng ta cần cài đặt Selenium WebDriver cho Chrome. Nó có thể được cài đặt với sự trợ giúp của lệnh sau:
webdriver-manager update
Lệnh trên sẽ tạo một thư mục Selenium chứa trình điều khiển Chrome cần thiết được sử dụng trong dự án.
Xác nhận Cài đặt & Cấu hình
Chúng ta có thể xác nhận cài đặt và cấu hình trên Protractor bằng cách thay đổi một chút conf.js được cung cấp trong ví dụ sau khi cài đặt Protractor. Bạn có thể tìm thấy tệp conf.js này trong thư mục gốcnode_modules/Protractor/example.
Đối với điều này, trước tiên hãy tạo một tệp mới có tên testingconfig.js trong cùng một thư mục, tức là node_modules/Protractor/example.
Bây giờ, trong tệp conf.js, dưới tham số khai báo tệp nguồn, hãy viết testingconfig.js.
Tiếp theo, lưu và đóng tất cả các tệp và mở dấu nhắc lệnh. Chạy tệp conf.js như được hiển thị trong ảnh chụp màn hình bên dưới.
Cấu hình và cài đặt Thước đo góc thành công nếu bạn nhận được kết quả như hình dưới đây -
Kết quả ở trên cho thấy rằng không có đặc tả vì chúng tôi đã cung cấp tệp trống tại tham số khai báo tệp nguồn trong tệp conf.js. Nhưng từ kết quả trên, chúng ta có thể thấy rằng cả thước đo góc và WebDriver đều đang chạy thành công.
Vấn đề về cài đặt và cấu hình
Trong khi cài đặt và cấu hình Protractor và WebDriver, chúng ta có thể gặp các sự cố phổ biến sau:
Selenium không được cài đặt đúng cách
Đây là vấn đề phổ biến nhất khi cài đặt WebDriver. Sự cố này phát sinh nếu bạn không cập nhật WebDriver. Lưu ý rằng chúng ta phải cập nhật WebDriver, nếu không chúng ta sẽ không thể tham chiếu nó đến cài đặt Thước đo góc.
Không thể tìm thấy các bài kiểm tra
Một vấn đề phổ biến khác là sau khi chạy Thước đo góc, nó cho thấy rằng không thể tìm thấy các bài kiểm tra. Đối với điều này, chúng tôi phải đảm bảo rằng các đường dẫn, tên tệp hoặc phần mở rộng tương đối là chính xác. Chúng ta cũng cần ghi tệp conf.js rất cẩn thận vì nó bắt đầu bằng chính tệp cấu hình.
Như đã thảo luận trước đó, Protractor là một khung thử nghiệm mã nguồn mở, end-to-end dành cho các ứng dụng Angular và AngularJS. Đó là chương trình Node.js. Mặt khác, Selenium là một khung tự động hóa trình duyệt bao gồm Máy chủ Selenium, các API WebDriver và trình điều khiển trình duyệt WebDriver.
Thước đo góc với Selenium
Nếu chúng ta nói về sự kết hợp của Protractor và Selenium, thì Protractor có thể làm việc với máy chủ Selenium để cung cấp cơ sở hạ tầng kiểm tra tự động. Cơ sở hạ tầng có thể mô phỏng tương tác của người dùng với một ứng dụng góc cạnh đang chạy trong trình duyệt hoặc trên thiết bị di động. Sự kết hợp của Thước đo góc và Selenium có thể được chia thành ba phân vùng cụ thể là kiểm tra, máy chủ và Trình duyệt, như được hiển thị trong sơ đồ sau:
Quy trình Selenium WebDriver
Như chúng ta đã thấy trong sơ đồ trên, một bài kiểm tra sử dụng Selenium WebDriver bao gồm ba quy trình sau:
- Các tập lệnh thử nghiệm
- Máy chủ
- Trình duyệt
Trong phần này, chúng ta hãy thảo luận về sự giao tiếp giữa ba quá trình này.
Giao tiếp giữa tập lệnh thử nghiệm và máy chủ
Giao tiếp giữa hai quy trình đầu tiên - các tập lệnh thử nghiệm và máy chủ phụ thuộc vào hoạt động của Máy chủ Selenium. Nói cách khác, chúng ta có thể nói rằng cách máy chủ Selenium đang chạy sẽ tạo ra hình dạng cho quá trình giao tiếp giữa các tập lệnh thử nghiệm và máy chủ.
Máy chủ Selenium có thể chạy cục bộ trên máy của chúng tôi dưới dạng Máy chủ Selenium độc lập (selenium-server-standalone.jar) hoặc nó có thể chạy từ xa thông qua một dịch vụ (Sauce Labs). Trong trường hợp máy chủ Selenium độc lập, sẽ có một giao tiếp http giữa Node.js và máy chủ selen.
Giao tiếp giữa máy chủ và trình duyệt
Như chúng ta biết rằng máy chủ chịu trách nhiệm chuyển tiếp các lệnh tới trình duyệt sau khi thông dịch giống nhau từ các tập lệnh thử nghiệm. Đó là lý do tại sao máy chủ và trình duyệt cũng yêu cầu một phương tiện giao tiếp và ở đây việc giao tiếp được thực hiện với sự trợ giúp củaJSON WebDriver Wire Protocol. Trình duyệt mở rộng với Trình điều khiển Trình duyệt được sử dụng để diễn giải các lệnh.
Khái niệm trên về các quy trình Selenium WebDriver và giao tiếp của chúng có thể được hiểu với sự trợ giúp của sơ đồ sau:
Trong khi làm việc với Protractor, quá trình đầu tiên, đó là tập lệnh thử nghiệm được chạy bằng Node.js nhưng trước khi thực hiện bất kỳ hành động nào trên trình duyệt, nó sẽ gửi thêm một lệnh để đảm bảo rằng ứng dụng đang được thử nghiệm được ổn định.
Thiết lập máy chủ Selenium
Selenium Server hoạt động giống như một máy chủ proxy giữa tập lệnh thử nghiệm của chúng tôi và trình điều khiển trình duyệt. Về cơ bản, nó chuyển tiếp lệnh từ tập lệnh thử nghiệm của chúng tôi tới WebDriver và trả về các phản hồi từ WebDriver tới tập lệnh thử nghiệm của chúng tôi. Có các tùy chọn sau để thiết lập máy chủ Selenium được bao gồm trongconf.js tệp kịch bản thử nghiệm -
Máy chủ Selenium độc lập
Nếu chúng ta muốn chạy máy chủ trên máy cục bộ của mình, chúng ta cần cài đặt máy chủ selen độc lập. Điều kiện tiên quyết để cài đặt máy chủ selen độc lập là JDK (Bộ phát triển Java). Chúng ta phải cài đặt JDK trên máy cục bộ của mình. Chúng ta có thể kiểm tra nó bằng cách chạy lệnh sau từ dòng lệnh:
java -version
Bây giờ, chúng tôi có tùy chọn cài đặt và khởi động Selenium Server theo cách thủ công hoặc từ tập lệnh thử nghiệm.
Cài đặt và khởi động máy chủ Selenium theo cách thủ công
Để cài đặt và khởi động máy chủ Selenium theo cách thủ công, chúng ta cần sử dụng công cụ dòng lệnh WebDriver-Manager đi kèm với Thước đo. Các bước cài đặt và khởi động máy chủ Selenium như sau:
Step 1- Bước đầu tiên là cài đặt máy chủ Selenium và ChromeDriver. Nó có thể được thực hiện với sự trợ giúp của việc chạy lệnh sau:
webdriver-manager update
Step 2- Tiếp theo, chúng ta cần khởi động máy chủ. Nó có thể được thực hiện với sự trợ giúp của việc chạy lệnh sau:
webdriver-manager start
Step 3- Cuối cùng, chúng ta cần đặt seleniumAddress trong tệp cấu hình thành địa chỉ của máy chủ đang chạy. Địa chỉ mặc định sẽ làhttp://localhost:4444/wd/hub.
Khởi động máy chủ Selenium từ Tập lệnh thử nghiệm
Để khởi động máy chủ Selenium từ Tập lệnh thử nghiệm, chúng tôi cần đặt các tùy chọn sau trong tệp cấu hình của mình:
Location of jar file - Chúng ta cần đặt vị trí của tệp jar cho máy chủ Selenium độc lập trong tệp cấu hình bằng cách đặt seleniumServerJar.
Specifying the port- Chúng ta cũng cần chỉ định cổng sử dụng để khởi động Máy chủ Selenium độc lập. Nó có thể được chỉ định trong tệp cấu hình bằng cách thiết lập seleniumPort. Cổng mặc định là 4444.
Array of command line options- Chúng ta cũng cần thiết lập mảng tùy chọn dòng lệnh để chuyển đến máy chủ. Nó có thể được chỉ định trong tệp cấu hình bằng cách đặt seleniumArgs. Nếu bạn cần danh sách đầy đủ các dãy lệnh, thì hãy khởi động máy chủ với-help cờ.
Làm việc với Máy chủ Selenium Từ xa
Một tùy chọn khác để chạy thử nghiệm của chúng tôi là sử dụng máy chủ Selenium từ xa. Điều kiện tiên quyết để sử dụng máy chủ từ xa là chúng ta phải có tài khoản với dịch vụ lưu trữ máy chủ. Trong khi làm việc với Thước đo góc, chúng tôi có hỗ trợ tích hợp cho các dịch vụ sau lưu trữ máy chủ -
TestObject
Để sử dụng TestObject làm Máy chủ Selenium từ xa, chúng tôi cần đặt testobjectUser, tên người dùng của tài khoản TestObject và testobjectKey, khóa API của tài khoản TestObject của chúng tôi.
BrowserStack
Để sử dụng BrowserStack làm Máy chủ Selenium từ xa, chúng tôi cần đặt browserstackUser, tên người dùng của tài khoản BrowserStack và browserstackKey, khóa API của tài khoản BrowserStack của chúng tôi.
Phòng thí nghiệm nước sốt
Để sử dụng Sauce Labs làm Máy chủ Selenium từ xa, chúng tôi cần đặt sauceUser, tên người dùng của tài khoản Sauce Labs và SauceKey, khóa API của tài khoản Sauce Labs của chúng tôi.
Kobiton
Để sử dụng Kobiton làm Máy chủ Selenium từ xa, chúng ta cần đặt kobitonUser, tên người dùng của tài khoản Kobiton và kobitonKey, khóa API của tài khoản Kobiton của chúng ta.
Kết nối trực tiếp với Trình điều khiển trình duyệt mà không cần sử dụng Máy chủ Selenium
Một tùy chọn nữa để chạy thử nghiệm của chúng tôi là kết nối trực tiếp với Trình điều khiển trình duyệt mà không cần sử dụng máy chủ Selenium. Thước đo góc có thể kiểm tra trực tiếp mà không cần sử dụng Máy chủ Selenium, chống lại Chrome và Firefox bằng cách thiết lập directConnect: true trong tệp cấu hình.
Thiết lập trình duyệt
Trước khi cấu hình và thiết lập trình duyệt, chúng ta cần biết những trình duyệt nào được hỗ trợ bởi Protractor. Sau đây là danh sách các trình duyệt được hỗ trợ bởi Protractor:
- ChromeDriver
- FirefoxDriver
- SafariDriver
- IEDriver
- Appium-iOS/Safari
- Appium-Android/Chrome
- Selendroid
- PhantomJS
Để thiết lập và cấu hình trình duyệt, chúng ta cần chuyển sang tệp cấu hình của Thước đo vì việc thiết lập trình duyệt được thực hiện trong đối tượng khả năng của tệp cấu hình.
Thiết lập Chrome
Để thiết lập Trình duyệt Chrome, chúng ta cần đặt đối tượng khả năng như sau
capabilities: {
'browserName': 'chrome'
}
Chúng tôi cũng có thể thêm các tùy chọn dành riêng cho Chrome được lồng trong chromeOptions và danh sách đầy đủ của nó có thể được xem tại https://sites.google.com/a/chromium.org/chromedriver/capabilities.
Ví dụ: nếu bạn muốn thêm bộ đếm FPS ở phía trên bên phải, thì có thể thực hiện như sau trong tệp cấu hình:
capabilities: {
'browserName': 'chrome',
'chromeOptions': {
'args': ['show-fps-counter=true']
}
},
Thiết lập Firefox
Để thiết lập trình duyệt Firefox, chúng ta cần đặt đối tượng khả năng như sau:
capabilities: {
'browserName': 'firefox'
}
Chúng tôi cũng có thể thêm các tùy chọn dành riêng cho Firefox được lồng trong đối tượng moz: firefoxOptions và danh sách đầy đủ của nó có thể được xem tại https://github.com/mozilla/geckodriver#firefox-capabilities.
Ví dụ: nếu bạn muốn chạy thử nghiệm của mình trên Firefox ở chế độ an toàn thì bạn có thể thực hiện như sau trong tệp cấu hình:
capabilities: {
'browserName': 'firefox',
'moz:firefoxOptions': {
'args': ['—safe-mode']
}
},
Thiết lập trình duyệt khác
Để thiết lập bất kỳ trình duyệt nào khác ngoài Chrome hoặc Firefox, chúng tôi cần cài đặt một tệp nhị phân riêng từ https://docs.seleniumhq.org/download/.
Thiết lập PhantonJS
Trên thực tế, PhantomJS không còn được hỗ trợ vì sự cố của nó. Thay vào đó, bạn nên sử dụng Chrome không đầu hoặc Firefox không đầu. Chúng có thể được thiết lập như sau:
Để thiết lập Chrome không đầu, chúng ta cần khởi động Chrome bằng cờ – không đầu như sau:
capabilities: {
'browserName': 'chrome',
'chromeOptions': {
'args': [“--headless”, “--disable-gpu”, “--window-size=800,600”]
}
},
Để thiết lập Firefox không đầu, chúng ta cần khởi động Firefox với –headless cờ như sau -
capabilities: {
'browserName': 'firefox',
'moz:firefoxOptions': {
'args': [“--headless”]
}
},
Thiết lập nhiều trình duyệt để thử nghiệm
Chúng tôi cũng có thể kiểm tra trên nhiều trình duyệt. Đối với điều này, chúng tôi cần sử dụng tùy chọn cấu hình multiCapabilities như sau:
multiCapabilities: [{
'browserName': 'chrome'
},{
'browserName': 'firefox'
}]
Khung nào?
Hai khung thử nghiệm BDD (Phát triển theo hướng hành vi), Jasmine và Mocha được hỗ trợ bởi Protractor. Cả hai framework đều dựa trên JavaScript và Node.js. Các khuôn khổ này cung cấp cú pháp, báo cáo và khung, cần thiết cho việc viết và quản lý các bài kiểm tra.
Tiếp theo, chúng tôi xem cách chúng tôi có thể cài đặt các khung công tác khác nhau -
Hoa nhài khung
Nó là khung thử nghiệm mặc định cho Thước đo góc. Khi bạn cài đặt Protractor, bạn sẽ nhận được phiên bản Jasmine 2.x với nó. Chúng tôi không cần phải cài đặt riêng nó.
Khuôn khổ Mocha
Mocha là một khung kiểm tra JavaScript khác về cơ bản chạy trên Node.js. Để sử dụng Mocha làm khung thử nghiệm của chúng tôi, chúng tôi cần sử dụng giao diện BDD (Phát triển theo hướng hành vi) và xác nhận Chai với Chai As Promised. Việc cài đặt có thể được thực hiện với sự trợ giúp của các lệnh sau:
npm install -g mocha
npm install chai
npm install chai-as-promised
Như bạn có thể thấy, tùy chọn -g được sử dụng trong khi cài đặt mocha, đó là vì chúng tôi đã cài đặt Thước đo trên toàn cầu bằng tùy chọn -g. Sau khi cài đặt nó, chúng tôi cần yêu cầu và thiết lập Chai bên trong các tệp thử nghiệm của chúng tôi. Nó có thể được thực hiện như sau:
var chai = require('chai');
var chaiAsPromised = require('chai-as-promised');
chai.use(chaiAsPromised);
var expect = chai.expect;
Sau đó, chúng ta có thể sử dụng Chai As Promised như vậy -
expect(myElement.getText()).to.eventually.equal('some text');
Bây giờ, chúng ta cần đặt thuộc tính khung thành mocha của tệp cấu hình bằng cách thêm khung: 'mocha'. Các tùy chọn như 'report' và 'slow' cho mocha có thể được thêm vào tệp cấu hình như sau:
mochaOpts: {
reporter: "spec", slow: 3000
}
Khuôn khổ dưa chuột
Để sử dụng Cucumber làm khung thử nghiệm của chúng tôi, chúng tôi cần tích hợp nó với Thước đo góc với tùy chọn khung custom. Việc cài đặt có thể được thực hiện với sự trợ giúp của các lệnh sau
npm install -g cucumber
npm install --save-dev protractor-cucumber-framework
Như bạn có thể thấy, tùy chọn -g được sử dụng trong khi cài đặt Cucumber, đó là vì chúng tôi đã cài đặt Protractor trên toàn cầu, tức là với tùy chọn -g. Tiếp theo, chúng ta cần đặt thuộc tính khung thànhcustom của tệp cấu hình bằng cách thêm khung: 'custom' và frameworkPath: 'Protractor-Cucum-framework' vào tệp cấu hình có tên CucConf.js.
Mã mẫu được hiển thị bên dưới là một tệp CucConf.js cơ bản có thể được sử dụng để chạy các tệp tính năng của dưa chuột với Thước đo góc -
exports.config = {
seleniumAddress: 'http://localhost:4444/wd/hub',
baseUrl: 'https://angularjs.org/',
capabilities: {
browserName:'Firefox'
},
framework: 'custom',
frameworkPath: require.resolve('protractor-cucumber-framework'),
specs: [
'./cucumber/*.feature'
],
// cucumber command line options
cucumberOpts: {
require: ['./cucumber/*.js'],
tags: [],
strict: true,
format: ["pretty"],
'dry-run': false,
compiler: []
},
onPrepare: function () {
browser.manage().window().maximize();
}
};
Trong chương này, chúng ta hãy hiểu cách viết test đầu tiên trong Protractor.
Các tệp được yêu cầu bởi Thước đo góc
Thước đo góc cần hai tệp sau để chạy:
Thông số kỹ thuật hoặc tệp thử nghiệm
Nó là một trong những tệp quan trọng để chạy Thước đo góc. Trong tệp này, chúng tôi sẽ viết mã thử nghiệm thực tế của chúng tôi. Mã thử nghiệm được viết bằng cách sử dụng cú pháp của khung thử nghiệm của chúng tôi.
Ví dụ, nếu chúng ta đang sử dụng Jasmine khung, sau đó mã kiểm tra sẽ được viết bằng cách sử dụng cú pháp của Jasmine. Tệp này sẽ chứa tất cả các luồng chức năng và các xác nhận của thử nghiệm.
Nói một cách dễ hiểu, chúng ta có thể nói rằng tệp này chứa logic và bộ định vị để tương tác với ứng dụng.
Thí dụ
Sau đây là một tập lệnh đơn giản, TestSpecification.js, có trường hợp thử nghiệm để điều hướng đến một URL và kiểm tra tiêu đề trang -
//TestSpecification.js
describe('Protractor Demo', function() {
it('to check the page title', function() {
browser.ignoreSynchronization = true;
browser.get('https://www.tutorialspoint.com/tutorialslibrary.htm');
browser.driver.getTitle().then(function(pageTitle) {
expect(pageTitle).toEqual('Free Online Tutorials and Courses');
});
});
});
Giải thích mã
Mã của tệp thông số kỹ thuật trên có thể được giải thích như sau:
Trình duyệt
Nó là biến toàn cục do Protractor tạo ra để xử lý tất cả các lệnh cấp trình duyệt. Về cơ bản, nó là một trình bao bọc xung quanh một phiên bản của WebDriver. browser.get () là một phương thức Selenium đơn giản sẽ ra lệnh cho Protractor tải một trang cụ thể.
describe và it- Cả hai đều là cú pháp của khung thử nghiệm Jasmine. Các’Describe’ được sử dụng để chứa luồng end to end của test case của chúng tôi trong khi ‘it’chứa một số kịch bản thử nghiệm. Chúng ta có thể có nhiều‘it’ các khối trong chương trình trường hợp thử nghiệm của chúng tôi.
Expect - Đó là một khẳng định khi chúng tôi đang so sánh tiêu đề trang web với một số dữ liệu được xác định trước.
ignoreSynchronization- Đây là một thẻ của trình duyệt được sử dụng khi chúng tôi cố gắng kiểm tra các trang web không góc cạnh. Thước đo góc chỉ hoạt động với các trang web có góc nhưng nếu chúng tôi muốn làm việc với các trang web không có góc, thì thẻ này phải được đặt thành“true”.
Tập tin cấu hình
Như tên cho thấy, tệp này cung cấp giải thích cho tất cả các tùy chọn cấu hình Thước đo góc. Về cơ bản, nó nói với Protractor như sau:
- Nơi để tìm tệp kiểm tra hoặc thông số kỹ thuật
- Chọn trình duyệt nào
- Sử dụng khung thử nghiệm nào
- Nơi nói chuyện với Máy chủ Selenium
Thí dụ
Sau đây là tập lệnh đơn giản, config.js, có bài kiểm tra
// config.js
exports.config = {
directConnect: true,
// Capabilities to be passed to the webdriver instance.
capabilities: {
'browserName': 'chrome'
},
// Framework to use. Jasmine is recommended.
framework: 'jasmine',
// Spec patterns are relative to the current working directory when
// protractor is called.
specs: ['TestSpecification.js'],
Giải thích mã
Đoạn mã của tệp cấu hình trên có ba tham số cơ bản, có thể được giải thích như sau:
Tham số khả năng
Tham số này được sử dụng để chỉ định tên của trình duyệt. Nó có thể được nhìn thấy trong khối mã sau của tệp conf.js:
exports.config = {
directConnect: true,
// Capabilities to be passed to the webdriver instance.
capabilities: {
'browserName': 'chrome'
},
Như đã thấy ở trên, tên của trình duyệt được đưa ra ở đây là 'chrome', theo mặc định là trình duyệt cho Thước đo góc. Chúng tôi cũng có thể thay đổi tên của trình duyệt.
Tham số khung
Tham số này được sử dụng để chỉ định tên của khung thử nghiệm. Nó có thể được nhìn thấy trong khối mã sau của tệp config.js:
exports.config = {
directConnect: true,
// Framework to use. Jasmine is recommended.
framework: 'jasmine',
Ở đây chúng tôi đang sử dụng khung thử nghiệm 'jasmine'.
Tham số khai báo tệp nguồn
Tham số này được sử dụng để chỉ định tên của khai báo tệp nguồn. Nó có thể được nhìn thấy trong khối mã sau của tệp conf.js:
exports.config = {
directConnect: true,
// Spec patterns are relative to the current working
directory when protractor is called.
specs: ['TsetSpecification.js'],
Như đã thấy ở trên, tên của khai báo tệp nguồn được đưa ra ở đây là ‘TestSpecification.js’. Đó là bởi vì, đối với ví dụ này, chúng tôi đã tạo tệp đặc tả với tênTestSpecification.js.
Thực thi mã
Vì chúng ta đã hiểu cơ bản về các tệp cần thiết và mã hóa của chúng để chạy Thước đo góc, chúng ta hãy thử chạy ví dụ. Chúng ta có thể làm theo các bước sau để thực hiện ví dụ này:
Step 1 - Đầu tiên, mở dấu nhắc lệnh.
Step 2 - Tiếp theo, chúng ta cần đi đến thư mục nơi chúng ta đã lưu các tệp của mình, cụ thể là config.js và TestSpecification.js.
Step 3 - Bây giờ, thực thi tệp config.js bằng cách chạy lệnh Protrcator config.js.
Ảnh chụp màn hình được hiển thị bên dưới sẽ giải thích các bước trên để thực hiện ví dụ:
Trong ảnh chụp màn hình có thể thấy rằng bài kiểm tra đã được vượt qua.
Bây giờ, giả sử nếu chúng tôi đang kiểm tra các trang web không góc cạnh và không đặt thẻ ignoreSynchronization thành true thì sau khi thực thi mã, chúng tôi sẽ gặp lỗi "Không thể tìm thấy Angular trên trang".
Nó có thể được nhìn thấy trong ảnh chụp màn hình sau:
Tạo báo cáo
Cho đến bây giờ, chúng ta đã thảo luận về các tệp cần thiết và mã hóa của chúng để chạy các trường hợp thử nghiệm. Thước đo góc cũng có thể tạo báo cáo cho các trường hợp thử nghiệm. Vì mục đích này, nó hỗ trợ Jasmine. JunitXMLReporter có thể được sử dụng để tạo báo cáo thực thi kiểm tra tự động.
Nhưng trước đó, chúng ta cần cài đặt trình báo cáo Jasmine với sự trợ giúp của lệnh sau:
npm install -g jasmine-reporters
Như bạn có thể thấy, tùy chọn -g được sử dụng trong khi cài đặt Jasmine Reporters, đó là vì chúng tôi đã cài đặt Protractor trên toàn cầu, với tùy chọn -g.
Sau khi cài đặt thành công jasmine-Reporter, chúng tôi cần thêm mã sau vào tệp config.js đã sử dụng trước đó của chúng tôi -
onPrepare: function(){ //configure junit xml report
var jasmineReporters = require('jasmine-reporters');
jasmine.getEnv().addReporter(new jasmineReporters.JUnitXmlReporter({
consolidateAll: true,
filePrefix: 'guitest-xmloutput',
savePath: 'test/reports'
}));
Bây giờ, tệp config.js mới của chúng tôi sẽ như sau:
// An example configuration file.
exports.config = {
directConnect: true,
// Capabilities to be passed to the webdriver instance.
capabilities: {
'browserName': 'chrome'
},
// Framework to use. Jasmine is recommended.
framework: 'jasmine',
// Spec patterns are relative to the current working directory when
// protractor is called.
specs: ['TestSpecification.js'],
//framework: "jasmine2", //must set it if you use JUnitXmlReporter
onPrepare: function(){ //configure junit xml report
var jasmineReporters = require('jasmine-reporters');
jasmine.getEnv().addReporter(new jasmineReporters.JUnitXmlReporter({
consolidateAll: true,
filePrefix: 'guitest-xmloutput',
savePath: 'reports'
}));
},
};
Sau khi chạy tệp cấu hình ở trên theo cách tương tự, chúng tôi đã chạy trước đó, nó sẽ tạo tệp XML chứa báo cáo trong thư mục gốc trong reportsthư mục. Nếu kiểm tra thành công, báo cáo sẽ như sau:
Nhưng, nếu thử nghiệm không thành công, báo cáo sẽ như hình dưới đây -
Thước đo góc - APIS lõi
Chương này cho phép bạn hiểu các API cốt lõi khác nhau là chìa khóa cho hoạt động của thước đo góc.
Tầm quan trọng của API thước đo góc
Thước đo góc cung cấp cho chúng tôi một loạt các API rất quan trọng để thực hiện các hành động sau để có được trạng thái hiện tại của trang web -
- Lấy các phần tử DOM của trang web mà chúng tôi sẽ kiểm tra.
- Tương tác với các phần tử DOM.
- Chỉ định hành động cho họ.
- Chia sẻ thông tin cho họ.
Để thực hiện các nhiệm vụ trên, điều rất quan trọng là phải hiểu các API thước đo góc.
Các API thước đo góc khác nhau
Như chúng ta biết rằng Protractor là một trình bao bọc xung quanh Selenium-WebDriver, là các ràng buộc WebDriver cho Node.js. Thước đo góc có các API sau:
Trình duyệt
Nó là một trình bao bọc xung quanh một phiên bản của WebDriver được sử dụng để xử lý các lệnh cấp trình duyệt như điều hướng, thông tin trên toàn trang, v.v. Ví dụ: phương thức browser.get tải một trang.
Thành phần
Nó được sử dụng để tìm kiếm và tương tác với phần tử DOM trên trang mà chúng tôi đang thử nghiệm. Với mục đích này, nó yêu cầu một tham số để định vị phần tử.
Người định vị (bởi)
Nó là một tập hợp các chiến lược định vị phần tử. Ví dụ, các phần tử có thể được tìm thấy bằng bộ chọn CSS, theo ID hoặc bất kỳ thuộc tính nào khác mà chúng được liên kết với ng-model.
Tiếp theo, chúng ta sẽ thảo luận chi tiết về các API này và chức năng của chúng.
API trình duyệt
Như đã thảo luận ở trên, nó là một trình bao bọc xung quanh một phiên bản của WebDriver để xử lý các lệnh cấp trình duyệt. Nó thực hiện các chức năng khác nhau như sau:
Chức năng và mô tả của chúng
Các chức năng của API ProtractorBrowser như sau−
browser.angularAppRoot
Chức năng này của API trình duyệt đặt bộ chọn CSS cho một phần tử mà chúng ta sẽ tìm Angular. Thông thường, hàm này nằm trong 'body', nhưng trong trường hợp nếu ng-app của chúng ta, nó nằm trên một phần phụ của trang; nó cũng có thể là một yếu tố phụ.
browser.waitForAngularEnabled
Chức năng này của API trình duyệt có thể được đặt thành true hoặc false. Như tên cho thấy, nếu chức năng này được đặt là false thì Thước đo góc sẽ không đợi Angular$http and $các tác vụ hết thời gian cần hoàn thành trước khi tương tác với trình duyệt. Chúng ta cũng có thể đọc trạng thái hiện tại mà không cần thay đổi nó bằng cách gọi waitForAngularEnabled () mà không cần chuyển một giá trị.
browser.getProcessedConfig
Với sự trợ giúp của hàm API trình duyệt này, chúng tôi có thể nhận được đối tượng cấu hình đã xử lý, bao gồm cả đặc điểm kỹ thuật và khả năng, hiện đang được chạy.
browser.forkNewDriverInstance
Như tên cho thấy, chức năng này sẽ phân nhánh một phiên bản trình duyệt khác để được sử dụng trong các bài kiểm tra tương tác. Nó có thể được chạy với luồng điều khiển được bật và tắt. Ví dụ được đưa ra dưới đây cho cả hai trường hợp -
Example 1
Đang chạy browser.forkNewDriverInstance() có bật luồng điều khiển -
var fork = browser.forkNewDriverInstance();
fork.get(‘page1’);
Example 2
Đang chạy browser.forkNewDriverInstance() đã tắt luồng điều khiển -
var fork = await browser.forkNewDriverInstance().ready;
await forked.get(‘page1’);
browser.restart
Như tên cho thấy, nó sẽ khởi động lại trình duyệt bằng cách đóng phiên bản trình duyệt và tạo một phiên bản mới. Nó cũng có thể chạy với luồng điều khiển được bật và tắt. Ví dụ được đưa ra dưới đây cho cả hai trường hợp -
Example 1 - Đang chạy browser.restart() có bật luồng điều khiển -
browser.get(‘page1’);
browser.restart();
browser.get(‘page2’);
Example 2 - Đang chạy browser.forkNewDriverInstance() đã tắt luồng điều khiển -
await browser.get(‘page1’);
await browser.restart();
await browser.get(‘page2’);
browser.restartSync
Nó tương tự như hàm browser.restart (). Sự khác biệt duy nhất là nó trả về phiên bản trình duyệt mới trực tiếp thay vì trả về một lời hứa giải quyết cho phiên bản trình duyệt mới. Nó chỉ có thể chạy khi luồng điều khiển được bật.
Example - Đang chạy browser.restartSync() có bật luồng điều khiển -
browser.get(‘page1’);
browser.restartSync();
browser.get(‘page2’);
browser.useAllAngular2AppRoots
Như tên cho thấy, nó chỉ tương thích với Angular2. Nó sẽ tìm kiếm thông qua tất cả các ứng dụng góc cạnh có sẵn trên trang trong khi tìm kiếm các yếu tố hoặc chờ đợi sự ổn định.
browser.waitForAngular
Hàm API của trình duyệt này hướng dẫn WebDriver đợi cho đến khi Angular kết xuất xong và không có gì nổi bật $http or $hết thời gian cuộc gọi trước khi tiếp tục.
browser.findElement
Như tên cho thấy, hàm API của trình duyệt này đợi Angular kết thúc việc hiển thị trước khi tìm kiếm phần tử.
browser.isElementPresent
Như tên cho thấy, hàm API của trình duyệt này sẽ kiểm tra xem phần tử có xuất hiện trên trang hay không.
browser.addMockModule
Nó sẽ thêm một mô-đun để tải trước Angular mỗi khi phương thức Protractor.get được gọi.
Example
browser.addMockModule('modName', function() {
angular.module('modName', []).value('foo', 'bar');
});
browser.clearMockModules
không giống như browser.addMockModule, nó sẽ xóa danh sách các mô-đun giả đã đăng ký.
browser.removeMockModule
Như tên cho thấy, nó sẽ loại bỏ một mô-đun giả đăng ký. Ví dụ: browser.removeMockModule ('modName');
browser.getRegisteredMockModules
Ngược lại với browser.clearMockModule, nó sẽ nhận được danh sách các mô-đun giả đã đăng ký.
browser.get
Chúng ta có thể sử dụng browser.get () để điều hướng trình duyệt đến một địa chỉ web cụ thể và tải các mô-đun giả cho trang đó trước khi tải Angular.
Example
browser.get(url);
browser.get('http://localhost:3000');
// This will navigate to the localhost:3000 and will load mock module if needed
browser.refresh
Như tên cho thấy, điều này sẽ tải lại trang hiện tại và tải các mô-đun giả trước Angular.
browser.navigate
Như tên cho thấy, nó được sử dụng để trộn các phương thức điều hướng trở lại đối tượng điều hướng để chúng được gọi như trước. Ví dụ: driver.navigate (). Refresh ().
browser.setLocation
Nó được sử dụng để duyệt đến một trang khác bằng cách sử dụng điều hướng trong trang.
Example
browser.get('url/ABC');
browser.setLocation('DEF');
expect(browser.getCurrentUrl())
.toBe('url/DEF');
Nó sẽ điều hướng từ ABC đến trang DEF.
browser.debugger
Như tên cho thấy, điều này phải được sử dụng với gỡ lỗi thước đo góc. Chức năng này về cơ bản thêm một tác vụ vào luồng điều khiển để tạm dừng kiểm tra và đưa các chức năng trợ giúp vào trình duyệt để việc gỡ lỗi có thể được thực hiện trong bảng điều khiển của trình duyệt.
browser.pause
Nó được sử dụng để gỡ lỗi các bài kiểm tra WebDriver. Chúng ta có thể sử dụngbrowser.pause() trong thử nghiệm của chúng tôi để nhập trình gỡ lỗi thước đo góc từ điểm đó trong luồng điều khiển.
Example
element(by.id('foo')).click();
browser.pause();
// Execution will stop before the next click action.
element(by.id('bar')).click();
browser.controlFlowEnabled
Nó được sử dụng để xác định xem luồng điều khiển có được bật hay không.
Thước đo góc - APIS lõi (CONTD…)
Trong chương này, chúng ta hãy tìm hiểu thêm một số API cốt lõi của Thước đo góc.
API yếu tố
Phần tử là một trong những hàm toàn cục được hiển thị bởi thước đo góc. Hàm này nhận một bộ định vị và trả về như sau:
- ElementFinder, tìm một phần tử duy nhất dựa trên bộ định vị.
- ElementArrayFinder, tìm một mảng các phần tử dựa trên bộ định vị.
Cả hai phương pháp trên đều hỗ trợ các phương pháp chuỗi như được thảo luận bên dưới.
Chuỗi các chức năng của ElementArrayFinder và mô tả của chúng
Các phần tiếp theo là các chức năng của ElementArrayFinder -
element.all(locator).clone
Như tên cho thấy, hàm này sẽ tạo một bản sao nông của mảng các phần tử tức là ElementArrayFinder.
element.all(locator).all(locator)
Hàm này về cơ bản trả về một ElementArrayFinder mới có thể trống hoặc chứa các phần tử con. Nó có thể được sử dụng để chọn nhiều phần tử dưới dạng một mảng như sau
Example
element.all(locator).all(locator)
elementArr.all(by.css(‘.childselector’));
// it will return another ElementFindArray as child element based on child locator.
element.all(locator).filter(filterFn)
Như tên cho thấy, sau khi áp dụng chức năng lọc cho mỗi phần tử trong ElementArrayFinder, nó sẽ trả về một ElementArrayFinder mới với tất cả các phần tử vượt qua chức năng lọc. Về cơ bản, nó có hai đối số, đầu tiên là ElementFinder và thứ hai là chỉ mục. Nó cũng có thể được sử dụng trong các đối tượng trang.
Example
View
<ul class = "items">
<li class = "one">First</li>
<li class = "two">Second</li>
<li class = "three">Third</li>
</ul>
Code
element.all(by.css('.items li')).filter(function(elem, index) {
return elem.getText().then(function(text) {
return text === 'Third';
});
}).first().click();
element.all(locator).get(index)
Với sự trợ giúp của điều này, chúng ta có thể lấy một phần tử trong ElementArrayFinder theo chỉ mục. Lưu ý rằng chỉ số bắt đầu từ 0 và các chỉ số âm được bao bọc.
Example
View
<ul class = "items">
<li>First</li>
<li>Second</li>
<li>Third</li>
</ul>
Code
let list = element.all(by.css('.items li'));
expect(list.get(0).getText()).toBe('First');
expect(list.get(1).getText()).toBe('Second');
element.all(locator).first()
Như tên cho thấy, điều này sẽ lấy phần tử đầu tiên cho ElementArrayFinder. Nó sẽ không truy xuất phần tử cơ bản.
Example
View
<ul class = "items">
<li>First</li>
<li>Second</li>
<li>Third</li>
</ul>
Code
let first = element.all(by.css('.items li')).first();
expect(first.getText()).toBe('First');
element.all(locator).last()
Như tên gợi ý, điều này sẽ lấy phần tử cuối cùng cho ElementArrayFinder. Nó sẽ không truy xuất phần tử cơ bản.
Example
View
<ul class = "items">
<li>First</li>
<li>Second</li>
<li>Third</li>
</ul>
Code
let first = element.all(by.css('.items li')).last();
expect(last.getText()).toBe('Third');
element.all(locator).all(selector)
Nó được sử dụng để tìm một mảng các phần tử trong phần tử cha khi các lệnh gọi tới $$ có thể được xâu chuỗi.
Example
View
<div class = "parent">
<ul>
<li class = "one">First</li>
<li class = "two">Second</li>
<li class = "three">Third</li>
</ul>
</div>
Code
let items = element(by.css('.parent')).$$('li');
element.all(locator).count()
Như tên cho thấy, điều này sẽ đếm số phần tử được đại diện bởi ElementArrayFinder. Nó sẽ không truy xuất phần tử cơ bản.
Example
View
<ul class = "items">
<li>First</li>
<li>Second</li>
<li>Third</li>
</ul>
Code
let list = element.all(by.css('.items li'));
expect(list.count()).toBe(3);
element.all(locator).isPresent()
Nó sẽ khớp các phần tử với công cụ tìm. Nó có thể trả về true hoặc false. Đúng, nếu có bất kỳ phần tử nào khớp với công cụ tìm và Sai.
Example
expect($('.item').isPresent()).toBeTruthy();
element.all(locator).locator
Như tên cho thấy, nó sẽ trả về bộ định vị phù hợp nhất.
Example
$('#ID1').locator();
// returns by.css('#ID1')
$('#ID1').$('#ID2').locator();
// returns by.css('#ID2')
$$('#ID1').filter(filterFn).get(0).click().locator();
// returns by.css('#ID1')
element.all(locator).then(thenFunction)
Nó sẽ truy xuất các phần tử được đại diện bởi ElementArrayFinder.
Example
View
<ul class = "items">
<li>First</li>
<li>Second</li>
<li>Third</li>
</ul>
Code
element.all(by.css('.items li')).then(function(arr) {
expect(arr.length).toEqual(3);
});
element.all(locator).each(eachFunction)
Như tên cho thấy, nó sẽ gọi hàm đầu vào trên mỗi ElementFinder được đại diện bởi ElementArrayFinder.
Example
View
<ul class = "items">
<li>First</li>
<li>Second</li>
<li>Third</li>
</ul>
Code
element.all(by.css('.items li')).each(function(element, index) {
// It will print First 0, Second 1 and Third 2.
element.getText().then(function (text) {
console.log(index, text);
});
});
element.all(locator).map(mapFunction)
Như tên gợi ý, nó sẽ áp dụng một chức năng bản đồ trên mỗi phần tử trong ElementArrayFinder. Nó đang có hai đối số. Đầu tiên sẽ là ElementFinder và thứ hai sẽ là chỉ mục.
Example
View
<ul class = "items">
<li>First</li>
<li>Second</li>
<li>Third</li>
</ul>
Code
let items = element.all(by.css('.items li')).map(function(elm, index) {
return {
index: index,
text: elm.getText(),
class: elm.getAttribute('class')
};
});
expect(items).toEqual([
{index: 0, text: 'First', class: 'one'},
{index: 1, text: 'Second', class: 'two'},
{index: 2, text: 'Third', class: 'three'}
]);
element.all(locator).reduce(reduceFn)
Như tên cho thấy, nó sẽ áp dụng chức năng giảm đối với bộ tích lũy và mọi phần tử được tìm thấy bằng cách sử dụng bộ định vị. Hàm này sẽ giảm mọi phần tử thành một giá trị duy nhất.
Example
View
<ul class = "items">
<li>First</li>
<li>Second</li>
<li>Third</li>
</ul>
Code
let value = element.all(by.css('.items li')).reduce(function(acc, elem) {
return elem.getText().then(function(text) {
return acc + text + ' ';
});
}, '');
expect(value).toEqual('First Second Third ');
element.all(locator).evaluate
Như tên cho thấy, nó sẽ đánh giá đầu vào liệu nó có nằm trong phạm vi của các phần tử cơ bản hiện tại hay không.
Example
View
<span class = "foo">{{letiableInScope}}</span>
Code
let value =
element.all(by.css('.foo')).evaluate('letiableInScope');
element.all(locator).allowAnimations
Như tên gợi ý, nó sẽ xác định xem hoạt ảnh có được phép trên các phần tử cơ bản hiện tại hay không.
Example
element(by.css('body')).allowAnimations(false);
Chuỗi các chức năng của ElementFinder và mô tả của chúng
Chuỗi các chức năng của ElementFinder và mô tả của chúng -
element(locator).clone
Như tên cho thấy, chức năng này sẽ tạo ra một bản sao cạn của ElementFinder.
element(locator).getWebElement()
Nó sẽ trả về WebElement được đại diện bởi ElementFinder này và lỗi WebDriver sẽ được ném ra nếu phần tử không tồn tại.
Example
View
<div class="parent">
some text
</div>
Code
// All the four following expressions are equivalent.
$('.parent').getWebElement();
element(by.css('.parent')).getWebElement();
browser.driver.findElement(by.css('.parent'));
browser.findElement(by.css('.parent'));
element(locator).all(locator)
Nó sẽ tìm một mảng các phần tử trong một phần tử cha.
Example
View
<div class = "parent">
<ul>
<li class = "one">First</li>
<li class = "two">Second</li>
<li class = "three">Third</li>
</ul>
</div>
Code
let items = element(by.css('.parent')).all(by.tagName('li'));
element(locator).element(locator)
Nó sẽ tìm các phần tử bên trong cha mẹ.
Example
View
<div class = "parent">
<div class = "child">
Child text
<div>{{person.phone}}</div>
</div>
</div>
Code
// Calls Chain 2 element.
let child = element(by.css('.parent')).
element(by.css('.child'));
expect(child.getText()).toBe('Child text\n981-000-568');
// Calls Chain 3 element.
let triple = element(by.css('.parent')).
element(by.css('.child')).
element(by.binding('person.phone'));
expect(triple.getText()).toBe('981-000-568');
element(locator).all(selector)
Nó sẽ tìm một mảng các phần tử trong phần tử cha khi các lệnh gọi tới $$ có thể được xâu chuỗi.
Example
View
<div class = "parent">
<ul>
<li class = "one">First</li>
<li class = "two">Second</li>
<li class = "three">Third</li>
</ul>
</div>
Code
let items = element(by.css('.parent')).$$('li'));
element(locator).$(locator)
Nó sẽ tìm các phần tử bên trong cha khi các lệnh gọi đến $ có thể được xâu chuỗi.
Example
View
<div class = "parent">
<div class = "child">
Child text
<div>{{person.phone}}</div>
</div>
</div>
Code
// Calls Chain 2 element.
let child = element(by.css('.parent')).
$('.child')); expect(child.getText()).toBe('Child text\n981-000-568'); // Calls Chain 3 element. let triple = element(by.css('.parent')). $('.child')).
element(by.binding('person.phone'));
expect(triple.getText()).toBe('981-000-568');
element(locator).isPresent()
Nó sẽ xác định xem phần tử có được trình bày trên trang hay không.
Example
View
<span>{{person.name}}</span>
Code
expect(element(by.binding('person.name')).isPresent()).toBe(true);
// will check for the existence of element
expect(element(by.binding('notPresent')).isPresent()).toBe(false);
// will check for the non-existence of element
element(locator).isElementPresent()
Nó giống như phần tử (định vị) .isPresent (). Sự khác biệt duy nhất là nó sẽ kiểm tra xem phần tử được xác định bởi sublocator có hiện diện hay không chứ không phải là công cụ tìm phần tử hiện tại.
element.all(locator).evaluate
Như tên cho thấy, nó sẽ đánh giá đầu vào xem nó có nằm trong phạm vi của các phần tử cơ bản hiện tại hay không.
Example
View
<span id = "foo">{{letiableInScope}}</span>
Code
let value = element(by.id('.foo')).evaluate('letiableInScope');
element(locator).allowAnimations
Như tên cho thấy, nó sẽ xác định xem hoạt ảnh có được phép trên các phần tử cơ bản hiện tại hay không.
Example
element(by.css('body')).allowAnimations(false);
element(locator).equals
Như tên cho thấy, nó sẽ so sánh một phần tử để bình đẳng.
API định vị (bởi)
Về cơ bản, nó là một tập hợp các chiến lược định vị phần tử cung cấp các cách tìm kiếm phần tử trong các ứng dụng Angular bằng cách ràng buộc, mô hình, v.v.
Functions and their descriptions
Các chức năng của API ProtractorLocators như sau:
by.addLocator(locatorName,fuctionOrScript)
Nó sẽ thêm một bộ định vị vào phiên bản ProtrcatorBy này, nó có thể được sử dụng thêm với phần tử (by.locatorName (args)).
Example
View
<button ng-click = "doAddition()">Go!</button>
Code
// Adding the custom locator.
by.addLocator('buttonTextSimple',
function(buttonText, opt_parentElement, opt_rootSelector) {
var using = opt_parentElement || document,
buttons = using.querySelectorAll('button');
return Array.prototype.filter.call(buttons, function(button) {
return button.textContent === buttonText;
});
});
element(by.buttonTextSimple('Go!')).click();// Using the custom locator.
by.binding
Như tên cho thấy, nó sẽ tìm thấy một phần tử bằng cách liên kết văn bản. So khớp từng phần sẽ được thực hiện để mọi phần tử liên kết với các biến chứa chuỗi đầu vào sẽ được trả về.
Example
View
<span>{{person.name}}</span>
<span ng-bind = "person.email"></span>
Code
var span1 = element(by.binding('person.name'));
expect(span1.getText()).toBe('Foo');
var span2 = element(by.binding('person.email'));
expect(span2.getText()).toBe('[email protected]');
by.exactbinding
Như tên cho thấy, nó sẽ tìm một phần tử bằng cách ràng buộc chính xác.
Example
View
<spangt;{{ person.name }}</spangt;
<span ng-bind = "person-email"gt;</spangt;
<spangt;{{person_phone|uppercase}}</span>
Code
expect(element(by.exactBinding('person.name')).isPresent()).toBe(true);
expect(element(by.exactBinding('person-email')).isPresent()).toBe(true);
expect(element(by.exactBinding('person')).isPresent()).toBe(false);
expect(element(by.exactBinding('person_phone')).isPresent()).toBe(true);
expect(element(by.exactBinding('person_phone|uppercase')).isPresent()).toBe(true);
expect(element(by.exactBinding('phone')).isPresent()).toBe(false);
by.model(modelName)
Như tên cho thấy, nó sẽ tìm một phần tử bằng biểu thức ng-model.
Example
View
<input type = "text" ng-model = "person.name">
Code
var input = element(by.model('person.name'));
input.sendKeys('123');
expect(input.getAttribute('value')).toBe('Foo123');
by.buttonText
Như tên cho thấy, nó sẽ tìm thấy một nút bằng văn bản.
Example
View
<button>Save</button>
Code
element(by.buttonText('Save'));
by.partialButtonText
Như tên cho thấy, nó sẽ tìm thấy một nút bằng một phần văn bản.
Example
View
<button>Save my file</button>
Code
element(by.partialButtonText('Save'));
by.repeater
Như tên cho thấy, nó sẽ tìm thấy một phần tử bên trong một ng-repeat.
Example
View
<div ng-repeat = "cat in pets">
<span>{{cat.name}}</span>
<span>{{cat.age}}</span>
<</div>
<div class = "book-img" ng-repeat-start="book in library">
<span>{{$index}}</span>
</div>
<div class = "book-info" ng-repeat-end>
<h4>{{book.name}}</h4>
<p>{{book.blurb}}</p>
</div>
Code
var secondCat = element(by.repeater('cat in
pets').row(1)); // It will return the DIV for the second cat.
var firstCatName = element(by.repeater('cat in pets').
row(0).column('cat.name')); // It will return the SPAN for the first cat's name.
by.exactRepeater
Như tên cho thấy, nó sẽ tìm một phần tử bằng bộ lặp chính xác.
Example
View
<li ng-repeat = "person in peopleWithRedHair"></li>
<li ng-repeat = "car in cars | orderBy:year"></li>
Code
expect(element(by.exactRepeater('person in
peopleWithRedHair')).isPresent())
.toBe(true);
expect(element(by.exactRepeater('person in
people')).isPresent()).toBe(false);
expect(element(by.exactRepeater('car in cars')).isPresent()).toBe(true);
by.cssContainingText
Như tên gợi ý, nó sẽ tìm các phần tử, chứa chuỗi chính xác, bằng CSS
Example
View
<ul>
<li class = "pet">Dog</li>
<li class = "pet">Cat</li>
</ul>
Code
var dog = element(by.cssContainingText('.pet', 'Dog'));
// It will return the li for the dog, but not for the cat.
by.options(optionsDescriptor)
Như tên cho thấy, nó sẽ tìm một phần tử bằng biểu thức ng-options.
Example
View
<select ng-model = "color" ng-options = "c for c in colors">
<option value = "0" selected = "selected">red</option>
<option value = "1">green</option>
</select>
Code
var allOptions = element.all(by.options('c for c in colors'));
expect(allOptions.count()).toEqual(2);
var firstOption = allOptions.first();
expect(firstOption.getText()).toEqual('red');
by.deepCSS(selector)
Như tên gợi ý, nó sẽ tìm thấy một phần tử bằng bộ chọn CSS bên trong DOM bóng.
Example
View
<div>
<span id = "outerspan">
<"shadow tree">
<span id = "span1"></span>
<"shadow tree">
<span id = "span2"></span>
</>
</>
</div>
Code
var spans = element.all(by.deepCss('span'));
expect(spans.count()).toEqual(3);
Thước đo góc - Đối tượng
Chương này thảo luận chi tiết về các đối tượng trong Thước đo góc.
Đối tượng Trang là gì?
Đối tượng trang là một mẫu thiết kế đã trở nên phổ biến để viết các bài kiểm tra e2e nhằm tăng cường bảo trì kiểm tra và giảm sự trùng lặp mã. Nó có thể được định nghĩa là một lớp hướng đối tượng phục vụ như một giao diện cho một trang AUT của bạn (ứng dụng đang được thử nghiệm). Tuy nhiên, trước khi đi sâu vào các đối tượng trang, chúng ta phải hiểu những thách thức với thử nghiệm giao diện người dùng tự động và cách xử lý chúng.
Những thách thức với kiểm tra giao diện người dùng tự động
Tiếp theo là một số thách thức phổ biến khi tự động kiểm tra giao diện người dùng -
Thay đổi giao diện người dùng
Các vấn đề rất phổ biến khi làm việc với thử nghiệm giao diện người dùng là các thay đổi xảy ra trong giao diện người dùng. Ví dụ, hầu hết thời gian xảy ra rằng các nút hoặc hộp văn bản, v.v. thường thay đổi và tạo ra các vấn đề cho thử nghiệm giao diện người dùng.
Thiếu hỗ trợ DSL (Ngôn ngữ dành riêng cho miền)
Một vấn đề khác với thử nghiệm giao diện người dùng là thiếu hỗ trợ DSL. Với vấn đề này, rất khó để hiểu những gì đang được thử nghiệm.
Lặp lại nhiều / Mã trùng lặp
Vấn đề phổ biến tiếp theo trong thử nghiệm giao diện người dùng là có rất nhiều sự lặp lại hoặc trùng lặp mã. Nó có thể được hiểu với sự trợ giúp của các dòng mã sau:
element(by.model(‘event.name’)).sendKeys(‘An Event’);
element(by.model(‘event.name’)).sendKeys(‘Module 3’);
element(by.model(‘event.name’));
Bảo trì khó khăn
Do những thách thức trên, nó trở nên đau đầu cho việc bảo trì. Đó là bởi vì chúng tôi phải tìm tất cả các phiên bản, thay thế bằng tên mới, bộ chọn và mã khác. Chúng tôi cũng cần dành nhiều thời gian để giữ cho các thử nghiệm phù hợp với việc tái cấu trúc.
Kiểm tra hỏng
Một thách thức khác trong thử nghiệm giao diện người dùng là xảy ra rất nhiều lỗi trong các thử nghiệm.
Cách xử lý các thách thức
Chúng tôi đã thấy một số thách thức phổ biến của thử nghiệm giao diện người dùng. Một số cách để xử lý những thách thức như sau:
Cập nhật tài liệu tham khảo theo cách thủ công
Tùy chọn đầu tiên để xử lý các thách thức trên là cập nhật các tài liệu tham khảo theo cách thủ công. Vấn đề với tùy chọn này là chúng tôi phải thực hiện thay đổi thủ công trong mã cũng như các thử nghiệm của chúng tôi. Điều này có thể được thực hiện khi bạn có một hoặc hai tệp thử nghiệm nhưng nếu bạn có hàng trăm tệp thử nghiệm trong một dự án thì sao?
Sử dụng Đối tượng Trang
Một tùy chọn khác để xử lý các thách thức trên là sử dụng các đối tượng trang. Đối tượng trang về cơ bản là một JavaScript thuần túy đóng gói các thuộc tính của mẫu Angular. Ví dụ: tệp đặc tả sau được viết mà không có và với các đối tượng trang để hiểu sự khác biệt:
Without Page Objects
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!');
});
});
With Page Objects
Để viết mã với Đối tượng Trang, điều đầu tiên chúng ta cần làm là tạo Đối tượng Trang. Do đó, một Đối tượng Trang cho ví dụ trên có thể trông như thế này -
var AngularHomepage = function() {
var nameInput = element(by.model('yourName'));
var greeting = element(by.binding('yourName'));
this.get = function() {
browser.get('http://www.angularjs.org');
};
this.setName = function(name) {
nameInput.sendKeys(name);
};
this.getGreetingText = function() {
return greeting.getText();
};
};
module.exports = new AngularHomepage();
Sử dụng Đối tượng Trang để Tổ chức Kiểm tra
Chúng ta đã thấy việc sử dụng các đối tượng trang trong ví dụ trên để xử lý các thách thức của thử nghiệm giao diện người dùng. Tiếp theo, chúng ta sẽ thảo luận về cách chúng ta có thể sử dụng chúng để tổ chức các bài kiểm tra. Đối với điều này, chúng ta cần sửa đổi tập lệnh thử nghiệm mà không sửa đổi chức năng của tập lệnh thử nghiệm.
Thí dụ
Để hiểu khái niệm này, chúng tôi sử dụng tệp cấu hình ở trên với các đối tượng trang. Chúng ta cần sửa đổi tập lệnh thử nghiệm như sau:
var angularHomepage = require('./AngularHomepage');
describe('angularjs homepage', function() {
it('should greet the named user', function() {
angularHomepage.get();
angularHomepage.setName('Julie');
expect(angularHomepage.getGreetingText()).toEqual
('Hello Julie!');
});
});
Ở đây, lưu ý rằng đường dẫn đến đối tượng trang sẽ liên quan đến đặc điểm kỹ thuật của bạn.
Đồng thời, chúng tôi cũng có thể tách bộ thử nghiệm của mình thành nhiều bộ thử nghiệm khác nhau. Sau đó, tệp cấu hình có thể được thay đổi như sau
exports.config = {
// The address of a running selenium server.
seleniumAddress: 'http://localhost:4444/wd/hub',
// Capabilities to be passed to the webdriver instance.
capabilities: {
'browserName': 'chrome'
},
// Spec patterns are relative to the location of the spec file. They may
// include glob patterns.
suites: {
homepage: 'tests/e2e/homepage/**/*Spec.js',
search: ['tests/e2e/contact_search/**/*Spec.js',
'tests/e2e/venue_search/**/*Spec.js']
},
// Options to be passed to Jasmine-node.
jasmineNodeOpts: {
showColors: true, // Use colors in the command line report.
}
};
Giờ đây, chúng ta có thể dễ dàng chuyển đổi giữa việc chạy một hoặc một bộ thử nghiệm khác. Lệnh sau sẽ chỉ chạy phần trang chủ của bài kiểm tra -
protractor protractor.conf.js --suite homepage
Tương tự, chúng ta có thể chạy các bộ thử nghiệm cụ thể bằng lệnh như sau:
protractor protractor.conf.js --suite homepage,search
Thước đo góc - Gỡ lỗi
Bây giờ chúng ta đã xem tất cả các khái niệm về Thước đo góc trong các chương trước, chúng ta hãy hiểu các khái niệm gỡ lỗi một cách chi tiết trong chương này.
Giới thiệu
Các bài kiểm tra end-to-end (e2e) rất khó gỡ lỗi vì chúng phụ thuộc vào toàn bộ hệ sinh thái của ứng dụng đó. Chúng tôi đã thấy rằng chúng phụ thuộc vào các hành động khác nhau hoặc đặc biệt có thể nói rằng chúng phụ thuộc vào các hành động trước đó như đăng nhập và đôi khi chúng phụ thuộc vào sự cho phép. Một khó khăn khác trong việc gỡ lỗi các bài kiểm tra e2e là sự phụ thuộc của nó vào WebDriver vì nó hoạt động khác nhau với các hệ điều hành và trình duyệt khác nhau. Cuối cùng, việc gỡ lỗi các bài kiểm tra e2e cũng tạo ra các thông báo lỗi dài và gây khó khăn cho việc tách các vấn đề liên quan đến trình duyệt và các lỗi trong quá trình kiểm tra.
Các loại thất bại
Có thể có nhiều lý do khác nhau dẫn đến sự cố của bộ thử nghiệm và sau đây là một số loại lỗi nổi tiếng -
Lỗi WebDriver
Khi một lệnh không thể được hoàn thành, một lỗi được đưa ra bởi WebDriver. Ví dụ: một trình duyệt không thể lấy địa chỉ đã xác định hoặc một phần tử không được tìm thấy như mong đợi.
WebDriver bị lỗi không mong muốn
Lỗi không mong muốn liên quan đến trình duyệt và hệ điều hành xảy ra khi không cập nhật được trình quản lý trình điều khiển web.
Lỗi thước đo góc cho Angular
Sự thất bại của Protractor cho Angular xảy ra khi Protractor không tìm thấy Angular trong thư viện như mong đợi.
Lỗi thước đo góc 2
Trong loại lỗi này, Thước đo góc sẽ không thành công khi không tìm thấy tham số useAllAngular2AppRoots trong cấu hình. Nó xảy ra bởi vì, không có điều này, quá trình kiểm tra sẽ xem xét một phần tử gốc duy nhất trong khi mong đợi nhiều hơn một phần tử trong quy trình.
Thước đo góc bị lỗi do hết thời gian chờ
Loại lỗi này xảy ra khi thông số kỹ thuật kiểm tra đạt một vòng lặp hoặc một nhóm dài và không trả lại dữ liệu kịp thời.
Kỳ vọng thất bại
Một trong những lỗi kiểm tra phổ biến nhất cho thấy lỗi kỳ vọng thông thường trông như thế nào.
Tại sao gỡ lỗi lại quan trọng trong Thước đo góc?
Giả sử, nếu bạn đã viết các trường hợp thử nghiệm và chúng bị lỗi thì điều rất quan trọng là phải biết cách gỡ lỗi các trường hợp thử nghiệm đó vì sẽ rất khó để tìm ra chính xác nơi xảy ra lỗi. Trong khi làm việc với Thước đo góc, bạn sẽ gặp một số lỗi dài trong phông chữ màu đỏ trong dòng lệnh.
Tạm dừng và gỡ lỗi kiểm tra
Các cách gỡ lỗi trong Thước đo góc được giải thích ở đây & miuns;
Phương pháp tạm dừng
Sử dụng phương pháp tạm dừng để gỡ lỗi các trường hợp thử nghiệm trong Thước đo góc là một trong những cách dễ nhất. Chúng tôi có thể nhập lệnh sau tại nơi chúng tôi muốn tạm dừng mã thử nghiệm của mình & miuns;
browser.pause();
Khi các mã đang chạy chạm vào lệnh trên, nó sẽ tạm dừng chương trình đang chạy tại thời điểm đó. Sau đó, chúng ta có thể đưa ra các lệnh sau theo sở thích của mình:
Loại C để Tiến lên
Bất cứ khi nào một lệnh đã hết, chúng ta phải gõ C để tiếp tục. Nếu bạn không gõ C, bài kiểm tra sẽ không chạy mã đầy đủ và nó sẽ thất bại do lỗi Jasmine time out.
Nhập repl để vào chế độ tương tác
Lợi ích của chế độ tương tác là chúng ta có thể gửi các lệnh WebDriver đến trình duyệt của mình. Nếu chúng ta muốn vào chế độ tương tác, hãy nhậprepl.
Gõ Ctrl-C để thoát và tiếp tục kiểm tra
Để thoát khỏi thử nghiệm từ trạng thái tạm dừng và tiếp tục kiểm tra từ nơi nó đã dừng, chúng ta cần gõ Ctrl-C.
Thí dụ
Trong ví dụ này, chúng tôi có tệp thông số kỹ thuật bên dưới có tên example_debug.js, thước đo góc cố gắng xác định một phần tử bằng bộ định vị by.binding('mmmm') nhưng URL (https://angularjs.org/ trang không có phần tử với bộ định vị được chỉ định.
describe('Suite for protractor debugger',function(){
it('Failing spec',function(){
browser.get("http://angularjs.org");
element(by.model('yourName')).sendKeys('Vijay');
//Element doesn't exist
var welcomeText =
element(by.binding('mmmm')).getText();
expect('Hello '+welcomeText+'!').toEqual('Hello Ram!')
});
});
Bây giờ, để thực hiện kiểm tra ở trên, chúng ta cần thêm mã browser.pause (), nơi bạn muốn tạm dừng kiểm tra, trong tệp đặc tả ở trên. Nó sẽ trông như sau:
describe('Suite for protractor debugger',function(){
it('Failing spec',function(){
browser.get("http://angularjs.org");
browser.pause();
element(by.model('yourName')).sendKeys('Vijay');
//Element doesn't exist
var welcomeText =
element(by.binding('mmmm')).getText();
expect('Hello '+welcomeText+'!').toEqual('Hello Ram!')
});
});
Nhưng trước khi thực hiện, chúng ta cũng cần thực hiện một số thay đổi trong tệp cấu hình. Chúng tôi đang thực hiện các thay đổi sau trong tệp cấu hình đã sử dụng trước đó, có tênexample_configuration.js trong chương trước -
// An example configuration file.
exports.config = {
directConnect: true,
// Capabilities to be passed to the webdriver instance.
capabilities: {
'browserName': 'chrome'
},
// Framework to use. Jasmine is recommended.
framework: 'jasmine',
// Spec patterns are relative to the current working directory when
// protractor is called.
specs: ['example_debug.js'],
allScriptsTimeout: 999999,
jasmineNodeOpts: {
defaultTimeoutInterval: 999999
},
onPrepare: function () {
browser.manage().window().maximize();
browser.manage().timeouts().implicitlyWait(5000);
}
};
Bây giờ, hãy chạy lệnh sau:
protractor example_configuration.js
Trình gỡ lỗi sẽ bắt đầu sau lệnh trên.
Phương pháp gỡ lỗi
Sử dụng phương pháp tạm dừng để gỡ lỗi các trường hợp thử nghiệm trong Thước đo góc là một cách nâng cao một chút. Chúng ta có thể gõ lệnh sau tại nơi chúng ta muốn ngắt mã thử nghiệm của mình -
browser.debugger();
Nó sử dụng trình gỡ lỗi nút để gỡ lỗi mã thử nghiệm. Để chạy lệnh trên, chúng ta phải nhập lệnh sau vào một dấu nhắc lệnh riêng biệt đã mở từ vị trí dự án thử nghiệm:
protractor debug protractor.conf.js
Trong phương pháp này, chúng ta cũng cần gõ C vào terminal để tiếp tục mã kiểm tra. Nhưng ngược lại với phương pháp tạm dừng, trong phương pháp này, nó chỉ được nhập một lần.
Thí dụ
Trong ví dụ này, chúng tôi đang sử dụng cùng một tệp đặc tả có tên bexample_debug.js, được sử dụng ở trên. Sự khác biệt duy nhất là thay vìbrowser.pause(), chúng ta cần sử dụng browser.debugger()nơi chúng tôi muốn phá vỡ mã kiểm tra. Nó sẽ trông như sau:
describe('Suite for protractor debugger',function(){
it('Failing spec',function(){
browser.get("http://angularjs.org");
browser.debugger();
element(by.model('yourName')).sendKeys('Vijay');
//Element doesn't exist
var welcomeText = element(by.binding('mmmm')).getText();
expect('Hello '+welcomeText+'!').toEqual('Hello Ram!')
});
});
Chúng tôi đang sử dụng cùng một tệp cấu hình, example_configuration.js, được sử dụng trong ví dụ trên.
Bây giờ, hãy chạy kiểm tra thước đo góc với tùy chọn dòng lệnh gỡ lỗi sau
protractor debug example_configuration.js
Trình gỡ lỗi sẽ bắt đầu sau lệnh trên.
Thước đo góc - Hướng dẫn kiểu cho thước đo góc
Trong chương này, chúng ta hãy tìm hiểu chi tiết về hướng dẫn kiểu cho thước đo góc.
Giới thiệu
Hướng dẫn kiểu được tạo bởi hai kỹ sư phần mềm có tên, Carmen Popoviciu, kỹ sư front-end tại ING và Andres Dominguez, kỹ sư phần mềm tại Google. Do đó, hướng dẫn kiểu này còn được gọi là Carmen Popoviciu và hướng dẫn kiểu của Google cho thước đo góc.
Hướng dẫn phong cách này có thể được chia thành năm điểm chính sau:
- Quy tắc chung
- Cấu trúc dự án
- Các chiến lược định vị
- Đối tượng Trang
- Bộ thử nghiệm
Quy tắc chung
Sau đây là một số quy tắc chung phải được cẩn thận khi sử dụng thước đo góc để thử nghiệm -
Không kiểm tra đầu cuối những gì đã được kiểm tra đơn vị
Đây là quy tắc chung đầu tiên được đưa ra bởi Carmen và Andres. Họ đề nghị rằng chúng tôi không được thực hiện kiểm tra e2e trên mã đã được kiểm tra đơn vị. Lý do chính đằng sau nó là các bài kiểm tra đơn vị nhanh hơn nhiều so với các bài kiểm tra e2e. Một lý do khác là chúng ta phải tránh các thử nghiệm trùng lặp (không thực hiện cả thử nghiệm đơn vị và e2e) để tiết kiệm thời gian của chúng tôi.
Chỉ sử dụng một tệp cấu hình
Một điểm quan trọng khác được khuyến nghị là chúng ta phải chỉ sử dụng một tệp cấu hình. Không tạo tệp cấu hình cho từng môi trường bạn đang thử nghiệm. Bạn có thể dùnggrunt-protractor-coverage để thiết lập các môi trường khác nhau.
Tránh sử dụng logic cho bài kiểm tra của bạn
Chúng ta phải tránh sử dụng các câu lệnh IF hoặc vòng lặp FOR trong các trường hợp thử nghiệm của mình vì nếu chúng ta làm như vậy thì bài kiểm tra có thể vượt qua mà không cần kiểm tra bất kỳ điều gì hoặc nó có thể chạy rất chậm.
Làm cho thử nghiệm độc lập ở cấp tệp
Thước đo góc có thể chạy thử nghiệm song song khi bật tính năng chia sẻ. Các tệp này sau đó sẽ được thực thi trên các trình duyệt khác nhau khi chúng có sẵn. Carmen và Andres khuyến nghị nên thực hiện kiểm tra độc lập ít nhất là ở cấp độ tệp vì thứ tự mà chúng sẽ được chạy bằng thước đo góc là không chắc chắn và hơn nữa, việc chạy kiểm tra một cách cô lập là điều khá dễ dàng.
Cấu trúc dự án
Một điểm chính quan trọng khác liên quan đến hướng dẫn kiểu của Thước đo góc là cấu trúc của dự án của bạn. Sau đây là khuyến nghị về cấu trúc dự án -
Tìm hiểu thử nghiệm e2e trong một cấu trúc hợp lý
Carmen và Andres khuyến nghị rằng chúng tôi phải nhóm các bài kiểm tra e2e của mình theo một cấu trúc phù hợp với cấu trúc của dự án của bạn. Lý do đằng sau khuyến nghị này là việc tìm kiếm các tệp sẽ trở nên dễ dàng và cấu trúc thư mục sẽ dễ đọc hơn. Bước này cũng sẽ tách các bài kiểm tra e2e khỏi các bài kiểm tra đơn vị. Họ khuyến nghị rằng nên tránh loại cấu trúc sau:
|-- project-folder
|-- app
|-- css
|-- img
|-- partials
home.html
profile.html
contacts.html
|-- js
|-- controllers
|-- directives
|-- services
app.js
...
index.html
|-- test
|-- unit
|-- e2e
home-page.js
home-spec.js
profile-page.js
profile-spec.js
contacts-page.js
contacts-spec.js
Mặt khác, họ đề xuất loại cấu trúc sau:
|-- project-folder
|-- app
|-- css
|-- img
|-- partials
home.html
profile.html
contacts.html
|-- js
|-- controllers
|-- directives
|-- services
app.js
...
index.html
|-- test
|-- unit
|-- e2e
|-- page-objects
home-page.js
profile-page.js
contacts-page.js
home-spec.js
profile-spec.js
contacts-spec.js
Chiến lược định vị
Sau đây là một số chiến lược định vị phải được cẩn thận khi sử dụng thước đo góc để kiểm tra -
Không bao giờ sử dụng XPATH
Đây là chiến lược định vị đầu tiên được đề xuất trong hướng dẫn kiểu thước đo góc. Lý do đằng sau điều tương tự là XPath đòi hỏi nhiều bảo trì vì đánh dấu rất dễ thay đổi. Hơn nữa, biểu thức XPath là chậm nhất và rất khó gỡ lỗi.
Luôn thích các công cụ định vị dành riêng cho thước đo góc như by.model và by.binding
Các bộ định vị cụ thể của thước đo góc như by.model và by.binding ngắn gọn, cụ thể và dễ đọc. Với sự giúp đỡ của họ, rất dễ dàng để viết bộ định vị của chúng tôi.
Thí dụ
View
<ul class = "red">
<li>{{color.name}}</li>
<li>{{color.shade}}</li>
<li>{{color.code}}</li>
</ul>
<div class = "details">
<div class = "personal">
<input ng-model = "person.name">
</div>
</div>
Đối với đoạn mã trên, bạn nên tránh những điều sau:
var nameElement = element.all(by.css('.red li')).get(0);
var personName = element(by.css('.details .personal input'));
Mặt khác, những điều sau đây được khuyến nghị sử dụng:
var nameElement = element.all(by.css('.red li')).get(0);
var personName = element(by.css('.details .personal input'));
var nameElement = element(by.binding('color.name'));
var personName = element(by.model('person.name'));
Khi không có bộ định vị Thước đo góc nào khả dụng, thì bạn nên ưu tiên by.id và by.css hơn.
Luôn tránh các trình định vị văn bản để thay đổi văn bản thường xuyên
Chúng ta phải tránh các trình định vị dựa trên văn bản như by.linkText, by.buttonText và by.cssCont rênText vì văn bản cho các nút, liên kết và nhãn thường xuyên thay đổi theo thời gian.
Đối tượng Trang
Như đã thảo luận trước đó, các đối tượng trang đóng gói thông tin về các phần tử trên trang ứng dụng của chúng tôi và do đó, điều này giúp chúng tôi viết các trường hợp thử nghiệm rõ ràng hơn. Một ưu điểm rất hữu ích của các đối tượng trang là chúng có thể được sử dụng lại qua nhiều lần kiểm tra và trong trường hợp nếu mẫu ứng dụng của chúng tôi đã bị thay đổi, chúng tôi chỉ cần cập nhật đối tượng trang. Dưới đây là một số khuyến nghị cho các đối tượng trang phải được cẩn thận khi sử dụng thước đo góc để thử nghiệm -
Để tương tác với trang đang kiểm tra, hãy sử dụng các đối tượng trang
Bạn nên sử dụng các đối tượng trang để tương tác với trang đang thử nghiệm vì chúng có thể đóng gói thông tin về phần tử trên trang đang kiểm tra và chúng cũng có thể được sử dụng lại.
Luôn khai báo đối tượng một trang cho mỗi tệp
Chúng ta nên xác định từng đối tượng trang trong tệp riêng của nó vì nó giữ cho mã sạch và việc tìm kiếm mọi thứ trở nên dễ dàng.
Ở cuối trang, tệp đối tượng luôn sử dụng một mô-đun duy nhất .exports
Khuyến nghị rằng mỗi đối tượng trang nên khai báo một lớp để chúng ta chỉ cần xuất một lớp. Ví dụ, nên tránh sử dụng tệp đối tượng sau:
var UserProfilePage = function() {};
var UserSettingsPage = function() {};
module.exports = UserPropertiesPage;
module.exports = UserSettingsPage;
Nhưng mặt khác, chúng tôi khuyên bạn nên sử dụng:
/** @constructor */
var UserPropertiesPage = function() {};
module.exports = UserPropertiesPage;
Khai báo tất cả các mô-đun bắt buộc ở trên cùng
Chúng ta nên khai báo tất cả các mô-đun bắt buộc ở đầu đối tượng trang vì nó làm cho các phần phụ thuộc của mô-đun rõ ràng và dễ tìm.
Khởi tạo tất cả các đối tượng trang ở đầu bộ thử nghiệm
Bạn nên khởi tạo tất cả các đối tượng trang ở đầu bộ thử nghiệm vì điều này sẽ tách các phần phụ thuộc khỏi mã thử nghiệm cũng như làm cho các phần phụ thuộc có sẵn cho tất cả các thông số kỹ thuật của bộ phần mềm.
Không sử dụng kỳ vọng () trong các đối tượng trang
Chúng ta không nên sử dụng kỳ vọng () trong các đối tượng trang, tức là chúng ta không nên thực hiện bất kỳ xác nhận nào trong các đối tượng trang của mình vì tất cả các xác nhận phải được thực hiện trong các trường hợp thử nghiệm.
Một lý do khác là người đọc thử nghiệm chỉ có thể hiểu hành vi của ứng dụng bằng cách đọc các trường hợp thử nghiệm.