Bài viết này đáng để bạn chú ý nếu bạn Đam mê viết phần mềm chất lượng tốt và muốn nâng cao tính ổn định của ứng dụng bằng các thử nghiệm. Bạn cảm thấy mệt mỏi với những lỗi không mong muốn xuất hiện trong hệ thống sản xuất của mình. Cần trợ giúp để hiểu thử nghiệm tự động là gì và cách tiếp cận chúng. Tại sao chúng ta cần kiểm tra tự động? Là kỹ sư, chúng tôi muốn nhưng với mỗi tính năng mới mà chúng tôi tạo ra, chúng tôi chắc chắn sẽ tăng quy mô và độ phức tạp của ứng dụng của mình. xây dựng những thứ hoạt động được Khi sản phẩm phát triển, việc kiểm tra (ví dụ: bằng tay) mọi chức năng bị ảnh hưởng bởi những thay đổi của bạn sẽ ngày càng tốn nhiều thời gian hơn. thủ công Việc thiếu các thử nghiệm tự động dẫn đến việc chúng tôi mất quá nhiều thời gian và làm chậm tốc độ vận chuyển hoặc chi tiêu quá ít để tiết kiệm vận tốc, dẫn đến các lỗi mới tồn đọng cùng với các cuộc gọi đêm khuya từ PagerDuty. Ngược lại, . Vì vậy, máy tính có thể được lập trình để làm điều tương tự nhiều lần hãy giao việc kiểm tra cho máy tính! Các loại bài kiểm tra gợi ý . Hãy đi sâu vào từng loại và hiểu lý do tại sao chúng ta cần từng loại. Ý tưởng kim tự tháp Thử nghiệm ba loại thử nghiệm chính: đơn vị, tích hợp và từ đầu đến cuối Kiểm tra đơn vị là một phần logic nhỏ mà bạn kiểm tra một (không dựa vào các thành phần khác). Đơn vị cách riêng biệt Họ hoàn thành trong vòng vài giây. cho phép họ chạy chúng bất kỳ lúc nào, cục bộ và trên CI mà không cần khởi động các dịch vụ phụ thuộc/thực hiện lệnh gọi API và cơ sở dữ liệu. Kiểm tra đơn vị là nhanh chóng. Sự cô lập Một hàm chấp nhận hai số và tính tổng chúng lại với nhau. Chúng tôi muốn gọi nó bằng các đối số khác nhau và khẳng định rằng giá trị trả về là chính xác. Ví dụ về kiểm thử đơn vị: // Function "sum" is the unit const sum = (x, y) => x + y test('sums numbers', () => { // Call the function, record the result const result = sum(1, 2); // Assert the result expect(result).toBe(3) }) test('sums numbers', () => { // Call the function, record the result const result = sum(5, 10); // Assert the result expect(result).toBe(15) }) Một ví dụ thú vị hơn là thành phần React hiển thị một số văn bản sau khi yêu cầu API kết thúc. Chúng tôi cần mô phỏng mô-đun API để trả về các giá trị cần thiết cho các thử nghiệm của mình, hiển thị thành phần và xác nhận HTML được hiển thị có nội dung chúng tôi cần. // "MyComponent" is the unit const MyComponent = () => { const { isLoading } = apiModule.useSomeApiCall(); return isLoading ? <div>Loading...</div> : <div>Hello world</div> } test('renders loading spinner when loading', () => { // Mocking the API module, so that it returns the value we need jest.mock(apiModule).mockReturnValue(() => ({ useSomeApiCall: jest.fn(() => ({ // Return "isLoading: false" for this test case isLoading: false })) })) // Execute the unit (render the component) const result = render(<MyComponent />) // Assert the result result.findByText('Loading...').toBeInTheDocument() }) test('renders text content when not loading', () => { // Mocking the API module jest.mock(apiModule).mockReturnValue(() => ({ useSomeApiCall: jest.fn(() => ({ // Return "isLoading: false" for this test case isLoading: false })) })) // Execute the unit (render the component) const result = render(<MyComponent />) // Assert the result result.findByText('Hello world').toBeInTheDocument() }) Kiểm tra tích hợp Khi của bạn tương tác với , chúng tôi gọi đó là . Các thử nghiệm này chậm hơn thử nghiệm đơn vị nhưng chúng kiểm tra cách các phần trong ứng dụng của bạn kết nối. đơn vị các đơn vị khác (phụ thuộc) sự tích hợp Một dịch vụ tạo người dùng trong cơ sở dữ liệu. Điều này đòi hỏi phải có phiên bản DB ( ) khi thực hiện kiểm thử. Chúng tôi sẽ kiểm tra xem dịch vụ có thể tạo và truy xuất người dùng từ DB hay không. Ví dụ về kiểm thử tích hợp: phụ thuộc import db from 'db' // We will be testing "createUser" and "getUser" const createUser = name => db.createUser(name) // creates a user const getUser = name => db.getUserOrNull(name) // retrieves a user or null test("creates and retrieves users", () => { // Try to get a user that doesn't exist, assert Null is returned const nonExistingUser = getUser("i don't exist") expect(nonExistingUser).toBe(null); // Create a user const userName = "test-user" createUser(userName); // Get the user that was just created, assert it's not Null const user = getUser(userName); expect(user).to.not.be(null) }) Kiểm tra đầu cuối Đây là thử nghiệm khi chúng tôi thử nghiệm , trong đó tất cả các phần phụ thuộc của nó đều có sẵn. Những thử nghiệm đó mô phỏng tốt nhất hành vi thực tế của người dùng và cho phép bạn nắm bắt trong ứng dụng của mình, nhưng chúng là loại thử nghiệm . toàn diện ứng dụng được triển khai đầy đủ tất cả các vấn đề có thể xảy ra chậm nhất Bất cứ khi nào muốn chạy thử nghiệm toàn diện, bạn phải cung cấp tất cả cơ sở hạ tầng và đảm bảo có sẵn các nhà cung cấp bên thứ 3 trong môi trường của bạn. Bạn muốn có chúng cho các tính năng của ứng dụng. chỉ quan trọng Luồng đăng nhập. Chúng tôi muốn truy cập ứng dụng, điền thông tin đăng nhập, gửi ứng dụng và xem thông báo chào mừng. Chúng ta hãy xem một ví dụ thử nghiệm toàn diện: test('user can log in', () => { // Visit the login page page.goto('https://example.com/login'); // Fill in the login form page.fill('#username', 'john'); page.fill('#password', 'some-password'); // Click the login button page.click('#login-button'); // Assert the welcome message is visible page.assertTextVisible('Welcome, John!') }) Làm thế nào để bạn chọn loại bài kiểm tra để viết? Hãy nhớ rằng và . kiểm thử toàn diện chậm hơn kiểm thử tích hợp kiểm thử tích hợp chậm hơn kiểm thử đơn vị Nếu tính năng bạn đang phát triển có vai trò quan trọng, hãy cân nhắc viết ít nhất một bài kiểm tra (chẳng hạn như kiểm tra cách hoạt động của chức năng Đăng nhập khi phát triển quy trình Xác thực). toàn diện Bên cạnh các luồng quan trọng của nhiệm vụ, chúng tôi muốn thử nghiệm càng nhiều trường hợp đặc biệt và các trạng thái khác nhau của tính năng càng tốt. cho phép chúng tôi kiểm tra cách các phần của ứng dụng hoạt động cùng nhau. Kiểm tra tích hợp Điểm cuối phải thực hiện các thao tác, tạo ra kết quả mong đợi và không đưa ra bất kỳ lỗi không mong muốn nào. Có các bài kiểm tra tích hợp cho các điểm cuối và các thành phần máy khách là một ý tưởng hay. Các thành phần máy khách phải hiển thị nội dung chính xác và phản hồi các tương tác của người dùng theo cách bạn mong đợi họ phản hồi. Và cuối cùng, khi nào chúng ta nên chọn ? Tất cả các hàm nhỏ có thể được kiểm tra riêng biệt, chẳng hạn như tổng các số, hiển thị thẻ , đều là những ứng cử viên tuyệt vời cho các bài kiểm tra đơn vị. Các đơn vị sẽ hoàn hảo nếu bạn tuân theo phương pháp . unit test sum Button <button> Phát triển dựa trên thử nghiệm Cái gì tiếp theo? (nhưng bắt đầu nhỏ) Viết một số bài kiểm tra! phù hợp với dự án/ngôn ngữ của bạn. Mỗi ngôn ngữ đều có một thư viện phổ biến để thử nghiệm, chẳng hạn như / cho JavaScript, / cho end-to-end (cũng sử dụng JavaScript), cho Java, v.v. Cài đặt khung kiểm tra Jest Vitest Cypress Playwright JUnit Tìm một chức năng nhỏ trong dự án của bạn và viết bài kiểm tra cho nó. đơn vị Viết bài kiểm thử cho một số tương tác giữa thành phần/dịch vụ-cơ sở dữ liệu. tích hợp Chọn một kịch bản quan trọng có thể được kiểm tra nhanh chóng, chẳng hạn như một luồng đăng nhập đơn giản và viết một bài kiểm tra cho kịch bản đó. toàn diện Làm những điều trên một lần để hiểu nó hoạt động như thế nào. Sau đó, thực hiện lại trong quá trình xử lý một số tính năng/lỗi. Sau đó chia sẻ nó với đồng nghiệp của bạn để tất cả các bạn viết bài kiểm tra, tiết kiệm thời gian và ngủ ngon hơn vào ban đêm! Tài nguyên hữu ích: của tôi Blog cá nhân của Kim tự tháp kiểm tra thực hành Ham Vocke của Phát triển dựa trên thử nghiệm Martin Fowler