Hôm nay, chúng ta sẽ thảo luận về kiểm thử trong JavaScript và giúp bạn bắt đầu hành trình để hiểu và làm chủ nó.



Kiểm thử là một trong những chủ đề quan trọng nhất trong phát triển phần mềm, nhưng nhiều nhà phát triển vẫn né tránh nó. Bài viết này ở đây để thay đổi điều đó .

Động lực chính đằng sau bài viết này là cung cấp một cái nhìn tổng quan rõ ràng về toàn bộ thế giới thử nghiệm JavaScript và làm cho nó trở nên đơn giản để hiểu . Ngay cả khi bạn chưa có kinh nghiệm thử nghiệm trước, bài viết này sẽ chứng minh là bước khởi đầu hoàn hảo cho hành trình của bạn.

Vì vậy, không lãng phí thời gian nữa, hãy bắt đầu.



Giới thiệu về kiểm thử trong JavaScript
Giới thiệu về kiểm thử trong JavaScript

Tại sao kiểm tra lại quan trọng

Trước khi đi sâu vào các loại và khái niệm khác nhau của kiểm thử phần mềm, trước tiên bạn nên hiểu rõ về lý do tại sao bạn nên thực sự quan tâm đến kiểm thử tự động ngay từ đầu.



Xây dựng niềm tin vào mã của bạn:

Để biết rằng mã của bạn đang hoạt động theo kế hoạch, nó cần được kiểm tra bằng một số hình thức. Kiểm tra thủ công hoạt động đối với hầu hết các ứng dụng nhỏ nhưng không cung cấp mức độ bảo mật và độ tin cậy mà bạn nhận được khi sử dụng kiểm tra tự động.

Kiểm tra tự động giúp bạn dễ dàng kiểm tra hầu hết mọi tình huống có thể xảy ra và cho phép bạn chạy chúng bất cứ khi nào bạn thực hiện thay đổi đối với mã của mình.

Xác định mọi trường hợp thành công và thất bại và viết các bài kiểm tra cho chúng sẽ đảm bảo rằng bạn tự tin với mã bạn đang triển khai cho sản xuất.



Viết mã tối thiểu:

Kiểm tra cũng giúp bạn giảm số lượng mã bạn đang viết cho một tính năng cụ thể. Sau khi kiểm tra, mục tiêu chính của bạn là viết mã bắt buộc tối thiểu để thực hiện các bài kiểm tra. Phong cách mã hóa này nơi bạn viết các bài kiểm tra trước khi viết bản triển khai thực tế còn được gọi là TDD (Phát triển theo hướng kiểm tra).

Sau khi thử nghiệm thành công, bạn có thể tập trung vào việc viết các triển khai sạch sẽ với mã tối thiểu nhất có thể.

Thoát khỏi lỗi hồi quy:

Bạn có biết cảm giác khi bạn vừa hoàn thành một tính năng mới của ứng dụng và muốn phát hành nó vào phiên bản sản xuất và đột nhiên, một tính năng cũ không hoạt động nữa không? Bạn hoàn toàn không biết tại sao điều này lại xảy ra và có thể sẽ lãng phí rất nhiều thời gian để tìm kiếm vấn đề.

Tình huống này sẽ không bao giờ xảy ra nếu bạn đã thử nghiệm các tính năng cũ của mình. Bạn có thể đã thường xuyên chạy các bài kiểm tra đó để kiểm tra xem ứng dụng của mình có còn hoạt động như mong đợi hay không. Các thử nghiệm cũng sẽ cung cấp cho bạn ý tưởng tốt hơn về những gì chính xác không hoạt động nữa vì các trường hợp thử nghiệm thích hợp sẽ thất bại.



Các loại kiểm tra

Có một số loại thử nghiệm khác nhau và điều cần thiết là phải biết chúng khác nhau như thế nào. Hầu hết các ứng dụng sẽ yêu cầu bạn viết nhiều loại bài kiểm tra để có được kết quả tốt nhất có thể.

Bài kiểm tra đơn vị:

Mục đích của kiểm thử đơn vị là xác nhận chức năng của một phần mềm tương đối nhỏ, độc lập với các phần khác. Các bài kiểm tra đơn vị có phạm vi hẹp, cho phép chúng tôi bao gồm tất cả các trường hợp để đảm bảo rằng mọi bộ phận hoạt động chính xác.

Chúng là những bài kiểm tra nhỏ và tập trung cao, có thể được thực thi hiệu quả trên máy cục bộ của bạn vì thời gian thực hiện nhanh. Bạn sẽ có hàng trăm, nếu không muốn nói là hàng nghìn bài kiểm tra này và chạy chúng thường xuyên trong khi phát triển.

Nhược điểm duy nhất của các loại thử nghiệm này là chúng không được thực hiện trên các thiết bị thực và do đó có độ trung thực thấp hơn so với các loại thử nghiệm khác.



Kiểm tra tích hợp:

Các bài kiểm tra tích hợp chứng minh rằng các phần khác nhau của ứng dụng của bạn hoạt động cùng nhau trong môi trường sản xuất ngoài đời thực. Họ xác minh rằng hai mô-đun hoặc thành phần riêng biệt đang hoạt động cùng nhau theo cách chúng cần.

Các bài kiểm tra này có kích thước trung bình và có thời gian thực hiện cao hơn nhiều so với các bài kiểm tra Đơn vị. Chúng không được thực thi thường xuyên nhưng vẫn rất quan trọng để kiểm tra tình trạng sức khỏe của các ứng dụng của bạn. Độ trung thực của chúng cũng cao hơn rất nhiều vì chúng chạy trên các thiết bị thực và xác minh sự tương tác thực tế giữa các thành phần khác nhau trong ứng dụng của bạn.

Kiểm tra End-to-End:

Kiểm tra End-to-End xác nhận các kịch bản phức tạp từ đầu đến cuối và thường yêu cầu các tài nguyên bên ngoài, như cơ sở dữ liệu hoặc máy chủ web, phải có mặt. Hãy tưởng tượng bạn có một ứng dụng với quy trình đăng ký bao gồm một số bước và bạn muốn kiểm tra toàn bộ quy trình, đó là lúc các thử nghiệm End-to-End phát huy tác dụng.

Các bài kiểm tra E2E cũng sẽ chạy trên các thiết bị thực giống như các bài kiểm tra tích hợp và do đó, quá trình thực thi của chúng sẽ khá chậm.



Nhược điểm duy nhất của các loại thử nghiệm này là việc gỡ lỗi chúng và tìm ra lỗi nếu một thử nghiệm cụ thể không thành công trở nên rất khó khăn vì phạm vi rộng lớn của chúng.

Các khái niệm

Trước khi bắt đầu viết các bài kiểm tra cho mã của bạn, trước tiên bạn cần phải làm quen với các khái niệm kiểm thử quan trọng nhất và khi nào bạn cần sử dụng chúng. Những khái niệm này sẽ ảnh hưởng đến kiến ​​trúc của ứng dụng của bạn và cách bạn viết mã nói chung nhưng nhiều hơn về điều đó trong phần sau.

Người đối sánh:

Đối sánh cho phép bạn xác nhận kết quả và giá trị của các bài kiểm tra theo những cách khác nhau và được sử dụng để đảm bảo rằng kết quả của bài kiểm tra phù hợp với mong đợi của bạn.

Hãy tưởng tượng bạn có một hàm tính toán kết quả của một số giai thừa nhất định. Sau đó, việc kiểm tra hàm có thể được thực hiện bằng cách sử dụng hàm mong đợi () và một trình so khớp đơn giản để kiểm tra xem kết quả của hàm có khớp với giá trị mong đợi hay không.



Hàm mong đợi () kiểm tra xem kết quả có đáp ứng các điều kiện được xác định bởi trình so khớp hay không. Chúng tôi sẽ sử dụng các đối sánh khác nhau trong khuôn khổ thử nghiệm Jest ở phần sau của hướng dẫn này.

Chế giễu:



Một đối tượng được kiểm tra có thể có phụ thuộc vào các đối tượng hoặc dịch vụ khác. Để cô lập hành vi của một đối tượng, bạn muốn thay thế các đối tượng khác mà nó tương tác bằng các mô phỏng mô phỏng hành vi của các đối tượng thực.

Mocks giúp các bài kiểm tra của bạn tránh được sự không đáng tin cậy của bài kiểm tra (tính không ổn định) và cải thiện tốc độ của các bài kiểm tra của bạn. Chúng cũng hữu ích nếu các đối tượng thực không thực tế để đưa vào các bài kiểm tra.

Nói tóm lại, mocking là tạo ra các đối tượng hoặc dịch vụ mô phỏng hành vi của các đối tượng thực (một cơ sở dữ liệu chẳng hạn).

Vòng đời:

Khi thử nghiệm, bạn thường thực hiện nhiều thử nghiệm sau nhau và có một số công việc thiết lập cần phải thực hiện trước khi chạy thử nghiệm. Hầu hết các khuôn khổ cung cấp các chức năng trợ giúp để xử lý các tình huống này.

Đây là một ví dụ về các phương pháp vòng đời trong khuôn khổ thử nghiệm Jest .



Kiến trúc có thể kiểm tra

Trước khi bắt đầu viết các bài kiểm tra cho mã của bạn, trước tiên bạn cần đảm bảo rằng kiến ​​trúc ứng dụng của bạn có thể kiểm tra được. Nếu không, bạn cần hiểu tại sao không và bạn có thể làm gì với nó.

Kiến trúc không thể tin được có lẽ là lý do phổ biến nhất khiến nhiều người cảm thấy việc thử nghiệm tẻ nhạt và khó khăn. Nếu mã của bạn không được cấu trúc đúng cách, bạn chắc chắn sẽ gặp khó khăn khi viết các bài kiểm tra cho nó.

Hãy cùng khám phá một số khái niệm quan trọng bạn nên biết khi nói về kiến ​​trúc có thể kiểm tra.

Tiêm phụ thuộc:

Chèn phụ thuộc là một khái niệm trong đó một đối tượng cung cấp các phụ thuộc của một đối tượng khác. Thay vì sử dụng từ khóa mới bất cứ khi nào tạo một đối tượng mới, tất cả những gì bạn cần làm là yêu cầu đối tượng khác cung cấp cho bạn phiên bản bạn muốn.

Khái niệm này hữu ích khi bạn cần thay đổi cách triển khai của một số đối tượng, ví dụ như khi bạn mô phỏng nó cho một bài kiểm tra cụ thể. Nhiều khung công tác hiện đại như Angular và Nest.js đã tích hợp sẵn tính năng chèn phụ thuộc, nhưng vẫn tốt nếu biết nó hoạt động như thế nào ở cấp cơ sở.



SRP (Nguyên tắc trách nhiệm duy nhất):

Nguyên tắc trách nhiệm duy nhất, còn được gọi là SRP, là một trong những nguyên tắc SOLID và xác định rằng một chức năng phải có một mục đích duy nhất. Điều này làm cho việc kiểm tra xem mỗi chức năng có hoạt động chính xác hay không.

Nếu chức năng hoặc dịch vụ của bạn đang thực hiện nhiều hơn một trách nhiệm, thì đã đến lúc xác định các trách nhiệm đó và tách chúng thành các chức năng riêng lẻ.

Tránh tác dụng phụ:

Các hàm của bạn phụ thuộc vào các biến và dịch vụ bên ngoài, và bạn phải thiết lập biến hoặc dịch vụ đó trước khi kiểm tra hàm của mình. Bạn cũng sẽ phải tin tưởng rằng bất kỳ mã nào khác đang được chạy không làm thay đổi các biến và trạng thái tương tự.

Đó là lý do tại sao bạn nên tránh viết các hàm làm thay đổi bất kỳ trạng thái bên ngoài nào (như ghi vào tệp hoặc lưu giá trị vào cơ sở dữ liệu). Điều này ngăn chặn các tác dụng phụ và cho phép bạn tự tin kiểm tra mã của mình.



Định luật Demeter:

Định luật Demeter, còn được gọi là “nguyên tắc ít kiến ​​thức nhất” nói rằng một đơn vị cụ thể nên có kiến ​​thức hạn chế về các đơn vị khác mà nó phối hợp. Mã của bạn càng phụ thuộc vào các chi tiết bên trong của các đối tượng mà nó tương tác, bạn càng gặp nhiều khó khăn khi viết các bài kiểm tra cho chúng.

Tổng quan về các công cụ kiểm tra khác nhau

Bây giờ bạn đã có cái nhìn tổng quan về các khái niệm thiết yếu trong thế giới kiểm thử và khi nào bạn cần sử dụng chúng, hãy tiếp tục bằng cách xem qua bản tóm tắt ngắn về các công cụ kiểm tra Javascript khác nhau hiện có.

Lưu ý: Tôi sẽ không đề cập đến mọi công cụ ở đó mà thay vào đó hãy xem xét những công cụ quan trọng nhất một lần để cung cấp cho bạn cái nhìn tổng quan về những lợi ích và điểm yếu ở đó.

Jest là một khung thử nghiệm mã nguồn mở do Facebook tạo ra với trọng tâm là sự đơn giản. Jest làm cho việc viết các bài kiểm tra JavaScript nhanh hơn và dễ dàng hơn bằng cách đưa mọi thứ ra khỏi hộp và không cần cấu hình. Jest cũng chạy các thử nghiệm của bạn song song, mang lại quá trình chạy thử nhanh hơn, mượt mà hơn.



Mocha là một thư viện kiểm tra JavaScript linh hoạt có sẵn và nhằm mục đích làm cho kiểm tra không đồng bộ trở nên đơn giản và thú vị Nó cung cấp cho các nhà phát triển một khung thử nghiệm cơ bản và cung cấp cho họ tùy chọn để chọn thư viện xác nhận, chế nhạo và gián điệp mà họ muốn sử dụng.

Nó yêu cầu một số thiết lập và cấu hình bổ sung nhưng đổi lại, bạn có thể kiểm soát hoàn toàn khung thử nghiệm của mình.

Cypress là một công cụ kiểm tra tất cả trong một, tập trung vào việc giúp kiểm tra End-to-End dễ dàng và hiện đại. Các bài kiểm tra của họ được thực hiện trong chính trình duyệt, điều này mang lại cho họ thời gian thực thi tốt hơn và không có độ trễ mạng.

Cypress được sử dụng để xử lý giao diện người dùng phức tạp chạy trên các ngăn xếp Javascript hiện đại. Bằng cách sử dụng khung và thư viện xác nhận của chúng, bạn có thể dễ dàng xác nhận các trạng thái trong giao diện người dùng. Sau đó, Cypress sẽ tự động đợi ứng dụng của bạn đạt đến trạng thái này trước khi tiếp tục.

Cypress là một công cụ mới hơn và hiện đại hơn Jest và Mocha và là một khởi đầu tuyệt vời cho người mới bắt đầu và thử nghiệm End-to-End nói chung.



Giới thiệu về Jest

Như đã đề cập ở trên, hướng dẫn này sẽ tập trung vào khung thử nghiệm Jest vì nó là khung phổ biến nhất hiện có. Nhưng hầu hết các khái niệm đều áp dụng cho tất cả các khuôn khổ thử nghiệm và có thể hữu ích cho dù bạn đang sử dụng công nghệ nào.

Jest là một dự án mã nguồn mở được duy trì bởi Facebook và đặc biệt rất phù hợp để thử nghiệm Đơn vị và Tích hợp. Điểm mạnh của nó là:

  • Nó đơn giản và nhanh chóng
  • Nó cung cấp mọi thứ bên ngoài và do đó không yêu cầu và cấu hình (mặc dù bạn có thể thay đổi cấu hình nếu bạn muốn)
  • Nó có thể thực hiện kiểm tra ảnh chụp nhanh

Bây giờ chúng ta sẽ khám phá một số ví dụ thực tế để bạn có thể áp dụng kiến ​​thức của mình vào thực tế.



Người đối sánh

Như đã nói ở trên, các trình so khớp cho phép bạn xác nhận kết quả và giá trị của các bài kiểm tra theo những cách khác nhau.

Chúng thường được sử dụng nhất để so sánh kết quả của hàm mong đợi () với giá trị được truyền dưới dạng đối số cho trình so khớp (Đó cũng là những gì chúng ta đã làm ở trên).

Dưới đây là danh sách các đối sánh phổ biến nhất:

  • toBe – so sánh về sự bình đẳng nghiêm ngặt (ví dụ: ===)
  • toEqual – so sánh giá trị của hai biến / đối tượng
  • toBeNull – kiểm tra nếu giá trị là null
  • toBeDefined – kiểm tra xem giá trị có được xác định không
  • toBeUndefined – kiểm tra nếu giá trị là không xác định
  • toBeTruthy – kiểm tra xem giá trị có đúng không (tương tự như câu lệnh if)
  • toBeFalsy – kiểm tra xem giá trị có sai không (tương tự như câu lệnh if)
  • toBeGreaterThan – kiểm tra xem kết quả của hàm mong đợi () có lớn hơn đối số hay không
  • toContain – kiểm tra xem kết quả của kỳ vọng () có chứa giá trị không
  • toHaveProperty – kiểm tra xem một đối tượng có thuộc tính hay không và tùy chọn kiểm tra giá trị của nó
  • toBeInstanceOf – kiểm tra xem một đối tượng có phải là một thể hiện của một lớp hay không

Thiết lập và Gỡ bỏ

Thông thường khi viết các bài kiểm tra, bạn sẽ phải thực hiện một số loại thiết lập như khởi tạo các biến trước khi chạy các bài kiểm tra và một số loại hành động sau khi chúng kết thúc.

Jest cung cấp hai cách khác nhau để bạn có thể làm điều đó.



Thiết lập một lần:

Trong một số trường hợp, bạn chỉ cần thiết lập một lần ở đầu tệp thử nghiệm của mình. Trong trường hợp đó, bạn có thể sử dụng các hàm trợ giúp beforeAll () và afterAll () sẽ thực thi trước khi quá trình kiểm tra bắt đầu và sau khi tất cả kết thúc.

Thiết lập lặp lại cho mỗi bài kiểm tra:

Nếu bạn có một quy trình thiết lập cần chạy trước mỗi lần kiểm tra, bạn nên sử dụng các hàm beforeEach () và afterEach () .

Lưu ý: Sẽ có những trường hợp mà bạn sẽ sử dụng cả hai quy trình thiết lập này cùng nhau để đạt được kết quả tốt nhất.

Nhóm các bài kiểm tra

Bạn cũng có thể nhóm các thử nghiệm liên quan lại với nhau để có thể tách biệt các chức năng thiết lập và xé nhỏ. Nhóm các bài kiểm tra cũng sẽ giúp bạn có cái nhìn tổng quan hơn về các trường hợp kiểm thử khác nhau của mình.

Kiểm tra các chức năng không đồng bộ

Mã Javascript thường chạy không đồng bộ bằng cách sử dụng các lời hứa hoặc lệnh gọi lại. Vấn đề với việc kiểm tra mã không đồng bộ là biết khi nào mã mà bạn đang kiểm tra thực sự hoàn tất. Jest có một số cách để xử lý điều này.



Lời hứa:

Thử nghiệm hứa hẹn sẽ thẳng tiến trong Jest. Chỉ cần trả lại lời hứa và Jest sẽ đợi lời hứa giải quyết. Nếu lời hứa không thành công, bài kiểm tra cũng sẽ tự động thất bại.



1 COMMENT

LEAVE A REPLY

Please enter your comment!
Please enter your name here