Ví dụ python kiểm tra đơn vị giả
Chế giễu có thể khó hiểu. Khi tôi đang kiểm tra mã mà tôi đã viết, tôi muốn xem liệu mã có thực hiện những gì nó phải làm từ đầu đến cuối không. Tôi thường bắt đầu nghĩ về một bài kiểm tra tích hợp, chức năng, nơi tôi nhập thông tin đầu vào thực tế và nhận được đầu ra thực tế. Tôi truy cập mọi hệ thống thực mà mã của tôi sử dụng để đảm bảo tương tác giữa các hệ thống đó đang hoạt động bình thường, sử dụng đối tượng thực và lệnh gọi API thực. Mặc dù các loại thử nghiệm này là cần thiết để xác minh rằng các hệ thống phức tạp đang hoạt động tốt với nhau, nhưng chúng không phải là thứ chúng tôi muốn từ các thử nghiệm đơn vị Show
Các bài kiểm tra đơn vị là kiểm tra lớp ngoài cùng của mã. Các bài kiểm tra tích hợp là cần thiết, nhưng các bài kiểm tra đơn vị tự động mà chúng tôi chạy sẽ không đạt được mức độ tương tác hệ thống sâu như vậy. Điều này có nghĩa là bất kỳ lệnh gọi API nào trong chức năng mà chúng tôi đang thử nghiệm đều có thể và nên được mô phỏng. Chúng ta nên thay thế bất kỳ lệnh gọi API hoặc tạo đối tượng không cần thiết nào bằng một lệnh gọi hoặc đối tượng giả. Điều này cho phép chúng tôi tránh sử dụng tài nguyên không cần thiết, đơn giản hóa việc khởi tạo các thử nghiệm của chúng tôi và giảm thời gian chạy của chúng. Hãy nghĩ đến việc thử nghiệm một chức năng truy cập API HTTP bên ngoài. Thay vì đảm bảo rằng máy chủ thử nghiệm có sẵn để gửi phản hồi chính xác, chúng tôi có thể thử thư viện HTTP và thay thế tất cả các lệnh gọi HTTP bằng các lệnh gọi giả. Điều này làm giảm sự phụ thuộc và độ phức tạp của thử nghiệm, đồng thời cho phép chúng tôi kiểm soát chính xác những gì thư viện HTTP trả về, điều này có thể khó thực hiện nếu không Chúng ta có ý gì khi chế giễu?
Thuật ngữ chế nhạo được sử dụng rất nhiều, nhưng tài liệu này sử dụng định nghĩa sau
Một lệnh gọi hàm giả trả về một giá trị được xác định trước ngay lập tức mà không thực hiện bất kỳ công việc nào. Các thuộc tính và phương thức của đối tượng mô phỏng được xác định hoàn toàn tương tự trong thử nghiệm mà không cần tạo đối tượng thực hoặc thực hiện bất kỳ công việc nào. Thực tế là người viết bài kiểm tra có thể xác định các giá trị trả về của mỗi lệnh gọi hàm mang lại cho người đó một lượng sức mạnh to lớn khi kiểm tra, nhưng điều đó cũng có nghĩa là người đó cần thực hiện một số công việc cơ bản để thiết lập mọi thứ đúng cách.
Trong Python, việc chế nhạo được thực hiện thông qua mô-đun 0. Mô-đun chứa một số lớp và hàm hữu ích, trong đó quan trọng nhất là hàm 1 (với vai trò trang trí và quản lý ngữ cảnh) và lớp 2. Mocking trong Python phần lớn được thực hiện thông qua việc sử dụng hai thành phần mạnh mẽ nàyChúng ta KHÔNG có ý gì bằng cách chế nhạo?
Các nhà phát triển sử dụng nhiều đối tượng hoặc mô-đun "giả", là những thay thế cục bộ đầy đủ chức năng cho các dịch vụ và API được nối mạng. Ví dụ: thư viện 3 là thư viện 4 giả thu thập tất cả các lệnh gọi API của 4 và xử lý chúng cục bộ. Mặc dù các mô phỏng này cho phép các nhà phát triển thử nghiệm cục bộ các API bên ngoài, nhưng chúng vẫn yêu cầu tạo các đối tượng thực. Đây không phải là kiểu chế giễu được đề cập trong tài liệu này. Tài liệu này đặc biệt về việc sử dụng các đối tượng 2 để quản lý đầy đủ luồng điều khiển của chức năng được kiểm tra, cho phép dễ dàng kiểm tra lỗi và xử lý ngoại lệLàm cách nào để chúng tôi mô phỏng bằng Python?
Mocking trong Python được thực hiện bằng cách sử dụng 1 để chiếm quyền điều khiển một chức năng API hoặc lệnh gọi tạo đối tượng. Khi 1 chặn một cuộc gọi, nó sẽ trả về một đối tượng 2 theo mặc định. Bằng cách đặt các thuộc tính trên đối tượng 2, bạn có thể mô phỏng lệnh gọi API để trả về bất kỳ giá trị nào bạn muốn hoặc tăng 11
Quy trình chung như sau
Nếu bài kiểm tra của bạn vượt qua, bạn đã hoàn thành. Nếu không, bạn có thể gặp lỗi trong chức năng đang được kiểm tra hoặc bạn có thể đã thiết lập phản hồi 2 không chính xác. Tiếp theo, chúng ta sẽ đi vào chi tiết hơn về các công cụ mà bạn sử dụng để tạo và định cấu hình mô hìnhvá 4
1 có thể được sử dụng làm công cụ trang trí cho hàm kiểm tra, lấy một chuỗi đặt tên hàm sẽ được vá làm đối số. Để 1 xác định vị trí chức năng được vá, chức năng này phải được chỉ định bằng tên đủ điều kiện của nó, đây có thể không phải là điều bạn mong đợi. Nếu một lớp được nhập bằng cách sử dụng câu lệnh 16, thì 17 sẽ trở thành một phần của không gian tên của mô-đun mà nó được nhập vào
Ví dụ: nếu một lớp được nhập trong mô-đun 18 như sau
Nó phải được vá thành 19, thay vì 20, do ngữ nghĩa của câu lệnh 21, câu lệnh nhập các lớp và hàm vào không gian tên hiện tại
Thông thường, 1 được sử dụng để vá một lệnh gọi API bên ngoài hoặc bất kỳ lệnh gọi chức năng hoặc tạo đối tượng nào khác tốn nhiều thời gian hoặc tài nguyên. Bạn chỉ nên vá một số lệnh gọi cho mỗi lần kiểm tra. Nếu bạn thấy mình đang thử 1 nhiều lần, hãy cân nhắc tái cấu trúc bài kiểm tra của bạn hoặc chức năng bạn đang kiểm tra
Sử dụng trình trang trí 1 sẽ tự động gửi đối số vị trí đến chức năng bạn đang trang trí (i. e. , chức năng kiểm tra của bạn). Khi vá nhiều chức năng, trình trang trí gần nhất với chức năng được trang trí sẽ được gọi trước, do đó, nó sẽ tạo đối số vị trí đầu tiên
1
Theo mặc định, các đối số này là phiên bản của 2, là đối tượng chế nhạo mặc định của 0. Bạn có thể xác định hành vi của hàm đã vá bằng cách đặt các thuộc tính trên phiên bản 2 được trả về
MagicMock
Các đối tượng 2 cung cấp một giao diện mô phỏng đơn giản cho phép bạn đặt giá trị trả về hoặc hành vi khác của lệnh gọi hàm hoặc tạo đối tượng mà bạn đã vá. Điều này cho phép bạn xác định đầy đủ hành vi của cuộc gọi và tránh tạo các đối tượng thực, điều này có thể gây khó khăn. Ví dụ: nếu chúng tôi đang vá một lệnh gọi tới 29, một lệnh gọi thư viện HTTP, thì chúng tôi có thể xác định phản hồi cho lệnh gọi đó sẽ được trả về khi lệnh gọi API được thực hiện trong chức năng đang thử nghiệm, thay vì đảm bảo rằng máy chủ thử nghiệm được
Hai thuộc tính quan trọng nhất của phiên bản 2 là 41 và 42, cả hai thuộc tính này đều cho phép chúng tôi xác định hành vi trả về của lệnh gọi đã vá lỗireturn_value
Thuộc tính 41 trên phiên bản 2 được chuyển vào hàm kiểm tra của bạn cho phép bạn chọn kết quả trả về có thể gọi được đã vá. Trong hầu hết các trường hợp, bạn sẽ muốn trả về một phiên bản giả của phiên bản có thể gọi được thường trả về. Đây có thể là JSON, một lần lặp, một giá trị, một thể hiện của đối tượng phản hồi thực, một 2 giả làm đối tượng phản hồi hoặc bất kỳ thứ gì khác. Khi vá các đối tượng, lệnh gọi được vá là lệnh gọi tạo đối tượng, do đó, 41 của 2 phải là một đối tượng giả, có thể là một 2 khácNếu mã bạn đang kiểm tra là Pythonic và gõ vịt thay vì gõ rõ ràng, thì việc sử dụng 2 làm đối tượng phản hồi có thể thuận tiện. Thay vì gặp rắc rối khi tạo một thể hiện thực của một lớp, bạn có thể định nghĩa các cặp khóa-giá trị thuộc tính tùy ý trong hàm tạo 2 và chúng sẽ tự động được áp dụng cho thể hiện
2
Lưu ý rằng đối số được chuyển đến 51, tôi. e. , 52, là một 2 và chúng tôi đang đặt 41 thành một 2 khác. Khi chế giễu, mọi thứ đều là 2Chỉ định một MagicMock
Mặc dù tính linh hoạt của 2 thuận tiện cho việc mô phỏng nhanh các lớp có yêu cầu phức tạp, nhưng nó cũng có thể là nhược điểm. Theo mặc định, các 2 hoạt động như thể chúng có bất kỳ thuộc tính nào, kể cả những thuộc tính mà bạn không muốn chúng có. Trong ví dụ trên, chúng tôi trả về đối tượng 2 thay vì đối tượng 40. Tuy nhiên, giả sử chúng ta đã mắc lỗi trong lệnh gọi 1 và đã vá một hàm được cho là trả về một đối tượng 42 thay vì một đối tượng 40. 2 mà chúng ta trả về sẽ vẫn hoạt động như thể nó có tất cả các thuộc tính của đối tượng 42, mặc dù chúng ta muốn nó mô hình hóa một đối tượng 40. Điều này có thể dẫn đến lỗi kiểm tra khó hiểu và hành vi kiểm tra không chính xác
Giải pháp cho vấn đề này là ________ 547 trong 2 khi tạo nó, sử dụng đối số từ khóa ________ 547. 40. Điều này tạo ra một 2 sẽ chỉ cho phép truy cập vào các thuộc tính và phương thức trong lớp mà từ đó 2 được xác định. Cố gắng truy cập một thuộc tính không có trong đối tượng ban đầu sẽ làm tăng 43, giống như đối tượng thực sẽ. Một ví dụ đơn giản là
4tác dụng phụ
Đôi khi, bạn sẽ muốn kiểm tra xem hàm của mình có xử lý chính xác một ngoại lệ hay không hoặc nhiều lệnh gọi của hàm bạn đang vá có được xử lý chính xác không. Bạn có thể làm điều đó bằng cách sử dụng 42. Đặt 42 thành một ngoại lệ sẽ tăng ngoại lệ đó ngay lập tức khi chức năng được vá được gọi
Đặt 42 thành một iterable sẽ trả về mục tiếp theo từ iterable mỗi khi chức năng được vá được gọi. Đặt 42 thành bất kỳ giá trị nào khác sẽ trả về giá trị đó
5khẳng định_gọi_với
48 khẳng định rằng hàm đã vá đã được gọi với các đối số được chỉ định làm đối số cho 48
4Một ví dụ đầy đủ
Trong ví dụ này, tôi đang thử nghiệm hàm 70 trên 71. Điều này có nghĩa là lệnh gọi API trong 72 sẽ được thực hiện hai lần, đây là thời điểm tuyệt vời để sử dụng 73
Mã đầy đủ của ví dụ ở đây
4
Tôi đang vá hai cuộc gọi trong chức năng đang được kiểm tra ( 74), một đến 75 và một đến 76. Vì tôi đang vá hai cuộc gọi, tôi nhận được hai đối số cho hàm kiểm tra của mình, mà tôi đã gọi là 77 và 78. Đây là cả hai đối tượng 2. Ở trạng thái mặc định, họ không làm gì nhiều. Chúng ta cần chỉ định một số hành vi phản hồi cho họ
7
Thử nghiệm này để đảm bảo rằng cơ sở thử lại cuối cùng cũng hoạt động, vì vậy tôi sẽ gọi cập nhật nhiều lần và thực hiện nhiều cuộc gọi tới 75 và 76
Ở đây tôi thiết lập các 42 mà tôi muốn. Tôi muốn tất cả các cuộc gọi tới 75 hoạt động (trả lại một 34 trống là tốt cho bài kiểm tra này), cuộc gọi đầu tiên tới 76 không thành công với một ngoại lệ và cuộc gọi thứ hai tới 76 hoạt động. Loại kiểm soát chi tiết đối với hành vi này chỉ có thể thực hiện được thông qua chế nhạo
3
Khi tôi đã thiết lập xong các 42, phần còn lại của bài kiểm tra rất đơn giản. hành vi là. cuộc gọi đầu tiên tới 76 không thành công, vì vậy cơ sở thử lại bao bọc 39 sẽ phát hiện lỗi và mọi thứ sẽ hoạt động lần thứ hai. Hành vi này có thể được xác minh thêm bằng cách kiểm tra lịch sử cuộc gọi của 78 và 77Sự kết luận
Việc sử dụng các đối tượng giả một cách chính xác đi ngược lại trực giác của chúng ta để làm cho các bài kiểm tra thực tế và kỹ lưỡng nhất có thể, nhưng làm như vậy sẽ cho chúng ta khả năng viết các bài kiểm tra độc lập chạy nhanh, không phụ thuộc. Nó cung cấp cho chúng tôi sức mạnh để kiểm tra xử lý ngoại lệ và các trường hợp cạnh mà nếu không thì không thể kiểm tra. Quan trọng nhất, nó cho phép chúng tôi tự do tập trung nỗ lực thử nghiệm vào chức năng của mã, thay vì khả năng thiết lập môi trường thử nghiệm. Bằng cách tập trung vào kiểm tra những gì quan trọng, chúng tôi có thể cải thiện phạm vi kiểm tra và tăng độ tin cậy của mã, đó là lý do tại sao chúng tôi kiểm tra ngay từ đầu Thử nghiệm đơn vị với ví dụ Python là gì?Kiểm tra đơn vị là phương pháp kiểm tra phần mềm xem xét các đoạn mã nhỏ nhất có thể kiểm tra được, được gọi là đơn vị, được kiểm tra để hoạt động chính xác . Bằng cách thực hiện kiểm tra đơn vị, chúng tôi có thể xác minh rằng từng phần của mã, bao gồm các chức năng của trình trợ giúp có thể không được hiển thị cho người dùng, hoạt động chính xác và như dự định.
Sự khác biệt giữa giả và MagicMock là gì?Vậy sự khác biệt giữa chúng là gì? . Nó chứa tất cả các phương pháp ma thuật được tạo sẵn và sẵn sàng để sử dụng (e. g. __str__ , __len__ , v.v. ). Do đó, bạn nên sử dụng MagicMock khi cần các phương thức ma thuật và Mock nếu không cần. MagicMock is a subclass of Mock . It contains all magic methods pre-created and ready to use (e.g. __str__ , __len__ , etc.). Therefore, you should use MagicMock when you need magic methods, and Mock if you don't need them.
Bạn có thể giả lập các biến trong Python không?Với biến mô-đun, bạn có thể đặt giá trị trực tiếp hoặc sử dụng mô hình . |