การทดสอบหน่วย AngularJS: บทช่วยสอน Karma Jasmine
หนึ่งในคุณสมบัติที่ยอดเยี่ยมที่สุดของ Angular.JS คือ การทดสอบ ด้าน. เมื่อนักพัฒนาที่ Google พัฒนา AngularJS พวกเขาคำนึงถึงการทดสอบและทำให้แน่ใจว่าเฟรมเวิร์ก AngularJS ทั้งหมดสามารถทดสอบได้
ใน AngularJS การทดสอบจะดำเนินการตามปกติโดยใช้ Karma (เฟรมเวิร์ก) การทดสอบ Angular JS สามารถทำได้โดยไม่ต้องใช้ Karma แต่เฟรมเวิร์ก Karma มีฟังก์ชันที่ยอดเยี่ยมสำหรับการทดสอบโค้ด AngularJS ซึ่งเหมาะสมที่จะใช้เฟรมเวิร์กนี้
- ใน AngularJS เราสามารถทำได้ การทดสอบหน่วย แยกต่างหากสำหรับตัวควบคุมและคำสั่ง
- นอกจากนี้เรายังสามารถทำการทดสอบแบบ end-end ของ AngularJS ซึ่งเป็นการทดสอบจากมุมมองของผู้ใช้
บทนำและการติดตั้งกรอบกรรม
กรรมคือก ทดสอบเครื่องมืออัตโนมัติ สร้างโดยทีม Angular JS ที่ Google ขั้นตอนแรกในการใช้ Karma คือการติดตั้ง Karma Karma ได้รับการติดตั้งผ่าน npm (ซึ่งเป็นตัวจัดการแพ็คเกจที่ใช้สำหรับการติดตั้งโมดูลบนเครื่องท้องถิ่นอย่างง่ายดาย)
การติดตั้งกรรม
การติดตั้ง Karma ผ่าน npm เสร็จสิ้นในสองขั้นตอน
ขั้นตอน 1) ดำเนินการบรรทัดด้านล่างจากภายในบรรทัดคำสั่ง
npm install karma karma-chrome-launcher karma-jasmine
โดยที่
- npm เป็นยูทิลิตีบรรทัดคำสั่งสำหรับตัวจัดการแพ็กเกจโหนดที่ใช้สำหรับการติดตั้งโมดูลแบบกำหนดเองบนเครื่องใดๆ
- พารามิเตอร์การติดตั้งจะแนะนำยูทิลิตีบรรทัดคำสั่ง npm ที่จำเป็นต้องมีการติดตั้ง
- มีการระบุไลบรารี 3 รายการในบรรทัดคำสั่งที่จำเป็นสำหรับการทำงานกับกรรม
- กรรมเป็นห้องสมุดหลักที่จะใช้สำหรับการทดสอบ
- karma-chrome-launcher เป็นไลบรารีแยกต่างหากซึ่งช่วยให้เบราว์เซอร์ Chrome จดจำคำสั่งกรรมได้
- karma-jasmine - สิ่งนี้จะติดตั้ง jasmine ซึ่งเป็นเฟรมเวิร์กที่ต้องพึ่งพาสำหรับ Karma
ขั้นตอน 2) ขั้นตอนต่อไปคือการติดตั้งยูทิลิตีบรรทัดคำสั่งกรรม สิ่งนี้จำเป็นสำหรับการดำเนินการคำสั่งบรรทัดกรรม ยูทิลิตี้บรรทัดกรรมจะถูกใช้เพื่อเริ่มต้นสภาพแวดล้อมกรรมสำหรับการทดสอบ
ในการติดตั้งยูทิลิตี้บรรทัดคำสั่งให้รันบรรทัดด้านล่างจากภายในบรรทัดคำสั่ง
npm install karma-cli
โดยที่
การกำหนดค่ากรอบกรรม
ขั้นตอนต่อไปคือการกำหนดค่ากรรมซึ่งสามารถทำได้ผ่านคำสั่ง
"karma –init"
หลังจากดำเนินการขั้นตอนข้างต้นแล้ว กรรมจะสร้างไฟล์ karma.conf.js ไฟล์อาจจะมีลักษณะเหมือนกับตัวอย่างที่แสดงด้านล่าง
files: [ 'Your application Name'/AngularJS/AngularJS.js', 'Your application Name'/AngularJS-mocks/AngularJS-mocks.js', 'lib/app.js', 'tests/*.js' ]
ไฟล์กำหนดค่าด้านบนจะแจ้งให้กลไกรันไทม์ Karma ทราบข้อมูลต่อไปนี้
- 'ชื่อใบสมัครของคุณ' – สิ่งนี้จะถูกแทนที่ด้วยชื่อใบสมัครของคุณ
- 'ชื่อแอปพลิเคชันของคุณ '/AngularJS/AngularJS.js' – สิ่งนี้บอกกรรมว่าแอปพลิเคชันของคุณขึ้นอยู่กับโมดูลหลักใน AngularJS
- 'ชื่อแอปพลิเคชันของคุณ'/AngularJS-mocks/AngularJS-mocks.js' – สิ่งนี้เป็นการบอกกรรมให้ใช้ฟังก์ชันการทดสอบหน่วยสำหรับ AngularJS จากไฟล์ Angular.JS-mocks.js
- แอปพลิเคชันหลักหรือไฟล์ตรรกะทางธุรกิจทั้งหมดมีอยู่ในโฟลเดอร์ lib ของแอปพลิเคชันของคุณ
- โฟลเดอร์การทดสอบจะมีการทดสอบหน่วยทั้งหมด
หากต้องการตรวจสอบว่ากรรมทำงานอยู่หรือไม่ ให้สร้างไฟล์ชื่อ Sample.js ใส่โค้ดด้านล่างและวางลงในไดเร็กทอรีทดสอบ
describe('Sample test', function() { it('Condition is true', function() { expect('AngularJS').toBe('AngularJS'); }); });
โค้ดด้านบนมีลักษณะดังต่อไปนี้
- ฟังก์ชั่นอธิบายใช้เพื่ออธิบายการทดสอบ ในกรณีของเรา เราจะให้คำอธิบาย 'การทดสอบตัวอย่าง' กับการทดสอบของเรา
- ฟังก์ชัน 'it' ใช้เพื่อตั้งชื่อให้กับการทดสอบ ในกรณีของเรา เราจะตั้งชื่อการทดสอบว่า 'Condition is true' ชื่อของการทดสอบจะต้องมีความหมาย
- การรวมกันของคีย์เวิร์ด 'expect' และ 'toBe' จะระบุค่าที่คาดหวังและมูลค่าที่แท้จริงของผลการทดสอบ หากค่าจริงและค่าที่คาดหวังเท่ากัน การทดสอบจะผ่าน ไม่เช่นนั้นจะล้มเหลว
เมื่อคุณดำเนินการบรรทัดต่อไปนี้ที่พรอมต์คำสั่ง ระบบจะดำเนินการไฟล์ทดสอบด้านบน
KARMA start
ผลลัพธ์ด้านล่างนำมาจาก IDE Webstorm ซึ่งได้ดำเนินการตามขั้นตอนข้างต้นแล้ว
- ผลลัพธ์จะมาใน Karma explorer ภายใน Webstorm- หน้าต่างนี้แสดงการดำเนินการทดสอบทั้งหมดที่กำหนดไว้ในกรอบกรรม
- ที่นี่คุณจะเห็นคำอธิบายของการทดสอบที่ดำเนินการซึ่งก็คือ “การทดสอบตัวอย่าง”
- ต่อไป คุณจะเห็นว่าการทดสอบซึ่งมีชื่อว่า "เงื่อนไขเป็นจริง" ได้ถูกดำเนินการแล้ว
- โปรดทราบว่าเนื่องจากการทดสอบทั้งหมดจะมีไอคอน "ตกลง" สีเขียวอยู่ข้างๆ ซึ่งเป็นสัญลักษณ์ว่าการทดสอบทั้งหมดผ่าน
การทดสอบคอนโทรลเลอร์ AngularJS
กรอบการทดสอบกรรมยังมีฟังก์ชันในการทดสอบตัวควบคุมตั้งแต่ต้นจนจบ ซึ่งรวมถึงการทดสอบวัตถุ $scope ที่ใช้ในคอนโทรลเลอร์
ลองดูตัวอย่างว่าเราจะบรรลุเป้าหมายนี้ได้อย่างไร
ในตัวอย่างของเรา
ก่อนอื่นเราจะต้องกำหนดตัวควบคุมก่อน ตัวควบคุมนี้จะดำเนินการตามขั้นตอนที่กล่าวถึงด้านล่าง
- สร้างตัวแปร ID และกำหนดค่า 5 ให้กับตัวแปรนั้น
- กำหนดตัวแปร ID ให้กับวัตถุ $scope
การทดสอบของเราจะทดสอบการมีอยู่ของคอนโทรลเลอร์นี้และทดสอบเพื่อดูว่าตัวแปร ID ของวัตถุ $scope ถูกตั้งค่าเป็น 5 หรือไม่
ก่อนอื่นเราต้องแน่ใจว่ามีข้อกำหนดเบื้องต้นต่อไปนี้
ติดตั้งไลบรารี Angular.JS-mocks ผ่านทาง npm ซึ่งสามารถทำได้โดยดำเนินการบรรทัดด้านล่างในพร้อมท์คำสั่ง
npm install Angular JS-mocks
ถัดไปคือการแก้ไขไฟล์ karma.conf.js เพื่อให้แน่ใจว่ามีไฟล์ที่ถูกต้องสำหรับการทดสอบ ส่วนด้านล่างแสดงเฉพาะส่วนของไฟล์ของ karma.conf.js ที่ต้องแก้ไข
files: ['lib/AngularJS.js','lib/AngularJS-mocks.js','lib/index.js','test/*.js']
- โดยพื้นฐานแล้วพารามิเตอร์ 'files' จะบอก Karma ถึงไฟล์ทั้งหมดที่จำเป็นในการทดสอบ
- จำเป็นต้องใช้ไฟล์ AngularJS.js และ AngularJS-mocks.js เพื่อรันการทดสอบหน่วย AngularJS
- ไฟล์ index.js จะมีโค้ดของเราสำหรับคอนโทรลเลอร์
- โฟลเดอร์ทดสอบจะมีการทดสอบ AngularJS ทั้งหมดของเรา
ด้านล่างนี้คือโค้ด Angular.JS ของเราซึ่งจะถูกจัดเก็บเป็นไฟล์ Index.js ในโฟลเดอร์ทดสอบของแอปพลิเคชันของเรา
โค้ดด้านล่างนี้ทำสิ่งต่อไปนี้
- สร้าง โมดูล AngularJS เรียกว่าแอพตัวอย่าง
- สร้างคอนโทรลเลอร์ชื่อ AngularJSController
- สร้างตัวแปรชื่อ ID โดยให้ค่า 5 และกำหนดให้กับอ็อบเจ็กต์ $scope
var sampleApp = AngularJS.module('sampleApp',[]); sampleApp.controller('AngularJSController', function($scope) { $scope.ID =5; });
เมื่อดำเนินการโค้ดข้างต้นสำเร็จแล้ว ขั้นตอนต่อไปคือการสร้าง กรณีทดสอบ เพื่อให้แน่ใจว่าโค้ดถูกเขียนและดำเนินการอย่างถูกต้อง
รหัสสำหรับการทดสอบของเราจะเป็นไปตามที่แสดงด้านล่าง
โค้ดจะอยู่ในไฟล์แยกต่างหากชื่อ ControllerTest.js ซึ่งจะวางไว้ในโฟลเดอร์ทดสอบ โค้ดด้านล่างนี้จะทำสิ่งสำคัญดังต่อไปนี้
- ฟังก์ชัน beforeEach – ฟังก์ชันนี้ใช้เพื่อโหลดโมดูล AngularJS.JS ของเราที่เรียกว่า 'sampleApp' ก่อนการทดสอบรัน โปรดทราบว่านี่คือชื่อของโมดูลในไฟล์ index.js
- วัตถุ $controller ถูกสร้างขึ้นเป็นวัตถุจำลองสำหรับตัวควบคุม ”Angular JSController” ซึ่งกำหนดไว้ในไฟล์ index.js ของเรา ในการทดสอบหน่วยประเภทใดก็ตาม วัตถุจำลองแสดงถึงวัตถุจำลองที่จะใช้สำหรับการทดสอบจริง วัตถุจำลองนี้จะจำลองพฤติกรรมของคอนโทรลเลอร์ของเราจริง ๆ
- beforeEach(inject(function(_$controller_) – ใช้เพื่อฉีดวัตถุจำลองในการทดสอบของเราเพื่อให้ทำงานเหมือนกับคอนโทรลเลอร์จริง
- var $ขอบเขต = {}; นี่คือวัตถุจำลองที่ถูกสร้างขึ้นสำหรับวัตถุ $scope
- ตัวควบคุม var = $controller('AngularJSController', { $scope: $scope }); – ที่นี่เรากำลังตรวจสอบการมีอยู่ของคอนโทรลเลอร์ชื่อ 'Angular.JSController' ในที่นี้ เรายังกำหนดตัวแปรทั้งหมดจากวัตถุ $scope ในคอนโทรลเลอร์ของเราในไฟล์ Index.js ให้กับวัตถุ $scope ในไฟล์ทดสอบของเรา
- สุดท้ายนี้ เรากำลังเปรียบเทียบ $scope.ID กับ 5
describe('AngularJSController', function() { beforeEach(module('sampleApp')); var $controller; beforeEach(inject(function(_$controller_){ $controller = _$controller_; })); describe('$scope.ID', function() { it('Check the scope object', function() { var $scope = {}; var controller = $controller('AngularJSController', { $scope: $scope }); expect($scope.ID).toEqual(5); }); }); });
การทดสอบข้างต้นจะทำงานในเบราว์เซอร์กรรมและให้ผลการผ่านเช่นเดียวกับที่แสดงในหัวข้อที่แล้ว
การทดสอบคำสั่ง AngularJS
กรอบการทดสอบกรรมยังมีฟังก์ชันในการทดสอบคำสั่งที่กำหนดเองอีกด้วย ซึ่งรวมถึง templateURL ที่ใช้ภายในคำสั่งที่กำหนดเอง
ลองดูตัวอย่างว่าเราจะบรรลุเป้าหมายนี้ได้อย่างไร
ในตัวอย่างของเรา เราจะกำหนดคำสั่งแบบกำหนดเองก่อน ซึ่งจะดำเนินการดังต่อไปนี้
- สร้างโมดูล AngularJS ชื่อ SampleApp
- สร้างคำสั่งที่กำหนดเองด้วยชื่อ – Guru99
- สร้างฟังก์ชันที่ส่งคืนเทมเพลตพร้อมแท็กส่วนหัวซึ่งแสดงข้อความ “นี่คือการทดสอบ AngularJS”
var sampleApp = AngularJS.module('sampleApp',[]); sampleApp.directive('Guru99', function () { return { restrict: 'E', replace: true, template: '<h1>This is AngularJS Testing</h1>' }; });
เมื่อดำเนินการโค้ดข้างต้นสำเร็จแล้ว ขั้นตอนต่อไปคือการสร้างกรณีทดสอบเพื่อให้แน่ใจว่าโค้ดได้รับการเขียนและดำเนินการอย่างถูกต้อง รหัสสำหรับการทดสอบของเราจะเป็นไปตามที่แสดงด้านล่าง
โค้ดจะอยู่ในไฟล์แยกต่างหากชื่อ DirectiveTest.js ซึ่งจะวางไว้ในโฟลเดอร์ทดสอบ โค้ดด้านล่างนี้ทำหน้าที่สำคัญดังต่อไปนี้
- ฟังก์ชัน beforeEach – ฟังก์ชันนี้ใช้เพื่อโหลดโมดูล Angular JS ของเราที่เรียกว่า 'sampleApp' ก่อนการทดสอบรัน
- บริการ $compile ใช้ในการรวบรวมคำสั่ง บริการนี้เป็นบริการบังคับและจำเป็นต้องประกาศเพื่อให้ Angular.JS สามารถใช้เพื่อรวบรวมคำสั่งที่กำหนดเองของเรา
- $rootscope เป็นขอบเขตหลักของแอปพลิเคชัน AngularJS.JS เราได้เห็นอ็อบเจ็กต์ $scope ของคอนโทรลเลอร์ในบทก่อนหน้านี้แล้ว อ็อบเจ็กต์ $scope คืออ็อบเจ็กต์ลูกของอ็อบเจ็กต์ $rootscope เหตุผลที่ประกาศสิ่งนี้ที่นี่ก็เนื่องมาจากเรากำลังทำการเปลี่ยนแปลงแท็ก HTML จริงใน DOM ผ่านคำสั่งที่กำหนดเองของเรา ดังนั้นเราจึงจำเป็นต้องใช้บริการ $rootscope ซึ่งจะรับฟังหรือรู้เมื่อมีการเปลี่ยนแปลงใด ๆ เกิดขึ้นจากภายในเอกสาร HTML
- องค์ประกอบ var = $คอมไพล์(“ ”) – ใช้เพื่อตรวจสอบว่าคำสั่งของเราได้รับการแทรกตามที่ควรหรือไม่ ชื่อของคำสั่งที่กำหนดเองของเราคือ Guru99 และเราทราบจากบทคำสั่งที่กำหนดเองของเราว่าเมื่อมีการแทรกคำสั่งใน HTML ของเรา มันจะถูกแทรกเป็น ' - ดังนั้นคำสั่งนี้จึงถูกนำมาใช้ในการตรวจสอบ
- คาดหวัง(element.html()).toContain(“นี่คือการทดสอบ AngularJS”) – ใช้เพื่อสั่งฟังก์ชันคาดหวังว่าควรค้นหาองค์ประกอบ (ในกรณีของเราคือแท็ก div) เพื่อให้มีข้อความ innerHTML ของ “นี่คือ การทดสอบ AngularJS”
describe('Unit testing directives', function() { var $compile, $rootScope; beforeEach(module('sampleApp')); beforeEach(inject(function(_$compile_, _$rootScope_){ $compile = _$compile_; $rootScope = _$rootScope_; })); it('Check the directive', function() { // Compile a piece of HTML containing the directive var element = $compile("<ng-Guru99></ng-Guru99>")($rootScope); $rootScope.$digest(); expect(element.html()).toContain("This is AngularJS Testing"); }); });
การทดสอบข้างต้นจะทำงานในเบราว์เซอร์กรรมและให้ผลการผ่านเช่นเดียวกับที่แสดงในหัวข้อที่แล้ว
สิ้นสุดการทดสอบแอปพลิเคชัน AngularJS JS
กรอบการทดสอบกรรมพร้อมกับกรอบงานที่เรียกว่า Protractor มีฟังก์ชันการทดสอบเว็บแอปพลิเคชันตั้งแต่ต้นจนจบ
ดังนั้นจึงไม่ใช่แค่การทดสอบคำสั่งและตัวควบคุมเท่านั้น แต่ยังทดสอบสิ่งอื่นใดที่อาจปรากฏบนหน้า HTML ด้วย
ลองดูตัวอย่างว่าเราจะบรรลุเป้าหมายนี้ได้อย่างไร
ในตัวอย่างด้านล่าง เราจะมีแอปพลิเคชัน AngularJS ซึ่งสร้างตารางข้อมูลโดยใช้คำสั่ง ng-repeat
- ขั้นแรกเรากำลังสร้างตัวแปรที่เรียกว่า "บทช่วยสอน" และกำหนดคู่คีย์-ค่าให้กับมันในขั้นตอนเดียว คู่คีย์-ค่าแต่ละคู่จะถูกใช้เป็นข้อมูลเมื่อแสดงตาราง จากนั้นตัวแปรบทช่วยสอนจะถูกกำหนดให้กับวัตถุขอบเขตเพื่อให้สามารถเข้าถึงได้จากมุมมองของเรา
- สำหรับแต่ละแถวของข้อมูลในตาราง เราใช้คำสั่ง ng-repeat คำสั่งนี้จะผ่านคู่คีย์-ค่าแต่ละคู่ในออบเจ็กต์ขอบเขตการสอนโดยใช้ตัวแปร ptutor
- ในที่สุดเราก็ใช้ แท็กพร้อมกับคู่ค่าคีย์ (ptutor.Name และ ptutor.Description) เพื่อแสดงข้อมูลตาราง
<table > <tr ng-repeat="ptutor in tutorial"> <td>{{ ptutor.Name }}</td> <td>{{ ptutor.Description }}</td> </tr> </table> </div> <script type="text/javascript"> var app = AngularJS.module('DemoApp', []); app.controller('DemoController', function($scope) { $scope.tutorial =[ {Name: "Controllers" , Description : "Controllers in action"}, {Name: "Models" , Description : "Models and binding data"}, {Name: "Directives" , Description : "Flexibility of Directives"} ] });
เมื่อดำเนินการโค้ดข้างต้นสำเร็จแล้ว ขั้นตอนต่อไปคือการสร้างกรณีทดสอบเพื่อให้แน่ใจว่าโค้ดได้รับการเขียนและดำเนินการอย่างถูกต้อง รหัสสำหรับการทดสอบของเราจะเป็นไปตามที่แสดงด้านล่าง
การทดสอบของเราจะทดสอบคำสั่ง ng-repeat และให้แน่ใจว่ามีข้อมูล 3 แถวตามที่ควรจะเป็นจากตัวอย่างข้างต้น
ก่อนอื่นเราต้องแน่ใจว่ามีข้อกำหนดเบื้องต้นต่อไปนี้
ติดตั้งไลบรารีไม้โปรแทรกเตอร์ผ่านทาง npm ซึ่งสามารถทำได้โดยดำเนินการบรรทัดด้านล่างในพร้อมท์คำสั่ง
"npm install protractor"
รหัสสำหรับการทดสอบของเราจะเป็นไปตามที่แสดงด้านล่าง
โค้ดจะอยู่ในไฟล์แยกต่างหากชื่อ CompleteTest.js ซึ่งจะวางไว้ในโฟลเดอร์ทดสอบ โค้ดด้านล่างนี้จะทำสิ่งสำคัญดังต่อไปนี้
- ฟังก์ชั่นเบราว์เซอร์จัดทำโดยไลบรารีไม้โปรแทรกเตอร์และถือว่าแอปพลิเคชัน AngularJS ของเรา (พร้อมโค้ดที่แสดงด้านบน) ทำงานบน URL เว็บไซต์ของเรา - http://localhost:8080/Guru99/
- var list=element.all(by.repeater(ptutor in tutorial')); - บรรทัดโค้ดนี้ดึงไดเร็กทิฟ ng-repeat ที่มีโค้ด 'ptutor in tutorial' อยู่ element และ by.repeater เป็นคีย์เวิร์ดพิเศษที่ไลบรารี protractor ให้มา ซึ่งช่วยให้เรารับรายละเอียดของไดเร็กทิฟ ng-repeat ได้
- คาดหวัง (list.count()).toEqual(3); – สุดท้ายนี้ เรากำลังใช้ฟังก์ชันคาดหวังเพื่อดูว่าเราได้รับ 3 รายการที่อยู่ในตารางของเราอันเป็นผลมาจากคำสั่ง ng-repeat
Describe('Unit testing end to end', function() { beforeEach(function() { browser.get('http://localhost:8080/Guru99/'); }) it('Check the ng directive', function() { var list=element.all(by.repeater(ptutor in tutorial')); expect(list.count()).toEqual(3); }); });
การทดสอบข้างต้นจะทำงานในเบราว์เซอร์กรรมและให้ผลการผ่านเช่นเดียวกับที่แสดงในหัวข้อที่แล้ว
สรุป
- การทดสอบใน AngularJS ทำได้โดยใช้เฟรมเวิร์กกรรม ซึ่งเป็นเฟรมเวิร์กที่พัฒนาโดย Google เอง
- กรอบกรรมได้รับการติดตั้งโดยใช้ตัวจัดการแพ็คเกจโหนด โมดูลสำคัญที่ต้องติดตั้งสำหรับการทดสอบขั้นพื้นฐาน ได้แก่ karma, karma-chrome-launcher ,karma-jasmine และ karma-cli
- การทดสอบจะเขียนเป็นไฟล์ js แยกกัน ซึ่งโดยปกติจะเก็บไว้ในโฟลเดอร์ทดสอบของแอปพลิเคชันของคุณ ต้องระบุตำแหน่งของไฟล์ทดสอบเหล่านี้ในไฟล์การกำหนดค่าพิเศษที่เรียกว่า karma.conf.js Karma ใช้ไฟล์การกำหนดค่านี้เมื่อทำการทดสอบทั้งหมด
- Karma สามารถใช้ทดสอบคอนโทรลเลอร์และคำสั่งแบบกำหนดเองได้เช่นกัน
- สำหรับการทดสอบเว็บตั้งแต่ต้นจนจบ จำเป็นต้องติดตั้งเฟรมเวิร์กอื่นที่เรียกว่าไม้โปรแทรกเตอร์ผ่าน Node ซึ่งเป็นตัวจัดการแพ็คเกจ กรอบนี้มีวิธีการพิเศษที่สามารถใช้เพื่อทดสอบองค์ประกอบทั้งหมดบนหน้า HTML