portaldacalheta.pt
  • หลัก
  • การจัดการโครงการ
  • การเพิ่มขึ้นของระยะไกล
  • การบริหารโครงการ
  • เครื่องมือและบทช่วยสอน
เทคโนโลยี

ข้อมูลเบื้องต้นเกี่ยวกับการเยาะเย้ยใน Python



วิธีเรียกใช้การทดสอบหน่วยใน Python โดยไม่ต้องทดสอบความอดทนของคุณ

บ่อยกว่านั้นซอฟต์แวร์ที่เราเขียนโต้ตอบโดยตรงกับสิ่งที่เราจะระบุว่าเป็นบริการ 'สกปรก' ในแง่ของคนธรรมดา: บริการที่มีความสำคัญต่อแอปพลิเคชันของเรา แต่การโต้ตอบมีเจตนา แต่ผลข้างเคียงที่ไม่ต้องการนั่นคือไม่เป็นที่ต้องการในบริบทของการทดสอบอัตโนมัติ

ตัวอย่างเช่นบางทีเรากำลังเขียนแอปโซเชียลและต้องการทดสอบฟีเจอร์ 'โพสต์ไปที่ Facebook' ใหม่ แต่ไม่ต้องการ จริง โพสต์ไปที่ Facebook ทุกครั้งที่เราเรียกใช้ชุดทดสอบของเรา



งูหลาม unittest ไลบรารีประกอบด้วยแพ็กเกจย่อยชื่อ unittest.mock - หรือหากคุณประกาศว่าเป็นการพึ่งพาเพียงแค่ mock - ซึ่งให้วิธีการที่มีประสิทธิภาพและมีประโยชน์อย่างมากในการล้อเลียนและขจัดผลข้างเคียงที่ไม่ต้องการเหล่านี้



การเยาะเย้ยและการทดสอบหน่วยในไลบรารี python unittest



หมายเหตุ: mock คือ รวมใหม่ ในไลบรารีมาตรฐานของ Python 3.3; การแจกแจงก่อนหน้านี้จะต้องใช้ไลบรารีจำลองที่ดาวน์โหลดได้ทาง PyPI .

การโทรของระบบเทียบกับการเยาะเย้ย Python

เพื่อเป็นตัวอย่างอื่นให้คุณและอีกตัวอย่างหนึ่งที่เราจะดำเนินการกับส่วนที่เหลือของบทความโปรดพิจารณา การโทรของระบบ . ไม่ยากที่จะเห็นว่าสิ่งเหล่านี้เป็นตัวเลือกหลักสำหรับการล้อเลียน: ไม่ว่าคุณจะเขียนสคริปต์เพื่อนำไดรฟ์ซีดีออกเว็บเซิร์ฟเวอร์ที่ลบไฟล์แคชเก่าออกจาก /tmp หรือเซิร์ฟเวอร์ซ็อกเก็ตที่ผูกกับ TCP พอร์ตสิ่งเหล่านี้เรียกคุณลักษณะทั้งหมดที่เป็นผลข้างเคียงที่ไม่ต้องการในบริบทของการทดสอบหน่วยของคุณ



ในฐานะนักพัฒนาคุณสนใจมากขึ้นที่ไลบรารีของคุณเรียกฟังก์ชันระบบสำหรับการดีดซีดีได้สำเร็จซึ่งต่างจากการเปิดถาดซีดีของคุณทุกครั้งที่มีการทดสอบ

ในฐานะนักพัฒนาคุณสนใจมากขึ้นว่าไลบรารีของคุณเรียกฟังก์ชันระบบสำหรับการดีดซีดีได้สำเร็จ (ด้วยอาร์กิวเมนต์ที่ถูกต้อง ฯลฯ ) ในทางตรงกันข้ามกับการเปิดถาดซีดีของคุณทุกครั้งที่มีการทดสอบ (หรือแย่กว่านั้นคือหลายครั้งเนื่องจากการทดสอบหลายครั้งอ้างอิงรหัสนำออกในระหว่างการทดสอบหน่วยเดียว!)

การโจมตีทางเว็บประเภทใดที่ใช้ฟังก์ชันรับและโพสต์ของรูปแบบ html

ในทำนองเดียวกันการทำให้การทดสอบหน่วยของคุณมีประสิทธิภาพและมีประสิทธิภาพหมายถึงการรักษา 'โค้ดที่ช้า' ไว้ให้มากที่สุดจากการทดสอบอัตโนมัตินั่นคือระบบไฟล์และการเข้าถึงเครือข่าย



สำหรับตัวอย่างแรกของเราเราจะปรับโครงสร้างกรณีทดสอบ Python มาตรฐานจากรูปแบบเดิมไปเป็นแบบเดิมโดยใช้ mock เราจะแสดงให้เห็นว่าการเขียนกรณีทดสอบด้วยหุ่นจำลองจะทำให้การทดสอบของเราฉลาดขึ้นเร็วขึ้นและสามารถเปิดเผยเพิ่มเติมเกี่ยวกับวิธีการทำงานของซอฟต์แวร์ได้อย่างไร

ฟังก์ชันลบอย่างง่าย

เราทุกคนจำเป็นต้องลบไฟล์ออกจากระบบไฟล์ของเราเป็นครั้งคราวดังนั้นเรามาเขียนฟังก์ชันใน Python ซึ่งจะทำให้สคริปต์ของเราทำได้ง่ายขึ้นเล็กน้อย



#!/usr/bin/env python # -*- coding: utf-8 -*- import os def rm(filename): os.remove(filename)

เห็นได้ชัดว่า rm ของเรา วิธีการ ณ เวลานี้ไม่ได้ให้อะไรมากไปกว่าพื้นฐาน os.remove วิธีการ แต่ codebase ของเราจะปรับปรุงทำให้เราสามารถเพิ่มฟังก์ชันการทำงานได้มากขึ้นที่นี่

เรามาเขียนกรณีทดสอบแบบเดิม ๆ นั่นคือไม่มีล้อเลียน:



#!/usr/bin/env python # -*- coding: utf-8 -*- from mymodule import rm import os.path import tempfile import unittest class RmTestCase(unittest.TestCase): tmpfilepath = os.path.join(tempfile.gettempdir(), 'tmp-testfile') def setUp(self): with open(self.tmpfilepath, 'wb') as f: f.write('Delete me!') def test_rm(self): # remove the file rm(self.tmpfilepath) # test that it was actually removed self.assertFalse(os.path.isfile(self.tmpfilepath), 'Failed to remove the file.')

กรณีทดสอบของเราค่อนข้างง่าย แต่ทุกครั้งที่เรียกใช้ไฟล์ชั่วคราวจะถูกสร้างขึ้นแล้วลบออก นอกจากนี้เราไม่มีวิธีทดสอบว่า rm ของเราหรือไม่ วิธีการส่งผ่านอาร์กิวเมนต์อย่างถูกต้องไปที่ os.remove โทร. เราทำได้ สมมติ เป็นไปตามการทดสอบข้างต้น แต่ยังเหลืออีกมากที่ต้องการ

การปรับโครงสร้างด้วย Python Mocks

มาปรับโครงสร้างกรณีทดสอบของเราใหม่โดยใช้ mock:



#!/usr/bin/env python # -*- coding: utf-8 -*- from mymodule import rm import mock import unittest class RmTestCase(unittest.TestCase): @mock.patch('mymodule.os') def test_rm(self, mock_os): rm('any path') # test that rm called os.remove with the right parameters mock_os.remove.assert_called_with('any path')

ด้วย refactors เหล่านี้เราได้เปลี่ยนวิธีการดำเนินการทดสอบโดยพื้นฐานแล้ว ตอนนี้เรามีไฟล์ คนวงใน ซึ่งเป็นวัตถุที่เราสามารถใช้เพื่อตรวจสอบการทำงานของวัตถุอื่นได้

Python Mocking Pitfalls ที่อาจเกิดขึ้น

สิ่งแรกที่ควรคำนึงถึงคือเรากำลังใช้ mock.patch เมธอดมัณฑนากรเพื่อจำลองวัตถุที่อยู่ที่ mymodule.os และฉีดจำลองนั้นลงในวิธีกรณีทดสอบของเรา คงไม่สมเหตุสมผลไปกว่าการล้อเลียน os เองแทนที่จะอ้างอิงที่ mymodule.os?

Python ค่อนข้างเป็นงูที่ส่อเสียดในการนำเข้าและจัดการโมดูล ที่รันไทม์ mymodule โมดูลมีของตัวเอง os ซึ่งนำเข้าสู่ขอบเขตโลคัลของตนเองในโมดูล ดังนั้นหากเราล้อเลียน os เราจะไม่เห็นผลกระทบของการล้อเลียนใน mymodule โมดูล.

มนต์ที่ต้องทำซ้ำ ๆ คือ:

เลียนแบบสิ่งของที่ใช้ไม่ใช่ที่มา

หากคุณต้องการล้อเลียน tempfile โมดูลสำหรับ myproject.app.MyElaborateClass คุณอาจต้องใช้การจำลองกับ myproject.app.tempfile เนื่องจากแต่ละโมดูลเก็บการนำเข้าของตัวเอง

ด้วยความผิดพลาดนั้นเรามาล้อเลียนกันต่อไป

การเพิ่มการตรวจสอบความถูกต้องใน 'rm'

rm วิธีการที่กำหนดไว้ก่อนหน้านี้ค่อนข้างง่ายเกินไป เราต้องการให้ตรวจสอบความถูกต้องว่ามีเส้นทางและเป็นไฟล์ก่อนที่จะพยายามลบออกโดยสุ่มสี่สุ่มห้า ขอ refactor rm ฉลาดขึ้นหน่อย:

#!/usr/bin/env python # -*- coding: utf-8 -*- import os import os.path def rm(filename): if os.path.isfile(filename): os.remove(filename)

เยี่ยมมาก ตอนนี้เรามาปรับเปลี่ยนกรณีทดสอบของเราเพื่อให้ครอบคลุม

ไฟล์ .cc เทียบกับ .cpp
#!/usr/bin/env python # -*- coding: utf-8 -*- from mymodule import rm import mock import unittest class RmTestCase(unittest.TestCase): @mock.patch('mymodule.os.path') @mock.patch('mymodule.os') def test_rm(self, mock_os, mock_path): # set up the mock mock_path.isfile.return_value = False rm('any path') # test that the remove call was NOT called. self.assertFalse(mock_os.remove.called, 'Failed to not remove the file if not present.') # make the file 'exist' mock_path.isfile.return_value = True rm('any path') mock_os.remove.assert_called_with('any path')

กระบวนทัศน์การทดสอบของเราเปลี่ยนไปอย่างสิ้นเชิง ตอนนี้เราสามารถตรวจสอบและตรวจสอบการทำงานภายในของวิธีการโดยไม่ต้อง ใด ๆ ผลข้างเคียง.

การลบไฟล์เป็นบริการด้วย Mock Patch

จนถึงขณะนี้เราดำเนินการเฉพาะกับการจัดหา mocks สำหรับฟังก์ชันเท่านั้น แต่ยังไม่ใช้สำหรับวิธีการกับวัตถุหรือกรณีที่จำเป็นต้องมีการจำลองเพื่อส่งพารามิเตอร์ เรามาดูวิธีการของวัตถุกันก่อน

เราจะเริ่มต้นด้วย refactor ของ rm วิธีการลงในคลาสบริการ ไม่มีความจำเป็นที่สมเหตุสมผลในการห่อหุ้มฟังก์ชันง่ายๆเช่นนี้ไว้ในวัตถุ แต่อย่างน้อยที่สุดก็จะช่วยให้เราแสดงแนวคิดหลักใน mock มาดูกันว่า

#!/usr/bin/env python # -*- coding: utf-8 -*- import os import os.path class RemovalService(object): '''A service for removing objects from the filesystem.''' def rm(filename): if os.path.isfile(filename): os.remove(filename)

คุณจะสังเกตเห็นว่าไม่มีการเปลี่ยนแปลงมากนักในกรณีทดสอบของเรา:

#!/usr/bin/env python # -*- coding: utf-8 -*- from mymodule import RemovalService import mock import unittest class RemovalServiceTestCase(unittest.TestCase): @mock.patch('mymodule.os.path') @mock.patch('mymodule.os') def test_rm(self, mock_os, mock_path): # instantiate our service reference = RemovalService() # set up the mock mock_path.isfile.return_value = False reference.rm('any path') # test that the remove call was NOT called. self.assertFalse(mock_os.remove.called, 'Failed to not remove the file if not present.') # make the file 'exist' mock_path.isfile.return_value = True reference.rm('any path') mock_os.remove.assert_called_with('any path')

เยี่ยมมากตอนนี้เรารู้แล้วว่า RemovalService ทำงานได้ตามแผน มาสร้างบริการอื่นที่ประกาศว่าเป็นการพึ่งพา:

#!/usr/bin/env python # -*- coding: utf-8 -*- import os import os.path class RemovalService(object): '''A service for removing objects from the filesystem.''' def rm(self, filename): if os.path.isfile(filename): os.remove(filename) class UploadService(object): def __init__(self, removal_service): self.removal_service = removal_service def upload_complete(self, filename): self.removal_service.rm(filename)

เนื่องจากเราได้ครอบคลุมการทดสอบใน RemovalService แล้วเราจะไม่ตรวจสอบความถูกต้องของฟังก์ชันการทำงานภายในของ rm วิธีการในการทดสอบ UploadService ของเรา แต่เราจะทดสอบ (โดยไม่มีผลข้างเคียงแน่นอน) ว่า UploadService โทร ที่ RemovalService.rm ซึ่งเรารู้ว่า 'ใช้ได้ผล' จากกรณีทดสอบก่อนหน้านี้

มีสองวิธีในการดำเนินการนี้:

  1. ล้อเลียน RemovalService.rm วิธีการเอง
  2. จัดหาอินสแตนซ์จำลองในตัวสร้างของ UploadService

เนื่องจากทั้งสองวิธีมักมีความสำคัญในการทดสอบหน่วยเราจะตรวจสอบทั้งสองอย่าง

ตัวเลือกที่ 1: วิธีการจำลองอินสแตนซ์

mock ไลบรารีมีตัวตกแต่งเมธอดพิเศษสำหรับการเยาะเย้ยเมธอดและคุณสมบัติของออบเจ็กต์เช่น @mock.patch.object มัณฑนากร:

#!/usr/bin/env python # -*- coding: utf-8 -*- from mymodule import RemovalService, UploadService import mock import unittest class RemovalServiceTestCase(unittest.TestCase): @mock.patch('mymodule.os.path') @mock.patch('mymodule.os') def test_rm(self, mock_os, mock_path): # instantiate our service reference = RemovalService() # set up the mock mock_path.isfile.return_value = False reference.rm('any path') # test that the remove call was NOT called. self.assertFalse(mock_os.remove.called, 'Failed to not remove the file if not present.') # make the file 'exist' mock_path.isfile.return_value = True reference.rm('any path') mock_os.remove.assert_called_with('any path') class UploadServiceTestCase(unittest.TestCase): @mock.patch.object(RemovalService, 'rm') def test_upload_complete(self, mock_rm): # build our dependencies removal_service = RemovalService() reference = UploadService(removal_service) # call upload_complete, which should, in turn, call `rm`: reference.upload_complete('my uploaded file') # check that it called the rm method of any RemovalService mock_rm.assert_called_with('my uploaded file') # check that it called the rm method of _our_ removal_service removal_service.rm.assert_called_with('my uploaded file')

เยี่ยมมาก! เราได้ตรวจสอบแล้วว่า UploadService เรียกอินสแตนซ์ของเราสำเร็จ rm วิธี. สังเกตเห็นอะไรที่น่าสนใจในนั้น? กลไกการแก้ไขแทนที่ rm วิธีการทั้งหมด RemovalService อินสแตนซ์ในวิธีการทดสอบของเรา นั่นหมายความว่าเราสามารถตรวจสอบอินสแตนซ์ได้ด้วยตนเอง หากคุณต้องการดูข้อมูลเพิ่มเติมให้ลองวางเบรกพอยต์ในโค้ดจำลองของคุณเพื่อรับความรู้สึกที่ดีว่ากลไกการแก้ไขทำงานอย่างไร

Mock Patch Pitfall: คำสั่งมัณฑนากร

เมื่อใช้นักตกแต่งหลายคนในวิธีการทดสอบของคุณ คำสั่งซื้อเป็นสิ่งสำคัญ และเป็นเรื่องที่น่าสับสน โดยทั่วไปเมื่อแมปมัณฑนากรกับพารามิเตอร์วิธีการ ทำงานย้อนหลัง . ลองพิจารณาตัวอย่างนี้:

@mock.patch('mymodule.sys') @mock.patch('mymodule.os') @mock.patch('mymodule.os.path') def test_something(self, mock_os_path, mock_os, mock_sys): pass

สังเกตว่าพารามิเตอร์ของเราตรงกับลำดับย้อนกลับของมัณฑนากรหรือไม่? ส่วนหนึ่งเป็นเพราะ วิธีการทำงานของ Python . เมื่อใช้มัณฑนากรหลายวิธีนี่คือลำดับของการดำเนินการในรหัสเทียม:

patch_sys(patch_os(patch_os_path(test_something)))

ตั้งแต่แพทช์จนถึง sys เป็นโปรแกรมแก้ไขที่อยู่นอกสุดซึ่งจะถูกเรียกใช้งานครั้งสุดท้ายทำให้เป็นพารามิเตอร์สุดท้ายในอาร์กิวเมนต์ของวิธีการทดสอบจริง จดสิ่งนี้ไว้และใช้ดีบักเกอร์เมื่อทำการทดสอบเพื่อให้แน่ใจว่าพารามิเตอร์ที่ถูกต้องถูกฉีดเข้าไปในลำดับที่ถูกต้อง

ตัวเลือกที่ 2: การสร้างอินสแตนซ์จำลอง

แทนที่จะล้อเลียนวิธีการอินสแตนซ์ที่เฉพาะเจาะจงเราสามารถจัดหาอินสแตนซ์จำลองให้กับ UploadService แทนได้ ด้วยตัวสร้าง ฉันชอบตัวเลือกที่ 1 ข้างต้นมากกว่าเนื่องจากมีความแม่นยำกว่ามาก แต่มีหลายกรณีที่ตัวเลือก 2 อาจมีประสิทธิภาพหรือจำเป็น มาปรับเปลี่ยนการทดสอบของเราอีกครั้ง:

แอพหาคู่ยอดนิยมประจำปี 2017
#!/usr/bin/env python # -*- coding: utf-8 -*- from mymodule import RemovalService, UploadService import mock import unittest class RemovalServiceTestCase(unittest.TestCase): @mock.patch('mymodule.os.path') @mock.patch('mymodule.os') def test_rm(self, mock_os, mock_path): # instantiate our service reference = RemovalService() # set up the mock mock_path.isfile.return_value = False reference.rm('any path') # test that the remove call was NOT called. self.assertFalse(mock_os.remove.called, 'Failed to not remove the file if not present.') # make the file 'exist' mock_path.isfile.return_value = True reference.rm('any path') mock_os.remove.assert_called_with('any path') class UploadServiceTestCase(unittest.TestCase): def test_upload_complete(self, mock_rm): # build our dependencies mock_removal_service = mock.create_autospec(RemovalService) reference = UploadService(mock_removal_service) # call upload_complete, which should, in turn, call `rm`: reference.upload_complete('my uploaded file') # test that it called the rm method mock_removal_service.rm.assert_called_with('my uploaded file')

ในตัวอย่างนี้เราไม่จำเป็นต้องแก้ไขการทำงานใด ๆ ด้วยซ้ำเราเพียงแค่สร้างข้อมูลจำเพาะอัตโนมัติสำหรับ RemovalService จากนั้นฉีดอินสแตนซ์นี้ลงใน UploadService ของเรา เพื่อตรวจสอบฟังก์ชันการทำงาน

mock.create_autospec เมธอดสร้างอินสแตนซ์ที่เทียบเท่ากับฟังก์ชันให้กับคลาสที่ให้มา สิ่งนี้หมายถึงในทางปฏิบัติคือเมื่ออินสแตนซ์ที่ส่งคืนมีการโต้ตอบมันจะเพิ่มข้อยกเว้นหากใช้ในรูปแบบที่ผิดกฎหมาย โดยเฉพาะอย่างยิ่งถ้าเมธอดถูกเรียกด้วยจำนวนอาร์กิวเมนต์ที่ไม่ถูกต้องจะมีการเพิ่มข้อยกเว้น สิ่งนี้มีความสำคัญอย่างยิ่งเมื่อ refactors เกิดขึ้น เมื่อมีการเปลี่ยนแปลงไลบรารีการทดสอบจะแตกและคาดว่าจะเกิดขึ้น หากไม่ใช้ข้อมูลจำเพาะอัตโนมัติการทดสอบของเราจะยังคงผ่านแม้ว่าการใช้งานพื้นฐานจะเสีย

หลุมพราง: mock.Mock และ mock.MagicMock ชั้นเรียน

mock ไลบรารียังมีคลาสที่สำคัญอีกสองคลาสซึ่งฟังก์ชันภายในส่วนใหญ่สร้างขึ้นจาก: mock.Mock และ mock.MagicMock . เมื่อมีตัวเลือกให้ใช้ mock.Mock เช่น a mock.MagicMock อินสแตนซ์หรือข้อมูลจำเพาะอัตโนมัติมักชอบใช้ข้อมูลจำเพาะอัตโนมัติเนื่องจากจะช่วยให้การทดสอบของคุณมีเหตุผลสำหรับการเปลี่ยนแปลงในอนาคต เนื่องจาก mock.Mock และ mock.MagicMock ยอมรับการเรียกเมธอดและการกำหนดคุณสมบัติทั้งหมดโดยไม่คำนึงถึง API ที่อยู่เบื้องหลัง พิจารณากรณีการใช้งานต่อไปนี้:

class Target(object): def apply(value): return value def method(target, value): return target.apply(value)

เราสามารถทดสอบได้ด้วย mock.Mock อินสแตนซ์เช่นนี้:

class MethodTestCase(unittest.TestCase): def test_method(self): target = mock.Mock() method(target, 'value') target.apply.assert_called_with('value')

ตรรกะนี้ดูเหมือนจะมีเหตุผล แต่เรามาแก้ไข Target.apply กัน วิธีการใช้พารามิเตอร์เพิ่มเติม:

class Target(object): def apply(value, are_you_sure): if are_you_sure: return value else: return None

ทำการทดสอบอีกครั้งและคุณจะพบว่ายังผ่าน นั่นเป็นเพราะไม่ได้สร้างขึ้นจาก API จริงของคุณ นี่คือเหตุผลที่คุณควร เสมอ ใช้ create_autospec วิธีการและ autospec ด้วยพารามิเตอร์ @patch และ @patch.object มัณฑนากร.

Python Mock ตัวอย่าง: การจำลองการเรียก API ของ Facebook

เพื่อให้เสร็จสมบูรณ์เรามาเขียนตัวอย่างการจำลองงูหลามในโลกแห่งความเป็นจริงที่เกี่ยวข้องมากขึ้นซึ่งเราได้กล่าวถึงในบทนำนั่นคือการโพสต์ข้อความไปยัง Facebook เราจะเขียนคลาส Wrapper ที่สวยงามและกรณีทดสอบที่เกี่ยวข้อง

import facebook class SimpleFacebook(object): def __init__(self, oauth_token): self.graph = facebook.GraphAPI(oauth_token) def post_message(self, message): '''Posts a message to the Facebook wall.''' self.graph.put_object('me', 'feed', message=message)

นี่คือกรณีทดสอบของเราซึ่งตรวจสอบว่าเราโพสต์ข้อความโดยไม่มี จริง โพสต์ข้อความ:

import facebook import simple_facebook import mock import unittest class SimpleFacebookTestCase(unittest.TestCase): @mock.patch.object(facebook.GraphAPI, 'put_object', autospec=True) def test_post_message(self, mock_put_object): sf = simple_facebook.SimpleFacebook('fake oauth token') sf.post_message('Hello World!') # verify mock_put_object.assert_called_with(message='Hello World!')

อย่างที่เราเห็นมาจนถึงตอนนี้ จริงๆ ง่ายต่อการเริ่มเขียนแบบทดสอบอย่างชาญฉลาดด้วย mock ใน Python

สรุป

Python ของ mock หากมีความสับสนเล็กน้อยในการใช้งานเป็นตัวเปลี่ยนเกมสำหรับ การทดสอบหน่วย . เราได้สาธิตกรณีการใช้งานทั่วไปสำหรับการเริ่มต้นใช้งาน mock ในการทดสอบหน่วยและหวังว่าบทความนี้จะช่วยได้ นักพัฒนา Python เอาชนะอุปสรรคเริ่มต้นและเขียนโค้ดที่ดีเยี่ยมและผ่านการทดสอบแล้ว

ทำความเข้าใจพื้นฐาน

การเยาะเย้ยในการทดสอบหน่วยคืออะไร?

การล้อเลียนจำลองการมีอยู่และพฤติกรรมของวัตถุจริงทำให้วิศวกรซอฟต์แวร์สามารถทดสอบโค้ดในสถานการณ์สมมติต่างๆได้โดยไม่จำเป็นต้องใช้การเรียกระบบจำนวนนับไม่ถ้วน การล้อเลียนจะช่วยเพิ่มความเร็วและประสิทธิภาพของการทดสอบหน่วยได้อย่างมาก

การเยาะเย้ยใน Python คืออะไร?

การจำลองใน Python หมายถึงไลบรารี unittest.mock ถูกนำมาใช้เพื่อแทนที่ส่วนต่างๆของระบบด้วยอ็อบเจ็กต์จำลองทำให้การทดสอบหน่วยง่ายขึ้นและมีประสิทธิภาพมากกว่าที่จะเป็นไปได้

Zeplin Sketch Plugin - สะพานเวิร์กโฟลว์ระหว่างการออกแบบและวิศวกรรม

เครื่องมือและบทช่วยสอน

Zeplin Sketch Plugin - สะพานเวิร์กโฟลว์ระหว่างการออกแบบและวิศวกรรม
ฉันจะสร้าง Arduino Weather Station ที่ใช้งานได้เต็มรูปแบบได้อย่างไร

ฉันจะสร้าง Arduino Weather Station ที่ใช้งานได้เต็มรูปแบบได้อย่างไร

เทคโนโลยี

โพสต์ยอดนิยม
ตลาด Crowdfunding Equity ของสหรัฐมีการเติบโตขึ้นตามความคาดหวังหรือไม่?
ตลาด Crowdfunding Equity ของสหรัฐมีการเติบโตขึ้นตามความคาดหวังหรือไม่?
คู่มือสำคัญสำหรับ Qmake
คู่มือสำคัญสำหรับ Qmake
หลักการออกแบบ Mobile UX
หลักการออกแบบ Mobile UX
MIDI Tutorial: การสร้างแอปพลิเคชั่นเสียงบนเบราว์เซอร์ที่ควบคุมโดยฮาร์ดแวร์ MIDI
MIDI Tutorial: การสร้างแอปพลิเคชั่นเสียงบนเบราว์เซอร์ที่ควบคุมโดยฮาร์ดแวร์ MIDI
Init.js: คำแนะนำเกี่ยวกับสาเหตุและวิธีการใช้ JavaScript แบบ Full-Stack
Init.js: คำแนะนำเกี่ยวกับสาเหตุและวิธีการใช้ JavaScript แบบ Full-Stack
 
Splash of EarlGrey - UI การทดสอบแอพ ApeeScape Talent
Splash of EarlGrey - UI การทดสอบแอพ ApeeScape Talent
จาก Node.js ไปจนถึงการจ่ายภาษีอิสระของคุณ: บทสัมภาษณ์กับ Developer ที่ประสบความสำเร็จ
จาก Node.js ไปจนถึงการจ่ายภาษีอิสระของคุณ: บทสัมภาษณ์กับ Developer ที่ประสบความสำเร็จ
ขายธุรกิจของคุณ? หยุดทิ้งเงินไว้บนโต๊ะ
ขายธุรกิจของคุณ? หยุดทิ้งเงินไว้บนโต๊ะ
บทช่วยสอนเกี่ยวกับส่วนขยายแอป iOS 8
บทช่วยสอนเกี่ยวกับส่วนขยายแอป iOS 8
ผู้จัดการการเติบโต
ผู้จัดการการเติบโต
โพสต์ยอดนิยม
  • เครื่องมือสร้างภาพข้อมูลใดต่อไปนี้ใช้เพื่อจัดระเบียบข้อมูลเชิงปริมาณ
  • วิธีโดนแฮกหมายเลขบัตรเครดิต
  • คุณภาพข้อมูลในคลังข้อมูล
  • แนวทางปฏิบัติที่ดีที่สุดสำหรับการเริ่มต้นใช้งานแอพมือถือ
  • รายการหมายเลขบัตรเครดิตที่ถูกแฮ็ก
หมวดหมู่
  • การจัดการโครงการ
  • การเพิ่มขึ้นของระยะไกล
  • การบริหารโครงการ
  • เครื่องมือและบทช่วยสอน
  • © 2022 | สงวนลิขสิทธิ์

    portaldacalheta.pt