Hướng dẫn how does mocking work in python? - làm thế nào để chế nhạo hoạt động trong python?
Bài đăng này được viết bởi Mike Lin. Show
Chào mừng bạn đến với một hướng dẫn về những điều cơ bản của chế giễu trong Python. Nó được sinh ra từ nhu cầu của tôi để kiểm tra một số mã đã sử dụng nhiều dịch vụ mạng và kinh nghiệm của tôi với Gomock, cho tôi thấy chế giễu mạnh mẽ như thế nào khi được thực hiện chính xác (cảm ơn, Tyler). Tôi sẽ bắt đầu với một cuộc thảo luận triết học về việc chế giễu bởi vì chế giễu tốt đòi hỏi một tư duy khác với sự phát triển tốt. Phát triển là về việc làm mọi thứ, trong khi chế giễu là về việc giả mạo mọi thứ. Điều này có vẻ rõ ràng, nhưng khía cạnh "giả mạo" của các bài kiểm tra chế giễu chạy sâu và hiểu điều này hoàn toàn thay đổi cách người ta nhìn vào thử nghiệm. Sau đó, chúng tôi sẽ xem xét các công cụ chế giễu mà Python cung cấp, và sau đó chúng tôi sẽ kết thúc với một ví dụ đầy đủ. Tìm hiểu thêm về mã kiểm tra cho bảo mật Python với tờ cheat của chúng tôi., which showed me how powerful mocking can be when done correctly (thanks, Tyler). I'll begin with a philosophical discussion about mocking because good mocking requires a different mindset than good development. Development is about making things, while mocking is about faking things. This may seem obvious, but the "faking it" aspect of mocking tests runs deep, and understanding this completely changes how one looks at testing. After that, we'll look into the mocking tools that Python provides, and then we'll finish up with a full example. Learn more about testing code for python security with our cheat-sheet.Chế giễu có thể khó hiểu. Khi tôi 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 hay 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, trong đó tôi nhập vào đầ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 các tương tác giữa các hệ thống đó hoạt động đúng, sử dụng các đối tượng thực và các cuộc gọi API thực. Mặc dù các loại thử nghiệm này rất cần thiết để xác minh rằng các hệ thống phức tạp đang làm việc tốt, nhưng chúng không phải là những gì chúng ta muốn từ các bài kiểm tra đơn vị. Các bài kiểm tra đơn vị là về việc kiểm tra lớp ngoài cùng của mã. Các thử nghiệm 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 không nên đạt đến độ sâu tương tác của hệ thống. Điều này có nghĩa là bất kỳ cuộc gọi API nào trong chức năng chúng tôi đang thử nghiệm có thể và nên bị chế giễu. Chúng ta nên thay thế mọi cuộc gọi API hoặc tạo đối tượng không cần thiết bằng một cuộc 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 bài kiểm tra của chúng tôi và giảm thời gian chạy của chúng. Hãy nghĩ về việc kiểm tra một chức năng truy cập API HTTP bên ngoài. Thay vì đảm bảo rằng một máy chủ thử nghiệm có sẵn để gửi các phản hồi chính xác, chúng tôi có thể chế giễu thư viện HTTP và thay thế tất cả các cuộc gọi HTTP bằng các cuộc gọi giả. Điều này làm giảm sự phức tạp và phụ thuộc của thử nghiệm, và cung cấp cho chúng tôi sự kiểm soát chính xác đối với những gì thư viện HTTP trả về, điều này có thể khó thực hiện khác. Chúng ta có nghĩa là gì khi chế giễu? & Nbsp; & nbsp;Thuật ngữ chế giễu được ném xung quanh rất nhiều, nhưng tài liệu này sử dụng định nghĩa sau:
Một cuộc 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 giả được xác định tương tự hoàn toàn trong thử nghiệm, mà không 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 cuộc gọi hàm mang lại cho anh ta hoặc cô ta một sức mạnh to lớn khi thử nghiệm, nhưng điều đó cũng có nghĩa là anh ta cần phải thực hiện một số công việc nền tảng để thiết lập mọi thứ đúng. Trong Python, chế giễu được thực hiện thông qua mô -đun 0. Mô -đun chứa một số lớp và chức năng hữu ích, trong đó quan trọng nhất là hàm 1 (với tư cách là trình trang trí và trình quản lý bối cảnh) và lớp 2. Việc chế giễu 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ày.Chúng ta không có nghĩa là gì khi chế giễu?Các nhà phát triển sử dụng rất nhiều đối tượng hoặc mô -đun "giả", là 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 giả 4 thu thập tất cả các cuộc gọi API 4 và xử lý chúng tại địa phương. Mặc dù các giả này cho phép các nhà phát triển kiểm tra các API bên ngoài cục bộ, 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à loại chế giễu trong tài liệu này. Tài liệu này cụ thể về việc sử dụng các đối tượng 2 để quản lý đầy đủ luồng điều khiển của hàm được kiểm tra, cho phép thử nghiệm dễ dàng các lỗi và xử lý ngoại lệ.Làm thế nào để chúng ta chế giễu trong Python?Việc chế giễu trong Python được thực hiện bằng cách sử dụng 1 để chiếm đoạt chức năng API hoặc cuộc gọi tạo đối tượng. Khi 1 chặn 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ể chế giễu cuộc gọi API để trả về bất kỳ giá trị nào bạn muốn hoặc tăng 1.Quy trình tổng thể 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 được kiểm tra hoặc bạn có thể đã thiết lập phản hồi 2 của mình không chính xác. Tiếp theo, chúng tôi sẽ đi sâu 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 giả.vá
1 có thể được sử dụng làm chất trang trí cho chức năng thử nghiệm, lấy một chuỗi đặt tên hàm sẽ được vá làm đối số. Để 1 định vị chức năng được vá, nó phải được chỉ định bằng tên đủ điều kiện, có thể không phải là những gì bạn mong đợi. Nếu một lớp được nhập bằng cách sử dụng câu lệnh 6, 7 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í dụ: nếu một lớp được nhập trong mô -đun 8 như sau:
Nó phải được vá là 9, thay vì 0, do ngữ nghĩa của câu lệnh 1, nhập các lớp và chức năng vào không gian tên hiện tại.Thông thường 1 được sử dụng để vá một cuộc gọi API bên ngoài hoặc bất kỳ lệnh gọi chức năng hoặc chức năng sử dụng nhiều tài nguyên nào khác hoặc việc tạo đối tượng. Bạn chỉ nên vá một vài thiết bị gọi cho mỗi bài kiểm tra. Nếu bạn thấy mình đang cố gắng 1 nhiều hơn một số lần, hãy xem xét 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 một đối số vị trí đến chức năng bạn đang trang trí (tức là chức năng kiểm tra của bạn). Khi vá nhiều chức năng, người trang trí gần chức năng được trang trí nhất được gọi là đầu tiên, vì vậy nó sẽ tạo ra đối số vị trí đầu tiên.
Theo mặc định, các đối số này là các trường hợp của 2, đó là đối tượng chế giễu mặc định của ____ 10. Bạn có thể xác định hành vi của hàm được vá bằng cách đặt các thuộc tính trên thể hiện 2 đã trả lại.MagicMock 2 Các đối tượng cung cấp một giao diện chế giễu đơn giản cho phép bạn đặt giá trị trả về hoặc hành vi khác của chức năng hoặc cuộc gọi 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, có thể gây khó chịu. Ví dụ: nếu chúng tôi đang khắc một cuộc gọi đến 9, cuộc gọi thư viện HTTP, chúng tôi có thể xác định phản hồi cho cuộc gọi đó sẽ được trả về khi cuộc gọi API được thực hiện trong chức năng được kiểm tra, thay vì đảm bảo rằng máy chủ kiểm tra là Có sẵn để trả lại phản hồi mong muốn.Hai thuộc tính quan trọng nhất của một ví dụ 2 là 1 và 2, cả hai đều cho phép chúng tôi xác định hành vi trả lại của cuộc gọi được vá.return_valueThuộc tính 1 trên thể hiện 2 được chuyển vào chức năng kiểm tra của bạn cho phép bạn chọn những gì mà các bản trả lại có thể gọi được vá. Trong hầu hết các trường hợp, bạn sẽ muốn trả lại một phiên bản giả của những gì mà người ta có thể gọi thường sẽ trở lại. Đây có thể là JSON, một giá trị, một giá trị, một ví dụ của đối tượng phản hồi thực, 2 giả vờ là đối tượng phản hồi hoặc bất cứ điều gì khác. Khi vá các đối tượng, cuộc gọi được vá là cuộc gọi tạo đối tượng, vì vậy 1 của 2 phải là một đối tượng giả, có thể là một 2 khác.Nếu mã bạn đang thử nghiệm là Pythonic và gõ vịt thay vì gõ rõ ràng, sử dụng 2 làm đối tượng phản hồi có thể thuận tiện. Thay vì trải qua những rắc rối trong việc tạo một thể hiện thực của một lớp, bạn có thể xác định các cặp giá trị khóa thuộc tính tùy ý trong hàm tạo 2 và chúng sẽ được áp dụng tự động cho phiên bản.
Lưu ý rằng đối số được chuyển cho 1, tức là, 2, là một 2 và chúng tôi đang đặt 1 cho một 2 khác. Khi chế giễu, mọi thứ đều là 2.Specing a MagicMockMặc dù tính linh hoạt của ____ 12 là thuận tiện cho các lớp chế giễu nhanh chóng với các yêu cầu phức tạp, nhưng nó cũng có thể là một nhược điểm. Theo mặc định, 2s hành động giống như chúng có bất kỳ thuộc tính nào, thậm chí các thuộc tính mà bạn không muốn họ có. Trong ví dụ trên, chúng tôi trả về một đối tượng 2 thay vì đối tượng 0. Tuy nhiên, giả sử chúng tôi đã phạm sai lầm trong cuộc gọi 1 và vá một hàm được cho là sẽ trả về một đối tượng 2 thay vì đối tượng 0. 2 chúng ta trở lại vẫn sẽ hoạt động giống như tất cả các thuộc tính của đối tượng 2, mặc dù chúng ta muốn mô hình hóa một đối tượng 0. Điều này có thể dẫn đến các 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 điều này là 7 2 khi tạo nó, sử dụng đối số từ khóa 7: 0. Đ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à 2 được chỉ định. Cố gắng truy cập một thuộc tính không có trong đối tượng gốc sẽ tăng 3, giống như đối tượng thực. Một ví dụ đơn giản là:
side_effectĐôi khi bạn sẽ muốn kiểm tra rằng chức năng của bạn xử lý chính xác một ngoại lệ hoặc nhiều cuộc gọi của chức năng bạn đang vá được xử lý chính xác. Bạn có thể làm điều đó bằng cách sử dụng 2. Cài đặt 2 thành một ngoại lệ nâng ngoại lệ đó ngay lập tức khi hàm được vá được gọi.Cài đặt 2 cho một ITEBLEBLE sẽ trả lại mục tiếp theo từ Itable mỗi khi hàm được vá được gọi. Cài đặt 2 cho bất kỳ giá trị nào khác sẽ trả về giá trị đó.
assert_called_with 8 khẳng định rằng hàm được vá được gọi với các đối số được chỉ định là đối số cho 8.
Một ví dụ đầy đủTrong ví dụ này, tôi đang thử nghiệm hàm 0 trên 1. Điều này có nghĩa là các cuộc gọi API trong 2 sẽ được thực hiện hai lần, đây là thời điểm tuyệt vời để sử dụng 3.Mã đầy đủ của ví dụ là ở đây:
Tôi đang vá hai cuộc gọi trong chức năng được kiểm tra ( 4), một đến 5 và một đến 6. Vì tôi đang vá hai cuộc gọi, tôi nhận được hai đối số cho chức năng kiểm tra của mình, mà tôi đã gọi là 7 và 8. Đây là cả hai đối tượng 2. Trong trạng thái mặc định của họ, họ không làm được gì nhiều. Chúng ta cần chỉ định một số hành vi phản ứng cho họ.
Các thử nghiệm này để đảm bảo một cơ sở thử lại cuối 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 đến 5 và 6.Ở đây tôi đã thiết lập những cái 2 mà tôi muốn. Tôi muốn tất cả các cuộc gọi đến 5 hoạt động (trả lại một 4 trống là tốt cho bài kiểm tra này), cuộc gọi đầu tiên đến 6 để thất bại với một ngoại lệ và cuộc gọi thứ hai đến 6 để làm việc. Loại kiểm soát hạt mịn này đối với hành vi chỉ có thể thông qua việc chế giễu.
Khi tôi đã thiết lập các 2, phần còn lại của bài kiểm tra là đơn giản. Hành vi này là: cuộc gọi đầu tiên đến 6 không thành công, vì vậy cơ sở thử lại 9 sẽ bị 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 8 và 7.Sự kết luậnSử 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 tôi để thực hiện 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 cho chúng tôi khả năng viết các bài kiểm tra độc lập chạy nhanh, không có sự phụ thuộc. Nó cho chúng ta sức mạnh để kiểm tra các trường hợp xử lý ngoại lệ và cạnh mà không thể kiểm tra. Quan trọng nhất, nó cho chúng tôi tự do tập trung các nỗ lực kiểm tra 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 việc 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ã của chúng tôi, đó là lý do tại sao chúng tôi kiểm tra ở nơi đầu tiên. Liên kết tài liệuhttps://docs.python.org/3/library/unittest.mock.html Làm thế nào để giả hoạt động?Một đối tượng mà bạn muốn kiểm tra có thể có sự phụ thuộc vào các đối tượng phức tạp khác. Để cô lập hành vi của đối tượng bạn muốn kiểm tra, bạn thay thế các đối tượng khác bằng các chế giễu mô phỏng hành vi của các đối tượng thực. Vì vậy, trong các từ đơn giản, chế giễu là tạo ra các đối tượng mô phỏng hành vi của các đối tượng thực.creating objects that simulate the behavior of real objects.
Làm thế nào để chế giễu pytest hoạt động?Trong pytest, chế giễu có thể thay thế giá trị trả về của một hàm trong một hàm.Điều này rất hữu ích để kiểm tra hàm mong muốn và thay thế giá trị trả về của hàm lồng nhau trong hàm mong muốn mà chúng tôi đang thử nghiệm.replace the return value of a function within a function. This is useful for testing the desired function and replacing the return value of a nested function within that desired function we are testing.
Tại sao chế giễu được sử dụng trong thử nghiệm đơn vị?Việc chế giễu là một cách để thay thế một sự phụ thuộc trong một đơn vị được thử nghiệm với sự phụ thuộc đó cho sự phụ thuộc đó.Đứng trong cho phép đơn vị được kiểm tra được kiểm tra mà không cần gọi sự phụ thuộc thực sự.to replace a dependency in a unit under test with a stand-in for that dependency. The stand-in allows the unit under test to be tested without invoking the real dependency.
Sự khác biệt giữa Mock và Magicmock là gì?Vậy sự khác biệt giữa họ là gì?MagicMock là một lớp con của Mock.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 (ví dụ: __str__, __len__, v.v.).Do đó, bạn nên sử dụng MagicMock khi bạn cần Phương pháp ma thuật và chế giễu nếu bạn không cần chúng.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. |